Technology

Make a file accessible when iPhone locked with Passcode or Touch ID

0 466

During my recent project, we encounter a unique problem, in one of the test phone, we were not able to access physical files on the IOS file system. It was strange, the code worked perfectly well everywhere else.

Upon digging deeper into the problem, we found the problem exists because the phone in question was PASSWORD protected. So whenever the application went into background state & the phone is locked then our code was not able to access the filesystem.

In order to resolve the issue, we had to set the security attribute for all the files which we wanted to access in background mode. Basically, to disable security check, we have to set key NSFileProtectionKey to NSFileProtectionNone explicitly.

Working with NSFileManager Class
When we are working with NSFileManager class we have two method where we can set this key,
one at creation of file using following method

- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSString *, id> *)attributes error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
and another, set attribute for a file using below method
- (BOOL)setAttributes:(NSDictionary<NSString *, id> *)attributes ofItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
For example
NSError *error;
BOOL fileAttributeUpdated = [[NSFileManager defaultManager] setAttributes:@{NSFileProtectionKey : NSFileProtectionNone} ofItemAtPath:<# file path #> error:&error];
 
if (!fileAttributeUpdated || error) {
//TODO: Somthing when file attribute not updated or encounter some error.

}

Working with NSData Class

When we are working with NSData class, write data on file system using one of the data writing method provided by class. In those method take an argument writeOptionsMask of type NSDataWritingOptions, we have to provide value NSDataWritingFileProtectionNone.

Working with Sqlite
If you want to access SQLITE database file from background then, you need to open sqlite db file, set an additional flag value SQLITE_OPEN_FILEPROTECTION_NONE.
e.g.
sqlite3_open_v2(<# file path #>, <# reference of sqlite pointer  #>, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL);

To read more about security in iOS refer
https://www.apple.com/business/docs/iOS_Security_Guide.pdf

About the author / 

Ravi Kumar

Leave a reply

Your email address will not be published. Required fields are marked *


*