6

I have the following URL query:

encodedMessage=PD94bWwgdmVyNlPg%3D%3D&signature=kcig33sdAOAr%2FYYGf5r4HGN

How can I split the query to get the of encodedMessage and signature values?

1

3 Answers 3

16

The right way to achieve this is to work with URLComponents:

A structure designed to parse URLs based on RFC 3986 and to construct URLs from their constituent parts.

By getting the url components host string and query​Items array, as follows:

if let urlComponents = URLComponents(string: "http://mydummysite.com?encodedMessage=PD94bWwgdmVyNlPg%3D%3D&signature=kcig33sdAOAr%2FYYGf5r4HGN"), let host = urlComponents.host, let queryItems = urlComponents.queryItems {

    print(host) // mydummysite.com

    print(queryItems) // [encodedMessage=PD94bWwgdmVyNlPg==, signature=kcig33sdAOAr/YYGf5r4HGN]
}

queryItems array contains URLQuery​Item objects, which have name and value properties:

if let urlComponents = URLComponents(string: "http://mydummysite.com?encodedMessage=PD94bWwgdmVyNlPg%3D%3D&signature=kcig33sdAOAr%2FYYGf5r4HGN"),let queryItems = urlComponents.queryItems {

    // for example, we will get the first item name and value:
    let name = queryItems[0].name // encodedMessage
    let value = queryItems[0].value // PD94bWwgdmVyNlPg==
}

Also:

In case of you are getting the query without the full url, I'd suggest to do a pretty simple trick, by adding a dummy host as a prefix to your query string, as follows:

let myQuery = "encodedMessage=PD94bWwgdmVyNlPg%3D%3D&signature=kcig33sdAOAr%2FYYGf5r4HGN"
let myDummyUrlString = "http://stackoverflow.com?" + myQuery

if let urlComponents = URLComponents(string: myDummyUrlString),let queryItems = urlComponents.queryItems {
    // for example, we will get the first item name and value:
    let name = queryItems[0].name // encodedMessage
    let value = queryItems[0].value // PD94bWwgdmVyNlPg==
} else {
    print("invalid url")
}
Sign up to request clarification or add additional context in comments.

5 Comments

Nothing happens.. It doesnt return anything when i execute it
make sure that the used url is a valid one, what are showing in the question is just the query, it is not a full url.
It is kind of weird to me that you are getting a query without the full url. However, please check the edit.
This should be the accepted answer. The above will follow RFC 3986 and will correctly handle all the edge cases - like the initial '?' and so on in a complete URL.
Brilliant ! thanks for a detailed explanation with a perfect example.
5

You can get the key value pairs this way:

let str = "encodedMessage=PD94bWwgdmVyNlPg%3D%3D&signature=kcig33sdAOAr%2FYYGf5r4HGN"
let arr = str.components(separatedBy:"&")
var data = [String:Any]()
for row in arr {
    let pairs = row.components(separatedBy:"=")
    data[pairs[0]] = pairs[1]
}
let message = data["encodedMessage"]
let sig = data["signature"]

I am not sure if that's what you were looking for or not. If it is not, could you please clarify a bit further as to what you are looking for?

2 Comments

Yes it is exaclty what i want but i only need to get the value for encodedMessage and signature. How do i store them into a variable?
See the edit I made to get the values as variables. Though you could simply extract them from the dictionary as you want as well :)
0

This is the method I am using to break URLs with swift5

func breakURL(_ urlString: String) -> URLComponents? {
    // Create a URL from the given urlString
    guard let url = URL(string: urlString) else {
        print("Invalid URL")
        return nil
    }
    
    // Get the components of the URL
    if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
        return urlComponents
    } else {
        print("Failed to parse URL components")
        return nil
    }
}

Following is the way to use it.

if let urlComponents = breakURL("https://www.example.com/path/to/resource?param1=value1&param2=value2") {
    print("Scheme: \(urlComponents.scheme ?? "N/A")") // https
    print("Host: \(urlComponents.host ?? "N/A")") //www.example.com
    print("Path: \(urlComponents.path)") //path/to/resource
    print("Query: \(urlComponents.query ?? "N/A")") //param1=value1&param2=value2
}

if you want to break path or query you can get specific value with index number or just put loop on it ...

for queryItem in urlComponents.queryItems ?? [] {
    print("\(queryItem.name): \(queryItem.value ?? "N/A")") 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.