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.

A short guide to Homebrew

What is Homebrew

Homebrew is a package management system for Mac OS X.

How to install Homebrew

Step 1) Homebrew has a dependency on Xcode and Xcode command line tools. So first install latest Xcode and command line tools by going Xcode -> Preference, Choose “Downloads” tab and click on “install the Command Line Tools”

Step 2) Run this command in Terminal to install Homebrew –

ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Now let’s go over a few common tasks you will have with Homebrew.

brew doctor

If you are doing any system update like OS X update or Xcode update you can check Homebrew’s health using this command. Homebrew will tell you if there is any issue with it or generally how to fix that issue.

brew update

This will update your Homebrew formula list. Please note that this will not update all your installed package it will just update the version and availability of packages you could install. You should run this often to keep your formula list updated or whenever you install/upgrade something new.

brew upgrade

This will update your installed packages.

brew install [package name here]

This will install new packages for you i.e.

brew install mysql

brew list

This will list all the packages that are currently installed on your system.

brew info [package name here]

This will show you information about a installed package.

brew uninstall [package name here]

The will remove package you previously installed.

So that’s is pretty much everything about Homebrew.

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!

Keyboard not working in iOS simulator?

If your keyboard (mac keyboard) is not working in the iPhone simulator you must have something wrong in iPhone Simulator preference file.

To fix the problem follow this –

0) Quit Xcode and simulator
1) Press ‘command+shift+g’ .. it will open the “go to folder” dialog.
2) type “~/Library/Preferences” in this dialog to go to your preference folder.
3) Delete “com.apple.iphonesimulator.plist” in this folder
4) Done. “com.apple.iphonesimulator.plist” will be regenerated when you start simulator again.

Alternatively you can also do this with just one command.

Open terminal and fire –

rm ~/Library/Preferences/com.apple.iphonesimulator.plist

This will do the trick in one step! Just make sure you quit Xcode and simulator before running this.

multiple SSH keys for github (or bitbucket) accounts & SSH Config

If you are using multiple github account for work and home projects or you are using one github account and one bitbucket account or any other git hosting service out there with SSH you have to manage SSH keys using a config file.

Lets go through each step for setting up github and bitbucket account-


Step 1: ssh keys

Create any keypairs you’ll need. In this example I’ve named these key pairs as ‘id_rsa_github’ and ‘id_rsa_’bitbucket:

ssh-keygen -t rsa -C “saurabhsharma@work.com"
ssh-keygen -t rsa -C “saurabhsharma@home.com”


Step 2: ssh config

Set up multiple ssh profiles by creating/modifying ~/.ssh/config. Note the differing ‘Host’ values:

# For GitHub
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_github

# For BitBucket
Host bitbucket.org
HostName bitbucket.org
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_bitbucket

Step 3: ssh-add

You may or may not have to do this. To check, list identity fingerprints by running:

$ ssh-add -l

2048 1f:1a:b8:69:cd:e3:ee:68:e1:c4:da:d8:96:7c:d0:6f saurabhsharma@home.com (RSA)
2048 6d:65:b9:3b:ff:9c:5a:54:1c:2f:6a:f7:44:03:84:3f saurabhsharma@work.com (RSA)

If your entries aren’t there then run:

ssh-add ~/.ssh/id_rsa_github
ssh-add ~/.ssh/id_rsa_bitbucket

Step 4: test

To test you’ve done this all correctly, I suggest the following quick check:

$ ssh -T git@github.com

Hi Saurabh! You’ve successfully authenticated, but GitHub does not provide shell access.

I hope this will save someone’s hair!!

How to calculate MD5 hash in node.js

First a little intro to Hashes, for those who are very new to Hashes

What is a Hash?

A hash is a fixed-length string of bits that is procedurally and deterministially generated from some arbitrary block of source data. Some important properties of these hashes (the type useful for cryptography) include:

Fixed length: This means that, no matter what the input, the length of the hash is the same. For example, md5 hashes are always 128 bits long whether the input data is a few bits or a few gigabytes.

Deterministic: For the same input, you should expect to be able to calculate exactly the same hash. This makes hashes useful for checksums.

Collision-Resistant: A collision is when the same hash is generated for two different input blocks of data. Hash algorithms are designed to be extremely unlikely to have collisions — just how unlikely is a property of the hash algorithm. The importance of this property depends on the use case.

Unidirectional: A good hash algorithm is easy to apply, but hard to undo. This means that, given a hash, there isn’t any reasonable way to find out what the original piece of data was.

Some of the most common hash types are SHA1 and MD5

Now how to calculate Hash in Node.js

Node.js have a module named Crypto, which has a method called createHash which allows you to calculate a hash. Its only argument is a string representing the hash This example finds the md5 hash for the string, “I love Node.js”

var crypto = require('crypto');
var name = 'I love Node.js';
var hash = crypto.createHash('md5').update(name).digest("hex");
console.log(hash); 

The update method is used to push data to later be turned into a hash with the digest method. update can be invoked multiple times to ingest streaming data, such as buffers from a file read stream. The argument for digest represents the output format, and may either be “binary”, “hex” or “base64”. It defaults to binary.

How to use HTML with Express (Node.js)

There is no direct way of using HTML under Jade, which comes with Express by default, But if you want to use more HTML-style templates, you could use els instead of Jade. Follow these steps to use ejs instead of Jade –

1) Install ejs –

npm install ejs

2) Set your template engine in app.js as ejs


// app.js
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

3) Now in your route file you can assign template variables –

// ./routes/index.js
exports.index = function(req, res){
  res.render('index', { title: 'ejs' });
};

4) Then you can create your html view in /views directory.

// ./views/index.html
<h1>Welcome to <%= title %>!</h1>

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.