Закрывает SFSafariViewController по определенному URL-адресу

Я пытаюсь закрыть SFSafariViewController, когда дохожу до определенной страницы.

Но я не могу сделать это, пока пользователь явно не нажмет кнопку "Готово".

Я хочу получить URL-адрес, как только он достигнет определенной страницы, а затем отклонить контроллер представления. Затем я могу выбрать остальные, используя это

func safariViewControllerDidFinish(_ controller: SFSafariViewController){
    // do work here
}

Примечание. Этот вопрос уже задавался ранее, но я не смог найти удовлетворительных ответов.


person Moaz Khan    schedule 13.11.2017    source источник
comment
Встречали ли вы подобные функции в других приложениях? Я сомневаюсь, что это возможно.   -  person ullstrm    schedule 13.11.2017
comment
Я видел это в некоторых пользовательских API, где они используют URL-адрес обратного вызова, который вызывает эту функцию в приложении делегата приложения (_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {} и где они призывают уволить   -  person Moaz Khan    schedule 13.11.2017
comment
проверьте этот вопрос stackoverflow.com/questions/41349184/   -  person Moaz Khan    schedule 13.11.2017
comment
Тогда у вас есть :) Я думаю, что это единственный способ сделать это   -  person ullstrm    schedule 13.11.2017
comment
Пожалуйста, кто-нибудь может что-нибудь сказать по этому поводу? Как получить определенный URL-адрес в SFSafariViewController?   -  person Anil shukla    schedule 27.04.2018
comment
@Анилшукла, ты не можешь. Вам нужно внедрить глубокие ссылки.   -  person Moaz Khan    schedule 27.04.2018
comment
можешь дать что-нибудь на анализ? Это было бы полезно!   -  person Anil shukla    schedule 27.04.2018


Ответы (3)


Если вы зарегистрируете схему URI для своего приложения, у вас может быть ссылка на странице, которая вернет вас к вашему приложению. В этот момент вы будете в

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

вашего AppDelegate, и вы можете делать все, что пожелаете.

«Поскольку Safari View Controller имеет доступ к учетным данным пользователя, синхронизированным на всех их устройствах с помощью iCloud Keychain, вход в систему будет очень простым.[…] Это займет два шага. Во-первых, вы бы использовали свой собственный браузер в приложении, просто представив экземпляр SFSafariViewController.

И как только пользователь завершит вход в систему и сторонний веб-сервис перенаправит обратно в ваше приложение с настраиваемой схемой URL-адресов, которую вы ему передали, вы можете принять это в методе handleOpenURL вашего AppDelegate.

Оттуда вы можете проверить ответ и отклонить экземпляр SFSafariViewController, потому что вы знаете, что аутентификация выполнена.

Вот и все. Два шага».

Источник: http://asciiwwdc.com/2015/sessions/504#t=1558.026< /а>

Обратите внимание, что метод handleOpenURL устарел в пользу application:openURL:options:.

person DBD    schedule 22.05.2018
comment
этот метод не вызывается - person Vyachaslav Gerchicov; 31.05.2018
comment
@Vyachaslav - я добавил больше информации. Почему вы говорите, что метод не вызывается? - person DBD; 08.06.2018
comment
проблема, например, в моем случае: instagram api позволяет использовать схему URL-адресов http/https. В то же время кажется, что этот метод вызывается для пользовательской схемы, а не для http/https. И информации об этом в открытых источниках почти нет. - person Vyachaslav Gerchicov; 11.06.2018
comment
Верно. Это было бы проблемой. Чтобы вернуться в приложение, необходимо использовать специальную схему, например myapp://. Вы все равно могли бы сделать это, если бы у вас был веб-сайт. Попросите instagram API отправить пользователя на ваш веб-сайт/страницу, которая имеет перенаправление выгрузки на пользовательскую схему, используемую вашим приложением. Это дополнительный отказ, но он фактически вернет вас обратно в ваше приложение. - person DBD; 11.06.2018
comment
проблема в том, что Instagram перенаправляет на этот сайт с токеном в URL-адресе. Поэтому я не могу перенаправить его напрямую в свое приложение - кажется, я должен кодировать-декодировать его вручную (потому что методы app:openURL:... работают только с URL-адресом, а не с телом запроса - person Vyachaslav Gerchicov; 11.06.2018

Может быть, уже поздно, но я думаю, что это поможет любому найти тот же вопрос. Слушая делегата SFSafariViewControllerDelegate, вы можете использовать этот метод внутри

func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {}

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

 func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
    if URL.absoluteString == "WHATEVER YOUR LINK IS"{
        controller.dismiss(animated: true, completion: nil)
    }
}
person abdallah Nader    schedule 09.06.2020
comment
Эй, спасибо за это. Но является ли это действительной функциональностью? Если мы делаем в нашем приложении IOS, в моем случае, аутентификацию, нарушает ли это какие-либо правила магазина приложений? - person Ricardo Green; 25.06.2020
comment
Нет, это не нарушает никаких правил App Store. Я опубликовал 2 приложения с этой функцией. - person abdallah Nader; 30.06.2020
comment
Это не работает. Он не поднимается даже при перенаправлении с мобильного сафари. - person JamesTBennett; 06.08.2020

Вы не можете сделать это с SFSafariViewController. Вместо этого используйте WKWebView и реализуйте метод WKNavigationDelegate, например optional func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!), а затем прочитайте текущий URL. Определите свои действия на основе этого.

Вы можете использовать это, чтобы закрыть контроллер представления, в котором находится ваше веб-представление. К сожалению, вам придется создать свои собственные кнопки навигации (те, что есть у SFSafariViewController), если вы хотите разрешить пользователю доступ к ним. Вам не нужно их предоставлять.

person erik_m_martens    schedule 13.11.2017