LeadKit/docs/tideeplink/deeplinks.md

5.3 KiB
Raw Blame History

Deeplink API

TIDeeplink добавляет сервис TIDeeplinksService для обработки диплинков

Как настроить

  1. Создать представителей класса Deeplink
import Foundation
import TIDeeplink
import UIKit

extension Deeplink {
    static var editProfile: Deeplink {
        Deeplink(rawValue: "editProfile")
    }

    static var office: Deeplink {
        Deeplink(rawValue: "office")
    }
}
  1. Создать объект, соответствующий протоколу 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 ?? ""
    }
}
  1. Реализовать у объекта отвечающего за навигацию протокол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()