I'm using the Swift framework ASWebAuthenticationSession
in order to add authentication via browser for my application. After processing the credentials, the authentication provider send URL with special prefix which gets intercepted by my app. The URL has the following format :
mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
Now I wish to create a method that extract param's value. So I use URLComponents. I need to replace the ':' with '?', but although it convert the percent encoding chars back into ascii, it seems like the url cannot be parsed properly
(lldb) po URLComponents(string: "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")
▿ Optional<URLComponents>
▿ some : mycallback%3Fun%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
- path : "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="
(lldb) po URLComponents(string: "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")?.queryItems
nil
Another approach is use the intercepted URL as-is and get scheme path but how can i query params out of this structure ?
(lldb) po URLComponents(string: "mycallback:un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")
▿ Optional<URLComponents>
▿ some : mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
- scheme : "mycallback"
- path : "un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="
only if I manually convert the percent encodingp symbols to their ascii representation in advance, than the query seems fine :
(lldb) po URLComponents(string: "mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=")
▿ Optional<URLComponents>
▿ some : mycallback?un=test&as=1&token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
- path : "mycallback"
▿ queryItems : 3 elements
▿ 0 : un=test
- name : "un"
▿ value : Optional<String>
- some : "test"
▿ 1 : as=1
- name : "as"
▿ value : Optional<String>
- some : "1"
▿ 2 : token=eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
- name : "token"
▿ value : Optional<String>
- some : "eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0="
So my question is how to convert all percent encoding symbols (formatted with '%' followed by hex value) to their ascii representation ?
CodePudding user response:
You have an URL where the scheme is mycallback
and the path is actually a query. You just need to parse and adjust it.
func decodedParameters(string: String) -> [URLQueryItem]? {
var c = URLComponents()
c.query = URLComponents(string: data)?.path
return c.queryItems
}
if let parameters = decodedParameters(string: data),
let token = parameters.first(where: { $0.name == "token"})?.value {
print(token)
}
// eyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
If you're doing this a lot, you may prefer to create an extension to make it a little easier:
extension Array where Element == URLQueryItem {
subscript(_ key: String) -> String? {
first(where: { $0.name == key})?.value
}
}
let parameters = decodedParameters(string: data) ?? []
if let token = parameters["token"] {
print(token)
}