Apple has put a number of restrictions in place to protect the privacy of its customers. In this quick tip, I tell you what you need to know about these changes and I show you how you can update your applications.
1. Querying URL Schemes
I assume you already know that an iOS application can ask the operating system to launch another application using a URL scheme. In its simplest form, it works something like this.
- let URLAsString = "tweetbot://_bartjacobs/timeline"
- if let URL = NSURL.init(string: URLAsString) {
- UIApplication.sharedApplication().openURL(URL)
- }
- let URLAsString = "tweetbot://_bartjacobs/timeline"
- if let URL = NSURL.init(string: URLAsString) {
- if UIApplication.sharedApplication().canOpenURL(URL) {
- UIApplication.sharedApplication().openURL(URL)
- } else {
- print("Cannot Open URL")
- }
- }
- Applications built against the iOS 9 SDK are forced to whitelist the URL schemes they would like to query. In other words, a call to canOpenURL(_:) fails if the URL isn't added to a whitelist in the application's Info.plist.
- Applications not built against the iOS 9 SDK continue to work as expected. There is one limitation, though. An application can only query 50 distinct URL schemes. Subsequent requests return false and throw an error. The documentation emphasizes that this limitation is reset when the user reinstalls or upgrades the application.
Let me show you what this means in practice by creating a simple application that opens Tweetbot, my favorite Twitter client. Create a new project in Xcode 7 and choose the Single View Application template. Name the project Schemes and set Language to Swift.
![]() |
![]() |
- // MARK: - Actions
- @IBAction func openTweetbot(sender: AnyObject) {
- }
![]() |
3. Before iOS 9
Before Apple imposed the aforementioned restrictions on querying URL schemes, you could do the following:
- @IBAction func openTweetbot(sender: AnyObject) {
- let application = UIApplication.sharedApplication()
- let URLAsString = "tweetbot://_bartjacobs/timeline"
- guard let URL = NSURL.init(string: URLAsString) else { return }
- guard application.canOpenURL(URL) else { return }
- // Open URL
- application.openURL(URL)
- }
4. iOS 9
If you build the application in Xcode 7 and tap the Open Tweetbot button, canOpenURL(_:) returns false and the operating system throws an error that looks something like this:
- Schemes[9227:3539016] -canOpenURL: failed for URL: "tweetbot://_bartjacobs/timeline" - error: "This app is not allowed to query for scheme tweetbot"
If you update the implementation of openTweetbot(_:) as shown below and you have Tweetbot installed, the application is able to open Tweetbot when the button is tapped. This emphasizes that Apple wants to limit the (mis)use of canOpenURL(_:), not openURL(_:).
- @IBAction func openTweetbot(sender: AnyObject) {
- let application = UIApplication.sharedApplication()
- let URLAsString = "tweetbot://_bartjacobs/timeline"
- guard let URL = NSURL.init(string: URLAsString) else { return }
- // Open URL
- application.openURL(URL)
- }
Fortunately, there is an easy solution to this problem. As of iOS 9, Apple asks developers to whitelist the URL schemes an application would like to query. This is as simple as adding an entry to the application's Info.plist.
Open Info.plist, add a key named LSApplicationQueriesSchemes, and set the type of the value to Array. Add an item of type String to the array and set its value to tweetbot.
![]() |
- @IBAction func openTweetbot(sender: AnyObject) {
- let application = UIApplication.sharedApplication()
- let URLAsString = "tweetbot://_bartjacobs/timeline"
- guard let URL = NSURL.init(string: URLAsString) else { return }
- guard application.canOpenURL(URL) else { return }
- // Open URL
- application.openURL(URL)
- }
Most applications won't have a problem with Apple's new policy. It is clear Apple aims to protect the privacy of its customers by limiting the information applications can extract from the operating system. Applications are sandboxed on iOS and Apple wants to control how much information an application can extract from the environment the sandbox lives in.
Whitelisting URL schemes isn't a big pain for most applications, but it can become tedious if you plan to create an application launcher, such as Launch Center Pro. It is still possible to create a launcher as long as you whitelist every URL scheme the application would like to query. This can be pretty tedious, though.
Written by Bart Jacobs
If you found this post interesting, follow and support us.
Suggest for you:
iOS 10 Projects: Build Amazing Apps with Apple's Newest iOS
iOS 10 & Swift 3: From Beginner to Paid Professional
Complete Beginners Guide to iOS Development - Build 10 Apps
The Complete iOS 10 Developer - Build Real Apps with Swift 3
Swift 3 and iOS 10 The Final Course Learn to Code like a Pro




No comments:
Post a Comment