如何在swift中将url.query转换为字典?

时间:2017-10-06 10:03:15

标签: ios swift nsdictionary nsurl

我有网址来自AppDelegate方法。

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

}

网址看起来www.wesite.com/shareplace.html?placeid=123

我的问题是它如何转换为字典以便于访问。

修改:我在某些网站上发现了一些代码,但它在Xcode 9中显示错误

 extension URL {
    var queryDictionary: [String: AnyObject]? {
        return URLComponents(url: self, resolvingAgainstBaseURL: false)?
            .queryItems?
            .reduce([:], combine: { (var result: [String: AnyObject], queryItem) -> [String: AnyObject] in
                if queryItem.value?.containsString(",") ?? false {
                    let array = queryItem.value?.componentsSeparatedByString(",")

                    result[queryItem.name] = array
                }
                else {
                    result[queryItem.name] = queryItem.value
                }

                return result
            })
    }
}
  

.reduce([:], combine: { (var result: [String: AnyObject], queryItem) -> [String: AnyObject] in(var result)参数可能没有' var'符

6 个答案:

答案 0 :(得分:12)

简单扩展程序

extension URL {
    var queryDictionary: [String: String]? {
        guard let query = self.query else { return nil}

        var queryStrings = [String: String]()
        for pair in query.components(separatedBy: "&") {

            let key = pair.components(separatedBy: "=")[0]

            let value = pair
                .components(separatedBy:"=")[1]
                .replacingOccurrences(of: "+", with: " ")
                .removingPercentEncoding ?? ""

            queryStrings[key] = value
        }
        return queryStrings
    }
}

<强> USAGE

let urlString = "http://www.youtube.com/video/4bL4FI1Gz6s?hl=it_IT&iv_logging_level=3&ad_flags=0&endscreen_module=http://s.ytimg.com/yt/swfbin/endscreen-vfl6o3XZn.swf&cid=241&cust_gender=1&avg_rating=4.82280613104"
let url = URL(string: urlString)
print(url!.queryDictionary ?? "NONE")

答案 1 :(得分:4)

这里有一个使用swift reduce函数的例子。这将转换为&#39; key1 = value1&amp; key2 = value2&amp; key3 = value3&#39;进入字典。

let params = queryString.components(separatedBy: "&").map({
    $0.components(separatedBy: "=")
}).reduce(into: [String:String]()) { dict, pair in
    if pair.count == 2 {
        dict[pair[0]] = pair[1]
    }
}

答案 2 :(得分:2)

详细信息

  • 雨燕5
  • 版本10.2(10E125)

解决方案

extension Array where Element == URLQueryItem {
    func toDictionary() -> [String: Any] {
        var dictionary = [String: Any]()
        for queryItem in self {
            guard let value = queryItem.value else { continue }
            if queryItem.name.contains("[]") {
                let key = queryItem.name.replacingOccurrences(of: "[]", with: "")
                let array = dictionary[key] as? [String] ?? []
                dictionary[key] = array + [value]
            } else {
                dictionary[queryItem.name] = value
            }
        }
        return dictionary
    }
}

extension String {
    func getURLQueryItems() -> [URLQueryItem]? {
        guard let urlString = self.removingPercentEncoding, let url = URL(string: urlString) else { return nil }
        if let querItems = url.getQueryItems() { return querItems }
        var urlComponents = URLComponents()
        urlComponents.query = urlString
        return urlComponents.queryItems
    }
}

extension URL {
    func getQueryItems() -> [URLQueryItem]? {
        let urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: false)
        return urlComponents?.queryItems
    }
}

用法

url.getQueryItems()
url.getQueryItems()?.toDictionary()

urlString.getURLQueryItems()
urlString.getURLQueryItems()?.toDictionary()

urlQueryString?.getURLQueryItems()
urlQueryString?.getURLQueryItems()?.toDictionary()

完整样本

var urlString = "https://example.com/l57?condition%5B%5D=31&brand%5B%5D=289&brand%5B%5D=291&brand%5B%5D=32&year%5B%5D=23259&year%5B%5D=23757&ships_from_region%5B%5D=23684&ships_from_region%5B%5D=23683"
let url = URL(string: urlString)!
var urlQueryString = url.query

print("URL:\n\(urlString)")
print("URL query string:\n\(String(describing: urlQueryString))\n")

print("get [URLQueryItem] from URL:\n\(String(describing: url.getQueryItems()))\n")
print("get [String: Any] from URL:\n\(String(describing: url.getQueryItems()?.toDictionary()))\n")

print("get [URLQueryItem] from url string (absoluteString):\n\(String(describing: urlString.getURLQueryItems()))\n")
print("get [String:Any] from url string (absoluteString):\n\(String(describing: urlString.getURLQueryItems()?.toDictionary()))\n")

print("get [URLQueryItem] from url string (only query):\n\(String(describing: urlQueryString?.getURLQueryItems()))\n")
print("get [String:Any] from url string (only query):\n\(String(describing: urlQueryString?.getURLQueryItems()?.toDictionary()))\n")

完整的样本输出

//URL:
//https://example.com/l57?condition%5B%5D=31&brand%5B%5D=289&brand%5B%5D=291&brand%5B%5D=32&year%5B%5D=23259&year%5B%5D=23757&ships_from_region%5B%5D=23684&ships_from_region%5B%5D=23683
//URL query string:
//Optional("condition%5B%5D=31&brand%5B%5D=289&brand%5B%5D=291&brand%5B%5D=32&year%5B%5D=23259&year%5B%5D=23757&ships_from_region%5B%5D=23684&ships_from_region%5B%5D=23683")
//
//get [URLQueryItem] from URL:
//Optional([condition[]=31, brand[]=289, brand[]=291, brand[]=32, year[]=23259, year[]=23757, ships_from_region[]=23684, ships_from_region[]=23683])
//
//get [String: Any] from URL:
//Optional(["ships_from_region": ["23684", "23683"], "condition": ["31"], "year": ["23259", "23757"], "brand": ["289", "291", "32"]])
//
//get [URLQueryItem] from url string (absoluteString):
//Optional([condition[]=31, brand[]=289, brand[]=291, brand[]=32, year[]=23259, year[]=23757, ships_from_region[]=23684, ships_from_region[]=23683])
//
//get [String:Any] from url string (absoluteString):
//Optional(["year": ["23259", "23757"], "ships_from_region": ["23684", "23683"], "brand": ["289", "291", "32"], "condition": ["31"]])
//
//get [URLQueryItem] from url string (only query):
//Optional([condition[]=31, brand[]=289, brand[]=291, brand[]=32, year[]=23259, year[]=23757, ships_from_region[]=23684, ships_from_region[]=23683])
//
//get [String:Any] from url string (only query):
//Optional(["year": ["23259", "23757"], "ships_from_region": ["23684", "23683"], "brand": ["289", "291", "32"], "condition": ["31"]])
//

答案 3 :(得分:0)

另外尝试一下:

extension URL {
    var queryDictionary: [String: AnyObject]? {
        return URLComponents(url: self, resolvingAgainstBaseURL: false)?
            .queryItems?
            .reduce([:], combine: { (lastResult: [String: AnyObject], queryItem) -> [String: AnyObject] in
                var result = lastResult
                if queryItem.value?.containsString(",") ?? false {
                    let array = queryItem.value?.componentsSeparatedByString(",")

                    result[queryItem.name] = array
                }
                else {
                    result[queryItem.name] = queryItem.value
                }

                return result
            })
    }
}

答案 4 :(得分:0)

guard let urlQuery =  URL(string: "https://en.wikipedia.org/wiki/Query_string?title=Main_page&action=raw")?.query else {
     return
}

let queryArray = urlQuery.characters.split { $0 == "&"}.map(String.init)
var parametersDict: [String: String] = [:]
for queryParameter in queryArray {
    // split the queryParam into key / value
    let keyValueArray = queryParameter.characters.split{$0 == "="}.map(String.init)
    let key = keyValueArray.first
    let value = keyValueArray.last
    parametersDict.updateValue(value!, forKey: key!)
}

print(parametersDict)
// prints ["action": "raw", "title": "Main_page"]

答案 5 :(得分:0)

使用.first(where:)

        guard let query = components.queryItems else {
            return
        }
        
        guard let accessToken = query.first(where: { $0.name == "access_token" }) else {
            return
        }