55// Created by Ben Myers on 9/2/22.
66//
77
8- #if os(iOS)
9-
108import Firebase
119import Foundation
12- import FirebaseCore
13- import FirebaseDynamicLinks
1410
1511@available ( iOS 13 . 0 , * )
1612public struct EasyLink {
@@ -37,22 +33,33 @@ public struct EasyLink {
3733 public var longURL : LongURL ? {
3834 guard let urlPrefix = Self . urlPrefix else { fatalError ( " Set static value EasyLink.urlPrefix before creating EasyLink instance. " ) }
3935 guard let deepLinkURL = deepLinkURL else { return nil }
40- guard let builder = DynamicLinkComponents ( link: deepLinkURL, domainURIPrefix: urlPrefix) else { return nil }
41- builder. iOSParameters = DynamicLinkIOSParameters ( bundleID: Bundle . identifier)
36+ let urlParts = urlPrefix. split ( separator: " / " , maxSplits: 1 )
37+ var builder = URLComponents ( )
38+ builder. scheme = " https "
39+ guard let host = urlParts. first else { return nil }
40+ builder. host = String ( host)
41+ if let path = urlParts. last {
42+ builder. path = " / \( path) "
43+ }
44+ builder. queryItems = [
45+ . init( name: " link " , value: deepLinkURL. absoluteString) ,
46+ . init( name: " ibi " , value: Bundle . identifier) ,
47+ ]
4248 if let appStoreID = Self . appStoreID {
43- builder. iOSParameters ? . appStoreID = appStoreID
49+ builder. queryItems ? . append ( . init ( name : " isi " , value : appStoreID) )
4450 }
4551 if let minimumAppVersion = Self . minimumAppVersion {
46- builder. iOSParameters? . minimumAppVersion = minimumAppVersion
47- builder. iOSParameters? . fallbackURL = Self . backupURL
48- }
49- if let social = social {
50- builder. socialMetaTagParameters = social. builderParameters
52+ builder. queryItems? . append ( . init( name: " imv " , value: minimumAppVersion) )
5153 }
5254 if let backupURL = Self . backupURL {
53- let params = DynamicLinkOtherPlatformParameters ( )
54- params. fallbackUrl = backupURL
55- builder. otherPlatformParameters = params
55+ builder. queryItems? . append ( . init( name: " ofl " , value: backupURL. absoluteString) )
56+ }
57+ if let social = social {
58+ builder. queryItems? . append ( . init( name: " st " , value: social. title) )
59+ builder. queryItems? . append ( . init( name: " sd " , value: social. desc) )
60+ if let imageURL = social. imageURL {
61+ builder. queryItems? . append ( . init( name: " si " , value: imageURL. absoluteString) )
62+ }
5663 }
5764 return builder. url
5865 }
@@ -95,28 +102,60 @@ public struct EasyLink {
95102 if let query = query { self . query [ query. 0 ] = query. 1 }
96103 }
97104
105+ public init ? ( url: DeepLinkURL ) {
106+ guard
107+ let _scheme = url. scheme,
108+ let scheme = Scheme ( rawValue: _scheme) ,
109+ let host = url. host
110+ else {
111+ return nil
112+ }
113+ self . scheme = scheme
114+ self . host = host
115+ self . path = url. path
116+ self . query = url. queryDictionary ?? [ : ]
117+ }
118+
98119 // MARK: - Public Static Methods
99120
100121 public static func handle( _ url: UniversialURL ? , completion: @escaping ( EasyLink ? ) -> Void ) {
101- guard let url = url else {
122+ guard
123+ let url = url,
124+ let path = Bundle . main. path ( forResource: " GoogleService-Info " , ofType: " plist " ) ,
125+ let dictionary = NSDictionary ( contentsOfFile: path)
126+ else {
127+ completion ( nil )
128+ return
129+ }
130+ let dict = [
131+ " requestedLink " : url. absoluteString,
132+ " bundle_id " : Bundle . identifier,
133+ " sdk_version " : " 9.0.0 "
134+ ]
135+ guard
136+ let json: Data = try ? JSONSerialization . data ( withJSONObject: dict) ,
137+ let apiKey = dictionary [ " API_KEY " ] as? String ,
138+ let endpoint = URL ( string: " https://firebasedynamiclinks.googleapis.com/v1/reopenAttribution?key= \( apiKey) " )
139+ else {
102140 completion ( nil )
103141 return
104142 }
105- DynamicLinks . dynamicLinks ( ) . handleUniversalLink ( url) { ( dynamicLink: Firebase . DynamicLink ? , error: Error ? ) in
143+ var request = URLRequest ( url: endpoint)
144+ request. httpMethod = " POST "
145+ request. setValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
146+ request. httpBody = json
147+ URLSession . shared. dataTask ( with: request) { data, response, error in
106148 guard
107- error == nil ,
108- let dynamicLink = dynamicLink,
109- let url = dynamicLink. url,
110- let scheme = Scheme . get ( from: url. scheme ?? " " ) ,
111- let host = url. host,
112- let query = url. queryDictionary
149+ let data = data,
150+ let dict = try ? JSONSerialization . jsonObject ( with: data) as? [ String : Any ] ,
151+ let deepLink = dict [ " deepLink " ] as? String ,
152+ let url = URL ( string: deepLink)
113153 else {
114154 completion ( nil )
115155 return
116156 }
117- let link = EasyLink ( scheme: scheme, host: host, path: url. path, query: query)
118- completion ( link)
119- }
157+ completion ( EasyLink ( url: url) )
158+ } . resume ( )
120159 }
121160
122161 // MARK: - Public Methods
@@ -127,19 +166,41 @@ public struct EasyLink {
127166 - parameter completion: The completion handler.
128167 */
129168 public func shorten( mode: ShortenMode = . short, completion: @escaping ( URL ? ) -> Void ) {
130- guard let longURL = longURL else {
169+ guard
170+ let path = Bundle . main. path ( forResource: " GoogleService-Info " , ofType: " plist " ) ,
171+ let dictionary = NSDictionary ( contentsOfFile: path) ,
172+ let longURL = longURL
173+ else {
131174 completion ( nil )
132175 return
133176 }
134- let opt = DynamicLinkComponentsOptions ( )
135- opt. pathLength = mode. convert
136- DynamicLinkComponents . shortenURL ( longURL, options: opt) { url, warnings, error in
137- guard let url = url, error == nil else {
177+ let dict : [ String : Any ] = [
178+ " longDynamicLink " : longURL. absoluteString,
179+ " suffix " : [ " option " : mode. string]
180+ ]
181+ guard
182+ let apiKey = dictionary [ " API_KEY " ] as? String ,
183+ let endpoint = URL ( string: " https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key= \( apiKey) " ) ,
184+ let json = try ? JSONSerialization . data ( withJSONObject: dict)
185+ else {
186+ completion ( nil )
187+ return
188+ }
189+ var request = URLRequest ( url: endpoint)
190+ request. httpMethod = " POST "
191+ request. setValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
192+ request. httpBody = json
193+ URLSession . shared. dataTask ( with: request) { data, response, error in
194+ guard
195+ let data = data,
196+ let json = try ? JSONSerialization . jsonObject ( with: data) as? [ String : Any ] ,
197+ let link = json [ " shortLink " ] as? String
198+ else {
138199 completion ( nil )
139200 return
140201 }
141- completion ( url )
142- }
202+ completion ( URL ( string : link ) )
203+ } . resume ( )
143204 }
144205
145206 // MARK: - Enumerations
@@ -157,17 +218,18 @@ public struct EasyLink {
157218
158219 public enum ShortenMode {
159220 case secure, short
160- var convert : ShortDynamicLinkPathLength {
221+ var string : String {
161222 switch self {
162- case . secure: return . unguessable
163- case . short: return . short
223+ case . secure: return " UNGUESSABLE "
224+ case . short: return " SHORT "
164225 }
165226 }
166227 }
167228
168229 // MARK: - Nested Structs
169230
170231 public struct SocialMeta {
232+
171233 public var title : String
172234 public var desc : String
173235 public var imageURL : URL ?
@@ -177,14 +239,6 @@ public struct EasyLink {
177239 self . desc = desc
178240 self . imageURL = imageURL
179241 }
180-
181- internal var builderParameters : DynamicLinkSocialMetaTagParameters {
182- let p = DynamicLinkSocialMetaTagParameters ( )
183- p. title = title
184- p. descriptionText = desc
185- p. imageURL = imageURL
186- return p
187- }
188242 }
189243}
190244
@@ -203,5 +257,3 @@ fileprivate extension URL {
203257 return queryStrings
204258 }
205259}
206-
207- #endif
0 commit comments