How to share text and Image on WhatsApp in iOS

Sharing text and Images on WhatsApp is now possible through Open URL Scheme (deep linking).

Send Text –

NSString * msg = @"YOUR MSG";
NSString * urlWhats = [NSString stringWithFormat:@"whatsapp://send?text=%@",msg];
NSURL * whatsappURL = [NSURL URLWithString:[urlWhats stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if ([[UIApplication sharedApplication] canOpenURL: whatsappURL]) {
    [[UIApplication sharedApplication] openURL: whatsappURL];
} else {
    // Cannot open whatsapp
}

Send Image –

— in .h file

@property (retain) UIDocumentInteractionController * documentInteractionController;

— in .m file

if ([[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"whatsapp://app"]]){

    UIImage     * iconImage = [UIImage imageNamed:@"YOUR IMAGE"];
    NSString    * savePath  = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/whatsAppTmp.jpg”];

    [UIImageJPEGRepresentation(iconImage, 1.0) writeToFile:savePath atomically:YES];

    _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
    _documentInteractionController.UTI = @"net.whatsapp.image";
    _documentInteractionController.delegate = self;

    [_documentInteractionController presentOpenInMenuFromRect:CGRectMake(0, 0, 0, 0) inView:self.view animated: YES];

} else {
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"WhatsApp not installed." message:@“No WhatsApp installed." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

You need add these lines in .plist file for iOS 9:

<key>LSApplicationQueriesSchemes</key>
<array>
<string>whatsapp</string>
</array>

How to show GPS strength value in iOS SDK

To show the signal strength of GPS we can use the properties of CLLocation like horizontalAccuracy and verticalAccuracy which indicate how accurate the device believes that location fix to be.

Here is some sample code –


if (someLocation.horizontalAccuracy < 0)
{
// No Signal
}
else if (someLocation.horizontalAccuracy > 163)
{
// Poor Signal
}
else if (someLocation.horizontalAccuracy > 48)
{
// Average Signal
}
else
{
// Full Signal
}

How to install “command line tools” with xcode 5.0.1

With Xcode 5.0.1 and Mavericks 10.9 the command line tools are no longer available via Xcode. There is only two ways to install command line tools.

1) Download directly from Apple developer downloads (https://developer.apple.com/downloads/index.action)

2) Using command line. Run this below command to install –

xcode-select --install

After you enter this command you’ll get a popup like below –

ZSTtJ

Just press Install and it will start downloading command line tools.. and you are good to go.

How to add UITextField in UIAlertView in iOS 7

For iOS 6 and below we have been adding UITextField in UIAlertView by adding a subview in UIAlertView. Something like below –

UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@"Enter ESC Score"];
[dialog setMessage:@" "];
[dialog addButtonWithTitle:@"Cancel"];
[dialog addButtonWithTitle:@"OK"];
dialog.tag = 5;

nameField = [[UITextField alloc] initWithFrame:CGRectMake(20.0, 45.0, 245.0, 25.0)];
[nameField setKeyboardType:UIKeyboardTypeNumberPad];
[nameField becomeFirstResponder];
[nameField setBackgroundColor:[UIColor whiteColor]];
[dialog addSubview:nameField];
CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0.0, 0.0);
[dialog setTransform: moveUp];
[dialog show];

But in iOS 7 Apple have changed things in UIAlertView class and not its not possible to add things in UIAlertView. Also as per the documentation its not a good idea to do so.

Fortunately Apple already have a functionality by which we can add a UITextField in the UIAlertView.

There is a property “alertViewStyle” for UIAlertView. We can set this style to get desired UIAlertView.

See this example –

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Folder Name?" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil] ;
alertView.tag = 2;
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
[alertView show];

We can get this textfield in alert view’s delegate method like this –

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

            UITextField * alertTextField = [alertView textFieldAtIndex:0];
            NSLog(@"alerttextfiled - %@",alertTextField.text);

// do whatever you want to do with this UITextField.
}

Here are supported UIAlertView styles.

UIAlertViewStyleDefault
A standard alert.

UIAlertViewStyleSecureTextInput
An alert that allows the user to enter text. The text field is obscured.

UIAlertViewStylePlainTextInput
An alert that allows the user to enter text.

UIAlertViewStyleLoginAndPasswordInput
An alert that allows the user to enter a login identifier and password.

Hope this would help and save someone’s some grey hair.

