Skip to content

Instantly share code, notes, and snippets.

@moderateepheezy
Last active May 3, 2020 11:00
Show Gist options
  • Select an option

  • Save moderateepheezy/af9b41460629dcb69f5ececa1fa58912 to your computer and use it in GitHub Desktop.

Select an option

Save moderateepheezy/af9b41460629dcb69f5ececa1fa58912 to your computer and use it in GitHub Desktop.
Deep linking iOS: A prototype of how you can implement deep linking with Coordinator in an iOS app
typealias Param = [AnyHashable: Any]?
/// We use `CordinatorActionFactory` in AppDelegate to process data
final class CordinatorActionFactory {
/// make a CoordinatorAction from url scheme data gotten from `CordinatorActionFactory`
func make(from urlSchemeHost: String, parameters: [String: Any]) -> CoordinatorAction? {
var params = parameters
params["type"] = urlSchemeHost
return CoordinatorAction(data: params)
}
/// make a CoordinatorAction from push notifications gotten from `CordinatorActionFactory`.
func make(from notification: [AnyHashable: Any]?) -> CoordinatorAction? {
return CoordinatorAction(data: notification)
}
}
/// This are the base route that get information and push to sub base route
enum CoordinatorAction {
case payment(paymentRoute: PaymentRoutes)
case services(serviceRoute: ServicesRoute)
init?(data: Param) {
guard let data = data,
let type = data["type"] as? String,
let routeType = RouteType.init(rawValue: type)
else { return nil }
switch routeType {
case .payToGomoney:
self = .payment(paymentRoute: .payMoney(data: data))
case .requestPayment:
self = .payment(paymentRoute: .request(data: data))
case .payForData:
self = .services(serviceRoute: .bills(data: data))
}
}
}
/// This is what the backend defined as the type of information coming into the device.
enum RouteType: String {
case payToGomoney = "gomoney"
case requestPayment = "requestGoMoney"
case payForData = "buyData"
}
/// This are the routes `Payment` tab can push to base on the `RouteType`
/// coming from push notifications or other external
/// source of information
enum PaymentRoutes {
case payMoney(data: Param)
case request(data: Param)
case root
}
/// This are the routes `Service` tab can push to base on the `RouteType`
/// coming from push notifications or other external
/// source of information
enum ServicesRoute {
case bills(data: Param)
case root
}
protocol Cordinator {
func process(action: CoordinatorAction?)
}
/// Using the process in the main coordinator: MainCoordinator creates and holds all tab items
class MainCordinator: Cordinator {
func process(action: CoordinatorAction?) {
guard let action = action else { return }
switch action {
case .payment:
tabBarController.selectedIndex = 2
paymentsCoordinator.process(action: action)
break
case .services:
tabBarController.selectedIndex = 3
servicesCoordinator.process(action: action)
break
}
}
}
// Using the process in the payments coordinator, where `PaymentsCordinator` is a tab item
class PaymentsCordinator: Cordinator {
func process(action: CoordinatorAction?) {
guard let action = action else { return }
switch action {
case .payment(let paymentRoute):
switch paymentRoute {
case .payMoney(let data):
print(data as Any)
break
case .request(let data):
print(data as Any)
break
case .root:
break
}
default:
break
}
}
}
/// Using the process in the services coordinator, where `ServicesCordinator` is a tab item
class ServicesCordinator: Cordinator {
func process(action: CoordinatorAction?) {
guard let action = action else { return }
switch action {
case .services(let serviceRoute):
switch serviceRoute {
case .bills(let data):
print(data as Any)
break
case .root:
break
}
default:
break
}
}
}
//** Simple Use case **//
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private lazy var actionFactory = CoordinatorActionFactory()
private lazy var applicationCoordinator: ApplicationCoordinator = {
return ApplicationCoordinator(window: window!, container: container)
}()
// Get data from push notifcations
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
applicationCoordinator.process(action: self.actionFactory.make(from: userInfo))
}
/// Get data from custom url scheme
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if let scheme = url.scheme,
scheme.localizedCaseInsensitiveCompare("scheme.something") == .orderedSame,
let host = url.host {
var parameters: [String: String] = [:]
URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
parameters[$0.name] = $0.value
}
let action = self.actionFactory.make(from: host, parameters: parameters)
applicationCoordinator.process(action: action)
}
return true
}
}
@jogboms
Copy link
Copy Markdown

jogboms commented May 3, 2020

What happened to indentation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment