Search code examples
iosswiftios8nsdocumentdirectory

Save pictures in swift where users can't access


I have an application that allows the user to take a photo and it saves immediately, however they are currently stored in the application documents directory which is accessible through programs like iFunBox. Here is how I save the images.

        var imageName = "SomeGeneratedImageName.jpeg"
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
        let documentsDirectory = paths.objectAtIndex(0) as NSString
        let path = documentsDirectory.stringByAppendingPathComponent(imageName)
        var data = UIImageJPEGRepresentation(image, 1)
        data.writeToFile(path, atomically: true)

Where do I save images so the user cannot access them even through programs such as iFunBox?

UPDATE - Answer Used

Based of of zaph's answer i encrypted the pictures before saving and when reading, using RNEncrytor Here is my save function:

        var imageName = "someImageName.jpeg"
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
        let documentsDirectory = paths.objectAtIndex(0) as NSString
        let path = documentsDirectory.stringByAppendingPathComponent(imageName)
        var data = UIImageJPEGRepresentation(image, 1) //change 1 for compression
        let encryptedData = RNEncryptor.faireseEncryptData(data, password: "password", error: nil)
        encryptedData.writeToFile(path, atomically: true)

and

    var imageName = "thatSameImageName.jpeg"
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths.objectAtIndex(0) as NSString
    let path = documentsDirectory.stringByAppendingPathComponent(imageName)
    var decryptedImg = RNDecryptor.faireseDecryptData(NSData(contentsOfFile: path), password: "theSamePass", error: nil)
    if(decryptedImg != nil) {
        //alert
    var image: UIImage? = UIImage(data: decryptedImg)
}

also to get this to work in swift there was some issue with the AES256 so i added some classes to the RNEncryptor.h, RNEncryptor.m, RNDecryptor.h, and the RNDecryptor.m

//To RNEncrpytor.h
+ (NSData *)faireseEncryptData:(NSData *)data password:(NSString *)password error:(NSError **)error;

.

//To RNEncryptor.m
+ (NSData *)faireseEncryptData:(NSData *)data password:(NSString *)password error:(NSError **)error {
return [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:password error:error]; }

.

//To RNDecryptor.h
+ (NSData *)faireseDecryptData:(NSData *)data password:(NSString *)password error:(NSError **)error;

.

//TO RNDecryptor.m
+ (NSData *)faireseDecryptData:(NSData *)data password:(NSString *)password error:(NSError **)error {
return [RNDecryptor decryptData:data withSettings:kRNCryptorAES256Settings password:password error:error]; }

Solution

  • Save with writeToFile:options:error: with a NSDataWritingOptions of NSDataWritingFileProtectionComplete or explicitly encrypt and decrypt as needed saving the password in the Keychain, see RNCryptor for a good encryption routine.

    Generally saving large data items in a database is not a good solution.