当从json字符串构建url时,Alamofire返回无效的url

时间:2018-02-08 11:24:42

标签: json swift string url alamofire

Alamofire返回无效网址

我正在使用以下代码

形成搜索(urlStrForCustSearch)的URL字符串

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")
    }

控制台打印所需的网址

RightURL:

  

http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl?jsonText=[ { “电话”:1234567, “电子邮件”:空, “历史”:NULL, “CUSTOMER_ID”:NULL, “地址”:空}]&安培; funname = GET_MM_CUSTOMER_DTL_LST

但是在将urlStrForCustSearch字符串作为参数传递给Alamofire时,Alamofire会返回无效的网址

  

回应失败
  原因:FAILURE:invalidURL(“http://pos1domain.mobi/pos/SV_IOS.asmx/IosJasonToDatatbl?jsonText=[ {\”tel \“:1234567,\”email \“:null,\”history \“:null,\”customer_id \“:null,\”add​​r \“日期null}]&安培; funname = GET_MM_CUSTOMER_DTL_LST“)

我们可以看到在网址字符串中添加了'\' 任何人都可以帮我创建带有'\'字符串

的url字符串

如果需要任何输入,请告诉我。

2 个答案:

答案 0 :(得分:1)

反斜杠用于转义字符串中的特殊字符。

如果你想设法在Swift中分配一个包含双引号的字符串变量,如下所示:

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

Xcode会在这里显示错误,因为你的字符串实际上以&#34结束;他们说" (打开和关闭双引号。

要解决此问题,您需要转义应该是字符串一部分的双引号,如此

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

如果没有这个,那么iOS项目中的代码都会出现问题,并且您的API在读取字符串时会出现问题,这将无效。

在URL中使用特殊字符时,您可以使用Percent Encoding对字符串进行编码,将特殊字符替换为浏览器可以理解的格式。如果使用百分比编码转换完整的URL,则它不是非常易读:

  

的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

因此,通常最好只编码URL的查询字符串(GET params)。

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)
  

输出: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

更新 - 更好的解决方案

我完全忘记你正在使用Alamofire,我正在解决你提到的字符串问题。 Alamofire可以通过将参数传递给请求调用来自动处理编码。

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)

答案 1 :(得分:0)

感谢Scriptable,

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

上面的一行有所不同,它是" .get"方法

        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 {