Статьи

Схемы конфиденциальности и URL в iOS 9

Начиная с iOS 9, сторонние приложения больше не могут запрашивать произвольные схемы URL. Несколько сторонних приложений, особенно Twitter, неправильно использовали метод canOpenURL(_:) класса UIApplication для отслеживания того, какие приложения установлены на конкретном устройстве.

Apple ввела ряд ограничений для защиты конфиденциальности своих клиентов. В этом кратком совете я расскажу вам, что вам нужно знать об этих изменениях, и покажу, как вы можете обновить свои приложения.

Я предполагаю, что вы уже знаете, что приложение iOS может попросить операционную систему запустить другое приложение, используя схему URL. В простейшем виде он работает примерно так.

1
2
3
4
5
let URLAsString = «tweetbot://_bartjacobs/timeline»
 
if let URL = NSURL.init(string: URLAsString) {
    UIApplication.sharedApplication().openURL(URL)
}

Иногда полезно сначала спросить операционную систему, можно ли открыть URL-адрес, прежде чем открывать его. Это особенно полезно, если вы хотите обновить пользовательский интерфейс в зависимости от того, какие приложения установлены пользователем и с каким приложением вы можете взаимодействовать. В приведенном выше примере openURL(_:) не будет успешным, если Tweetbot не установлен на устройстве пользователя. Чтобы спросить операционную систему, можно ли открыть URL-адрес, вы можете использовать метод canOpenURL(_:) класса UIApplication .

1
2
3
4
5
6
7
8
9
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»)
    }
}

К сожалению, некоторые приложения, особенно Twitter, неправильно используют canOpenURL(_:) чтобы определить, какие приложения установлены на устройстве пользователя. По словам Apple, это нарушает конфиденциальность пользователя. В результате Apple больше не терпит этот тип неправильного использования в iOS 9, накладывая два ограничения.

  • Приложения, созданные на основе iOS 9 SDK, вынуждены вносить в белый список те схемы URL, которые они хотели бы запросить. Другими словами, вызов canOpenURL(_:) не выполняется, если URL-адрес не добавлен в белый список в Info.plist приложения.
  • Приложения, не созданные для iOS 9 SDK, продолжают работать, как и ожидалось. Однако есть одно ограничение. Приложение может запросить только 50 различных схем URL. Последующие запросы возвращают false и выдают ошибку. В документации подчеркивается, что это ограничение сбрасывается, когда пользователь переустанавливает или обновляет приложение.

Позвольте мне показать вам, что это означает на практике, создав простое приложение, которое открывает мой любимый клиент Twitter Tweetbot. Создайте новый проект в Xcode 7 и выберите шаблон приложения Single View . Назовите Схемы проекта и установите язык на Swift .

Настройка проекта
Настройка проекта

Прежде чем мы рассмотрим схемы URL, я хочу настроить пользовательский интерфейс. Откройте ViewController.swift и добавьте действие openTweetbot(_:) в класс ViewController . Вы можете оставить его реализацию пустой пока.

1
2
3
4
5
// MARK: — Actions
 
@IBAction func openTweetbot(sender: AnyObject) {
 
}

Откройте Main.storyboard и добавьте кнопку в представление View Controller Scene . Установите заголовок кнопки на « Открыть Tweetbot» и соедините кнопку с действием openTweetbot(_:) контроллера представления, openTweetbot(_:) мы создали ранее.

Настройка интерфейса пользователя

Мы не собираемся делать что-то слишком сложное. Когда я нажимаю кнопку « Открыть Tweetbot» , операционная система открывает Tweetbot, показывая мою временную шкалу. Вы можете прочитать больше о схемах URL для Tweetbot на сайте Tapbots .

Прежде чем Apple наложит вышеупомянутые ограничения на запросы схем URL, вы можете сделать следующее:

01
02
03
04
05
06
07
08
09
10
@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)
}

Мы спрашиваем операционную систему, может ли она открыть URL-адрес, который мы передаем canOpenURL(_:) . Если этот метод возвращает false на iOS 8 и ниже, мы знаем, что интересующее нас приложение не установлено на устройстве пользователя, при условии, что схема URL относится к другому приложению. Это может быть очень полезно, но Apple хочет наложить некоторые ограничения на API, чтобы избежать злоупотреблений.

Если вы создаете приложение в Xcode 7 и нажимаете кнопку Open Tweetbot , canOpenURL(_:) возвращает false и операционная система выдает ошибку, которая выглядит примерно так:

1
Schemes[9227:3539016] -canOpenURL: failed for URL: «tweetbot://_bartjacobs/timeline» — error: «This app is not allowed to query for scheme tweetbot»

Операционная система явно сообщает нам, что приложению не разрешено знать , может ли оно открыть URL-адрес, который мы передаем canOpenURL(_:) . Это не означает, что приложению не разрешено открывать URL, который мы передали openURL(_:) .

Если вы обновите реализацию openTweetbot(_:) как показано ниже, и у вас установлен Tweetbot, приложение сможет открыть Tweetbot при нажатии кнопки. Это подчеркивает, что Apple хочет ограничить (неправильное) использование canOpenURL(_:) , а не openURL(_:) .

1
2
3
4
5
6
7
8
9
@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)
}

К счастью, есть простое решение этой проблемы. Начиная с iOS 9, Apple просит разработчиков внести в белый список схемы URL, которые приложение хотело бы запросить. Это так же просто, как добавить запись в Info.plist приложения.

Откройте Info.plist , добавьте ключ с именем LSApplicationQueriesSchemes и установите тип значения Array . Добавьте элемент типа String в массив и установите его значение в tweetbot .

Если мы openTweetbot(_:) к его первоначальной реализации, мы сможем вызвать canOpenURL(_:) без ошибок операционной системы. Вы можете добавить столько схем URL в Info.plist вашего приложения.

01
02
03
04
05
06
07
08
09
10
@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)
}

У большинства приложений не будет проблем с новой политикой Apple. Ясно, что Apple стремится защитить конфиденциальность своих клиентов путем ограничения информации, которую приложения могут извлекать из операционной системы. Приложения изолированы в iOS, и Apple хочет контролировать, сколько информации приложение может извлечь из среды, в которой находится песочница.

Схемы URL-адресов, включенных в белый список, не являются большой болью для большинства приложений, но могут стать утомительными, если вы планируете создать панель запуска приложений, например Launch Center Pro . Все еще можно создать модуль запуска, если вы добавляете в белый список каждую схему URL, которую приложение будет запрашивать. Это может быть довольно утомительно, хотя.