Every file stored on an iOS device is protected by one of four types of data that determine when it can be read and written. Developers can set these types of protection either by authorization or programmatically. As far as possible, you should use such mechanisms to protect user data. In order of effectiveness, the four methods are as follows:
Files can only be accessed when the device is unlocked. When the device is locked, your application will receive a UIApplicationProtectedDataWillBecomeUnavailable notification, and after 10 seconds, the losing access to the protected file. Use this mechanism as often as possible, but don’t use it for applications that need to run continuously in the background.
When the device is locked, files can still be created, and open files can continue to be accessed. With this mechanism, we can perform all kinds of related tasks in the background — such as saving new data or updating a database.
When the device is booted, the corresponding files can be accessed at any time after the user enters a password — even if the device is locked. In this way, you can read files running in the background at any time.
NSFileProtectionNone
Files are always accessible. The system needs to use this mechanism in some cases, but it is not suitable for the vast majority of third-party applications.
If you want to access the protected files, the operation returns NSFileReadNoPermissionError (code 257) or NSFileWriteNoPermissionError error code (513).
Those interested can refer to Apple’s iOS Security Whitepaper for more technical information related to the above types of protection.
It is important to note that data protection mechanisms do not apply to emulators. The FileVault encryption mechanism used on Mac devices also works in a completely different way. Even if the protection type is set, it does not take effect on subsequent reads. You will always read NSURLFileProtectionCompleteUntilFirstUserAuthentication – at least on my Mac. Therefore, you must test the data protection capability on the direct machine.
You don’t need to do anything to do this — it’s been the default on all versions of iOS since iOS 7.
You or extension of the application of the container file created specifically how to use the default protection level, depends on the com. Apple. The developer. The default – data – protection, permissions, the Xcode is shown as “data protection” (data protection).
You need to set this option for the relevant application and all its extensions. In this connection, the following two points should be noted:
1. According to Quinn “The Eskimo! According to apple’s developer forum, this permission needs to be set before the app is installed.
The default data protection level in your permissions Settings (stored in your App ID through the configuration file) is only used during the creation of the App container.
In my own research, if you change the permissions of an installed app, sometimes it will apply the new level to subsequent files, but sometimes it won’t. To be sure, however, changes don’t affect existing files, so unless you’re developing a new app, it’s best to set the protection type programmatically. We will elaborate on this later.
2. Since this permission only applies to your application or extension container, you need to programmatically set the protection level for the shared container.
With these considerations in mind, permissions are easy to set. In your Xcode project Settings, head to the app or extension’s “Capabilities” TAB and enable “Data Protection.” It’s so convenient.
As a result, a data protection permission will be added to your application permission file (if it doesn’t already exist, create another one) with the value set to NSFileProtectionComplete. It will also enable data protection on top of developer App ids in Apple developer websites Certificates, Identifiers & Profiles.
You can also see Apple’s App Launch Guide in the “Enable Data Protection” section, which provides a brief description of how to update this Capabilities.
Next up is NSFileProtectionComplete (as described above), Then make protection level changes to permissions files and App ids in the Certificates, Identifiers & Profiles section of the Apple developer website. You must manually synchronize these two values or you will get invalid permissions at build time.
Here’s the navigation flow: Identifiers > App IDs > Edit > Data Protection > Sharing and Permissions. You can set one of three protection levels here (but not NSFileProtectionNone).
The key focus of the permission documents for NSFileProtectionCompleteUnlessOpen. I found that Xcode did not update the changes made to the configuration files on the site, even when auto-configuring. You can delete the ~ / Library/MobileDevice/Provisioning Profiles/to force the Xcode to download the config file. If you’re having trouble, you can also choose to use the Provisioning QuickLook plug-in provided by Craig Hockenberry to quickly determine if the current configuration is correct.
You can’t set None as the default level because this option is not available in the Certificates, Identifiers & Profiles section of the Apple developer website. In addition, you should never choose to give up on yourself.
If your application has been installed on the user equipment, and did not set the permissions, and other equipment NSFileProtectionCompleteUntilFirstUserAuthentication you want, you will need to set programmatically protection type, in order to protect the new file and upgrade existing files. Note that you do not need to set up rights to use these apis.
Let’s start with a single file that contains multiple protection types that the API accepts as options. If you want to write a new file from Data/NSData, use:
try data.write(to: fileURL, options: .completeFileProtection)
Copy the code
For an existing file, you can use NSFileManager/FileManager or NSURL:
try FileManager.default.setAttributes([.protectionKey: FileProtectionType.complete], ofItemAtPath: fileURL.path)
// or
// cast as NSURL because the fileProtection property of URLResourceValues is read-only
try (fileURL as NSURL).setResourceValue(URLFileProtection.complete, forKey: .fileProtectionKey)
Copy the code
In the case of Core Data, you can pass this protection type when adding persistent storage:
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: [NSPersistentStoreFileProtectionKey: FileProtectionType.complete])
Copy the code
For those interested, see the section “Protecting Data with on-disk encryption” in Apple’s iOS App Programming guide.
Quinn”The Eskimo!” And posted this very useful piece of information on apple’s developer forums:
By default, data protection values are inherited directly from the parent directory during project creation. For example, if you set the directory to NSFileProtectionComplete, any project created in that directory will be set to NSFileProtectionComplete by default.
The permissions file controls the data protection value in the root directory of the container, and this value will also affect the protection level of any content created in the container. However, if you explicitly set this value for a directory, subsequent entries created within that directory will default to this new value.
So, you can use a FileManager/NSFileManager or NSURL as directory URL to replace the file URL, or provide the protection properties when creating this directory:
try FileManager.default.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: [.protectionKey: FileProtectionType.complete])
Copy the code
This way, you can then create files in that directory as normal.
When you set a protection level for a directory, the protection level of all existing files in the directory does not change. Therefore, you need to set the correct protection level for each file in the directory.
You can use the FileManager. DirectoryEnumerator/NSDirectoryEnumerator to finish the work:
guard let directoryEnumerator = FileManager.default.enumerator(at: directoryURL, includingPropertiesForKeys: [], options: [], errorHandler: { url, error -> Bool in
print(error)
return true
}) else {
print("Could not create directory enumerator at \(directoryURL.path)")
return
}
// NSEnumerator is not generic in Swift so we have to deal with Any.
for urlAsAny in directoryEnumerator {
do {
try (urlAsAny as! NSURL).setResourceValue(URLFileProtection.complete, forKey: .fileProtectionKey)
} catch {
print(error)
}
}
Copy the code
PSPDFKit Instant can be easily used to protect your files. If you set a default protection level, that protection will be automatically used on Instant, and you don’t have to do anything else. If you want to set different levels of protection for specific files and comments stored in Instant, you can use the dataDirectory class attribute on PSPDFInstantClient to access Instant’s data store path, and then use the change method mentioned above. Those interested can refer to our Instant Data Protection guide for more details.
https://pspdfkit.com/blog/2017/how-to-use-ios-data-protection/
1.NSFileProtectionComplete:
https://developer.apple.com/documentation/foundation/nsfileprotectioncomplete
2.NSFileProtectionCompleteUnlessOpen:
https://developer.apple.com/documentation/foundation/nsfileprotectioncompleteunlessopen
3.NSFileProtectionCompleteUntilFirstUserAuthentication:
https://developer.apple.com/documentation/foundation/nsfileprotectioncompleteuntilfirstuserauthentication
4.NSFileProtectionNone:
https://developer.apple.com/documentation/foundation/nsfileprotectionnone
5. IOS Security Whitepaper:
https://www.apple.com/business/docs/iOS_Security_Guide.pdf
6.Provisioning QuickLook plug-in:
https://github.com/chockenberry/Provisioning
7.Instant Data Protection Guide:
https://pspdfkit.com/guides/ios/current/instant/data-protection/
Mobile development front
Mobile Frontier is InfoQ’s vertical community focused on mobile development technology. Please email your submission to [email protected], marked “Mobile Development Front Submission”.
The hottest technology at the moment is AI. So, what are the cases of AI implementation at present? How can machine learning, deep learning, NLP, image recognition and other technologies be used to solve business problems?
At AICon2018 Global Artificial Intelligence Technology Conference, we invited AI application landing directors from 360, JD, Tencent, Baidu, Etsy, Microsoft, Ele. me, Moride, Sogou, Ctrip, Weibo and other well-known domestic and foreign enterprises to share their latest AI landing cases and technical exploration for reference. May give you some inspiration, at present, 20% off registration is hot, click “read the original article” to learn more!