I'm trying to implement Universal links I'm able to launch the app but stuck in routing. How to decode ids and bind them with viewcontrollers. Link looks like this.
Here is how looks my code
class DeeplinkParser {
static let shared = DeeplinkParser()
private init(){}
func parseDeepLink(_ url: URL) -> DeeplinkType? {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true), let host = components.host else {
return nil
}
var token = components.user?.components(separatedBy: "/")
var pathComponents = components.path.components(separatedBy: "/")
var linkFragment = components.fragment?.components(separatedBy: "/")
let queryItems = components.queryItems
//var pathComponents = url.pathComponents
pathComponents.removeFirst()
switch host {
case "app.icontrolapp.se":
let projectIdString = pathComponents.filter({ $0.hasPrefix("project_")}).first
if let projectId = projectIdString?.components(separatedBy: "_").last {
findSession(components: components)
if let urlPath = parseDeepLink(url) {
//print("Url Path: \(urlPath)")
let proj = URLSession.shared.dataTask(with: url) {(data, response, error) in
if error != nil {
print("Error\(error)")
} else {
if let usableData = data {
print(usableData)
}
}
}
proj.resume()
}
print("Path Components 0: \(pathComponents[0])")
print("Path Components 1: \(pathComponents[1])")
print("Path Components 2: \(pathComponents[2])")
print("Path Components 3: \(pathComponents[3])")
print("ProjectId: \(projectId)")
print(findSession(components: components))
return DeeplinkType.projects(.details(id: projectId))
}
case "closeout.icontrolapp.se":
guard var tokenId = linkFragment?[2], let projetId = linkFragment?[3], let teamId = linkFragment?[4], let inspectionId = linkFragment?[5], let issueId = linkFragment?[6] else { return nil }
//guard let userId = linkFragment?[2], let teamId = linkFragment?[4], let inspectionId = linkFragment?[5], let issueId = linkFragment?[6] else { return nil }
print("Token ID \(tokenId)")
print("Project ID \(projetId)")
print("Team ID \(teamId)")
print("Inspection ID \(inspectionId)")
print("Issue ID \(issueId)")
let session = Session.currentSession()
session?.userID?.append(tokenId)
tokenId.append((session?.userID)!)
let project = ProjectEntity.get(projetId)
let report = Report.get(inspectionId)
print("Report: \(report!)")
let issue = Issue.get(issueId)
session?.selectProject(project)
session?.selectReport(report)
//session?.selectReport(report)
CurrentIssue.sharedInstance.makeIssueCurrentSelection(issue!, db: CBLDatabase.db()!)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let window = appDelegate.window!
return DeeplinkType.observation(tokenId: tokenId, projectId: projetId, teamId: teamId, issueId: issueId, inspectionId: inspectionId)
default:
break
}
return nil
}
}
import UIKit
enum DeeplinkType{
enum Projects {
case root
case details(id: String)
}
case projects(Projects)
case projectId(Projects)
case observation(tokenId: String, projectId: String, teamId: String, issueId: String, inspectionId: String)
case teamId
case request(id: String)
}
enum Route {
case issue
case bluePrint
init?(url: URL) {
switch url.absoluteString {
case "\(url)//defect_2017-08-31_16_53_test_15041912125876": self = .issue
default: return nil
}
}
}
var Deeplinker = DeepLinkManager()
class DeepLinkManager{
fileprivate init(){}
private var deeplinkType: DeeplinkType?
func handleRoute(route: Route) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let window = appDelegate.window!
let issueVC = window.rootViewController as! IssuesViewController
switch route {
case .issue: issueVC.showMenu()
default: brea
}
}
@discardableResult
func handleDeeplink(url: URL) -> Bool {
deeplinkType = DeeplinkParser.shared.parseDeepLink(url)
return deeplinkType != nil
}
func checkDeepLink() {
guard let deeplinkType = deeplinkType else {
return
}
DeeplinkNavigator.shared.proceedToDeeplink(deeplinkType)
self.deeplinkType = nil
}
}
class DeeplinkNavigator: UIViewController {
static let shared = DeeplinkNavigator()
//private init() {}
var window: UIWindow?
private var alertController = UIAlertController()
func proceedToDeeplink(_ type: DeeplinkType) {
switch type {
case .observation(let tokenId, let projectId, let teamId, let issueId, let photoId):
presentView()
case .projects(.root):
displayAlert(title: "Project Root")
case .projects(.details(id: let id)):
displayAlert(title: "Project Details bla bla bla \(id)")
case .request(id: let id):
displayAlert(title: "Request Details \(id)")
/*case .project(id: let id):
displayAlert(title: "project details \(id)")*/
default: break
}
}
private func displayAlert(title: String) {
alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
let okButton = UIAlertAction(title: "Ok", style: .default, handler: nil)
alertController.addAction(okButton)
alertController.title = title
if let vc = UIApplication.shared.keyWindow?.rootViewController{
if vc.presentedViewController != nil {
alertController.dismiss(animated: false, completion: {
vc.present(self.alertController, animated: true, completion: nil)
})
} else {
vc.present(alertController, animated: true, completion: nil)
}
}
}
My personal experience has shown that this is not FE responsibility. One possible scenario is after receiving the URL to send it to the BackEnd and from that point you should receive
deeplink
or error for translation. Also, your app should navigate through screens withdeeplinks
.