Create a folder inside documents directory in iOS apps

 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/MyFolder"];

if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder

iOS app security: Data Protection (Part 1)

Are you storing User’s credentials in app, Communicating with web services, getting user’s credit card details in your app? using in app purchases? If your answer is yes for any of these questions then you should seriously consider improving security of your application? Are you implementing proper security measures? if no then read on.. I am going to write a series of posts on iOS app security.

In this first post of this series I am going to explain how we can protect files which we are creating in our app.

iOS provides hardware-level encryption of files. Files marked for protection are encrypted using a per-device key, which is encrypted using the user’s password or PIN. Ten seconds after the device is locked, the unencrypted per-device key is removed from memory. When the user unlocks the device, the password or personal identification number (PIN) is used to decrypt the per-device key again, which is then used to decrypt the files.

You can configure the protection of files that you create with NSFileManager or NSData. The options, shown in the following list, have slightly different names. NSFileManager applies string attributes to the file, whereas NSData uses numeric options during creation, but the meanings are the same. The FileManager constants begin with NSFileProtection…, and the NSData constants begin with NSDataWritingFileProtection….

…None — The file is not protected and can be read or written at any time. This is the default value.

…Complete — Any file with this setting is protected ten seconds after the device is locked. This is the highest level of protection. Files with this setting may not be available when your program is running in the background. When the device is unlocked, these files are unprotected.

…CompleteUnlessOpen — Files with this setting are protected ten seconds after the device is locked unless they’re currently open. This allows your program to continue accessing the file while running in the background. When the file is closed, it will be protected if the device is locked.

…CompleteUntilFirstUserAuthentication — Files with this setting are protected only between the time the device boots and the first time the user unlocks the device. The files are unprotected from that point until the device is rebooted. This allows your application to open existing files while running in the background.

Sample usages with NSData –

 
[data writeToFile:path
             options:NSDataWritingFileProtectionComplete
               error:&error]

Sample usages with NSFileManager –

 
[[NSFileManager defaultManager] createFileAtPath:[self filePath]
                                        contents:[@"super secret file contents" dataUsingEncoding:NSUTF8StringEncoding]
                                      attributes:[NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey]];

If your application needs to know whether protected data is available, you can use one of the following:

– Implement the methods applicationProtectedDataWillBecomeUnavailable: and applicationProtectedDataDidBecomeAvailable: in your application delegate.

– Observe the notifications UIApplicationProtectedDataWillBecomeUnavailable and UIApplicationProtectedDataDidBecomeAvailable (these constants lack the traditional Notification suffix).

– Check[[UIApplication sharedApplication] protectedDataAvailable]

The weakest point in using file protection is that it depends on the 4 digit PIN user use, which offer only 10,000 combinations. Also if user is not using PIN then this won’t work at all.

Pro Tip –

The easiest way to create a protected file when you may or may not be in the background is as follows:

 
   [data writeToFile:path
             options:NSDataWritingFileProtectionComplete
               error:&error] ||
   [data writeToFile:path
             options:NSDataWritingFileProtectionCompleteUnlessOpen
               error:&error];

Note “||” between two statements.

If you use this technique, upgrade your file protection at startup with a routine like this:

 
-(void)upgradeFilesInDirectory:(NSString *)dir
                            error:(NSError **)error {
     NSFileManager *fm = [NSFileManager defaultManager];
     NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:dir];
     for (NSString *path in dirEnum) {

		NSDictionary *attrs = [dirEnum fileAttributes];
		if (![[attrs objectForKey: NSFileProtectionKey]
    				isEqual:NSFileProtectionComplete]) {
			attrs = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
			[fm setAttributes:attrs ofItemAtPath:path error:error];
		}

	} 

}

File protection is very easy, simple and hardware-optimised, you should use this in every project of yours, unless you have a good reason to not to.

FacebookSDK/FacebookSDK.h file not found

If you are getting “FacebookSDK/FacebookSDK.h file not found” error, even if you have Facebook SDK included in your project? It might be possible that project is not able to access FacebookSDK because of some mis-configuration in references.

Your best bet to resolve this error is by  removing FacebookSDK.framework from your project and then start over with these steps. Re-linking the framework won’t help in many cases –

Step 1. Go to Build Phases in your Project Target.
Step 2. In Link Binary With Libraries, click the “+” button.
Step 3. Click on “Add Other…” button
Step 4. Browse your FacebookSDK folder. Generally in ~/Documents/FacebookSDK/
Step 5. Clik on (select) “FacebookSDK.framework” and then OPEN.

Hope this will save someone’s time!

How to take screenshot programmatically in iOS SDK

First Import QuartzCore

#import <QuartzCore/QuartzCore.h>

Then –

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
    UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
else
    UIGraphicsBeginImageContext(self.window.bounds.size);

[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:@"foo.png" atomically:YES];

Note that this won’t capture certain types of screen content, like OpenGL ES layers.

Open Settings app in iphone using Open URL Scheme

Update: This doesn’t work anymore from iOS 5.1
Thanks Toto.

Do you want to open settings app or any section of settings app from your iOS application? Now you can do this you can use below URLs to open different sections of Settings app.

Preference Shortcuts:
About — prefs:root=General&path=About
Accessibility — prefs:root=General&path=ACCESSIBILITY
Airplane Mode On — prefs:root=AIRPLANE_MODE
Auto-Lock — prefs:root=General&path=AUTOLOCK
Brightness — prefs:root=Brightness
Bluetooth — prefs:root=General&path=Bluetooth
Date & Time — prefs:root=General&path=DATE_AND_TIME
FaceTime — prefs:root=FACETIME
General — prefs:root=General
Keyboard — prefs:root=General&path=Keyboard
iCloud — prefs:root=CASTLE
iCloud Storage & Backup — prefs:root=CASTLE&path=STORAGE_AND_BACKUP
International — prefs:root=General&path=INTERNATIONAL
Location Services — prefs:root=LOCATION_SERVICES
Music — prefs:root=MUSIC
Music Equalizer — prefs:root=MUSIC&path=EQ
Music Volume Limit — prefs:root=MUSIC&path=VolumeLimit
Network — prefs:root=General&path=Network
Nike + iPod — prefs:root=NIKE_PLUS_IPOD
Notes — prefs:root=NOTES
Notification — prefs:root=NOTIFICATIONS_ID
Phone — prefs:root=Phone
Photos — prefs:root=Photos
Profile — prefs:root=General&path=ManagedConfigurationList
Reset — prefs:root=General&path=Reset
Safari — prefs:root=Safari
Siri — prefs:root=General&path=Assistant
Sounds — prefs:root=Sounds
Software Update — prefs:root=General&path=SOFTWARE_UPDATE_LINK
Store — prefs:root=STORE
Twitter — prefs:root=TWITTER
Usage — prefs:root=General&path=USAGE
VPN — prefs:root=General&path=Network/VPN
Wallpaper — prefs:root=Wallpaper
Wi-Fi — prefs:root=WIFI

Distribute Enterprise applications Over The Air (OTA)

iOS supports over-the-air installation of enterprise apps, letting you distribute in-house software to your users without using iTunes or iPhone Configuration Utility.

Here are the steps by which you can create OTA distribution for your Enterprise apps.

Step 1: Archive your project as usual and open Organizer.

Step 2: Select the file you want to distribute and press the Share button.

Step 3: Select “iOS App Store Package (.ipa) and press next.

Step 4: A new window will which will ask you to enter the name of the ipa file. There is a check box at the bottom of the screen “Save for Enterprise Distribution”, select this check box.

Step 5: The window will expand to look something like this.

It will ask you few information on where you want to host the file, its icons and title.

Make sure you enter the application URL to the complete url of the file you would host on your server. Then enter title, subtitle, large icon url (512×512) and small icon url (57×57). Once you select the “ok” a .ipa file and .plist file will save in your select folder.

Step 6: Now we need to create a html file which will have the link of the plist file. Here is the sample file –

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Sushi App</title>
</head>
<body>
  <ul>
    <li><a href="itms-services://?action=download-manifest&url=http://122.160.153.125/sushi_ota_16_05_2012.plist"> Tap Here to Install the Application</a>
  </li>
  </ul>
</body> </html>

Notice the url in form – itms-services://?action=download-manifest&url=http://122.160.153.125/sushi_ota_16_05_2012.ipa
The above is just a sample html which have only the link, you can create more good looking files but just be careful with the link.

Step 7: Now upload .ipa file, .plist file and .html file on the webserver (which you mentioned while saving the ipa file).

Step 8: Open the html file in safari and tap the link to install the app on your device.