5.3 KiB
Deeplink API
TIDeeplink добавляет сервис TIDeeplinksService для обработки диплинков
Как настроить
- Создать представителей класса
Deeplink
import Foundation
import TIDeeplink
import UIKit
extension Deeplink {
static var editProfile: Deeplink {
Deeplink(rawValue: "editProfile")
}
static var office: Deeplink {
Deeplink(rawValue: "office")
}
}
- Создать объект, соответствующий протоколу
DeeplinkMapper. Его задачей будет - преобразование URL в диплинк
final class ProjectDeeplinkMapper: DeeplinkMapper {
private let availableDeeplinks: [Deeplink] = [.office, .editProfile]
func map(url: URL) -> Deeplink? {
let stringData = parse(url)
return availableDeeplinks.find(byRawValue: stringData)
}
private func parse(_ url: URL) -> String {
url.host ?? ""
}
}
- Реализовать у объекта отвечающего за навигацию протокол
DeeplinkHandler. В необходимом для реализации методеhandle(deeplink:)нужно обработать передаваемый диплинк и вернуть соответствующее действие
class MainCoordinator: DeeplinkHandler {
func openEditProfileScreen() {
print("Presenting edit profile view controller")
}
func openOfficesScreen() {
print("Presenting offices view controller")
}
// MARK: DeeplinkHandler
func handle(deeplink: Deeplink) -> Operation? {
if deeplink == .editProfile {
return BlockOperation { [weak self] in
self?.openEditProfileScreen()
}
}
if deeplink == .office {
return BlockOperation { [weak self] in
self?.openOfficesScreen()
}
}
return nil
}
}
Опционально 4. Создать сабкласс TIDeeplinksService для удобного использования по проекту
final class ProjectDeeplinksService: TIDeeplinksService {
static let shared = ProjectDeeplinksService()
}
Создаем и передаем в сервис Mapper и Handler
Так же можно воспользоваться инициализатором
init(mapper:handler:operationQueue:)
let coordinator = MainCoordinator()
let mapper = ProjectDeeplinkMapper()
ProjectDeeplinksService.shared.deeplinkMapper = mapper
ProjectDeeplinksService.shared.deeplinkHandler = coordinator
В AppDelegate использвуем методы deferredHandle(url:) и handlePendingDeeplinks() для обработки диплинков.
deferredHandle(url:): пытается создать из URL диплинк и добавить его в очередь на обработкуhandlePendingDeeplinks(): обрабатывает первый в череди диплинк
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
ProjectDeeplinksService.shared.deferredHandle(url: url)
ProjectDeeplinksService.shared.handlePendingDeeplinks()
return true
}
guard let url = URL(string: "app://office/") else {
fatalError()
}
application(.shared, open: url)
В качестве DeeplinkHandler можно использовать базовую реализацию BaseNavigationStackDeeplinkHandler, которая позволяет искать handler в иерархии view, способный обработать диплинк
class NavigationController: UINavigationController, DeeplinkHandler {
func handle(deeplink: Deeplink) -> Foundation.Operation? {
nil
}
}
class ViewController: UIViewController, DeeplinkHandler {
func handle(deeplink: Deeplink) -> Operation? {
if deeplink == .editProfile {
return BlockOperation {
print("Presenting edit profile view controller")
}
}
if deeplink == .office {
return BlockOperation {
print("Presenting offices view controller")
}
}
return nil
}
}
Создание Handler. Для настройки передается rootViewController, который должен наследоваться от UIViewController и соответствовать протоколу DeeplinkHandler. С этого контроллера будет начинаться поиск обработчика
typealias ProjectNavigationStackDeeplinkHandler = BaseNavigationStackDeeplinkHandler<NavigationController>
let viewController = ViewController()
let navigationController = NavigationController(rootViewController: viewController)
let handler = ProjectNavigationStackDeeplinkHandler(rootViewControllerKeeper: navigationController)
Далее handler может передаваться для использования в TIDeeplinksService
let service = TIDeeplinksService(mapper: mapper, handler: handler)
service.deferredHandle(url: url)
service.handlePendingDeeplinks()
RunLoop.main.run()