D Madhu Kiran Raju
D Madhu Kiran Raju

Reputation: 55

Alamofire returns invalid url, when building an url from json string

Alamofire returns a invalid URL

I am forming an URL string for Searching (urlStrForCustSearch) using the following code

and URL_CUSTOMER_SEARCH = "http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl":

    let customerJson = [[
                        "customer_id":nil,
                        "tel":1234567,
                        "email":nil,
                        "addr":nil,
                        "history":nil]]

    do{
        let JSONData = try JSONSerialization.data(withJSONObject: customerJson, options: [])
        let JSONText = String(data: JSONData,
                              encoding: .utf8)!

        let urlStrForCustSearch = URL_CUSTOMER_SEARCH+"?jsonText=\(JSONText)&funname=GET_MM_CUSTOMER_DTL_LST"
        print(urlStrForCustSearch)

        Alamofire.request(urlStrForCustSearch, method: .post, parameters: [:], encoding: URLEncoding.default, headers: [:]).responseString { response in
            if response.result.isSuccess {
                print("Response is success")

            }else{
                print("Response Failed")
                print("Reason : \(response)")
            }
        }

    }catch{
        print("Cannot parse the dictionary")
    }

Console prints desired url

RightURL:

http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl?jsonText=[{"tel":1234567,"email":null,"history":null,"customer_id":null,"addr":null}]&funname=GET_MM_CUSTOMER_DTL_LST

but on passing the urlStrForCustSearch string to Alamofire as parameter, Alamofire return invalid URL

Response Failed
Reason : FAILURE: invalidURL("http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl?jsonText=[{\"tel\":1234567,\"email\":null,\"history\":null,\"customer_id\":null,\"addr\":null}]&funname=GET_MM_CUSTOMER_DTL_LST")

As we can see that '\' is added inside the url string
Can any one help me in creating the url string with out '\' string

Please let me know if any input needed.

Upvotes: 1

Views: 2276

Answers (2)

Scriptable
Scriptable

Reputation: 19758

Backslashes are used to escape special characters in a string.

If you imagine trying to assign a string variable in Swift which contained double quotes like so:

let str = "They said "hi" when I walked in"

Xcode would show an error here as your string actually ends at "They said " (opened and closed double quotes.

To address the issue you need to escape the double quotes that should be part of the string, like so

let str = "They said \"hi\" when I walked in"

Without this both your code in the iOS project would have issues and your API would have issues reading the string, it would not be valid.

When using special characters in a URL, you can encode the string with Percent Encoding which replaces special characters into a format that browsers can understand. If you convert the full url using percent encoding it is not very readable:

http%3A%2F%2Fpos1domain%2Emobi%2Fpos%2FSV%5FIOS%2Easmx%2FIosJasonToDatatbl%3FjsonText%3D%5B%7B%22tel%22%3A1234567%2C%22email%22%3Anull%2C%22history%22%3Anull%2C%22customer%5Fid%22%3Anull%2C%22addr%22%3Anull%7D%5D%26funname%3DGET%5FMM%5FCUSTOMER%5FDTL%5FLST

So it is usually best to just encode the query string (GET params) of the URL.

let baseUrlString = "http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl"
let queryString = "?jsonText=[{\"tel\":1234567,\"email\":null,\"history\":null,\"customer_id\":null,\"addr\":null}]&funname=GET_MM_CUSTOMER_DTL_LST".addingPercentEncoding(withAllowedCharacters: .alphanumerics)!

let urlString = baseUrlString + queryString
print(urlString)

Output: http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl%3FjsonText%3D%5B%7B%22tel%22%3A1234567%2C%22email%22%3Anull%2C%22history%22%3Anull%2C%22customer%5Fid%22%3Anull%2C%22addr%22%3Anull%7D%5D%26funname%3DGET%5FMM%5FCUSTOMER%5FDTL%5FLST

UPDATE - Better Solution

I completely forgot that you are using Alamofire, I was addressing the string issue you mentioned. Alamofire can deal with the encoding for you automatically by passing the parameters into the request call.

let parameters: Parameters = ["foo": "bar"]

// All three of these calls are equivalent
Alamofire.request("https://httpbin.org/get", parameters: parameters) // encoding defaults to `URLEncoding.default`
Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding.default)

Upvotes: 3

D Madhu Kiran Raju
D Madhu Kiran Raju

Reputation: 55

Thanks Scriptable,

        let queryString = JSONText.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!

the above line made the difference and it was ".get" method.

        let JSONData = try JSONSerialization.data(withJSONObject: customerJson, options: [])
        let JSONText = String(data: JSONData,
                              encoding: .utf8)!
        //Without this line we will get invalid url from alamofire
        let queryString = JSONText.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!

        let urlStringForCust = URL_CUSTOMER_SEARCH+"?jsonText=\(queryString)&funname=GET_MM_CUSTOMER_DTL_LST"
        print(urlStringForCust)

        Alamofire.request(urlStringForCust, method: .get, parameters: [:], encoding: URLEncoding.default, headers: [:]).responseString { response in
            if response.result.isSuccess {

Upvotes: 0

Related Questions