如何使用包含swift中相同键的多个值的查询参数构建URL?

Abh*_*edi 39 nsurl ios swift swift2

我在我的iOS应用程序中使用AFNetworking,并且对于它所做的所有GET请求,我从基本URL构建url,然后使用NSDictionary键值对添加参数.

问题是我需要相同的键来表示不同的值.

以下是我需要最终URL的示例 -

http://example.com/.....&id=21212&id=21212&id=33232

NSDictionary中不可能在相同的键中具有不同的值.所以我尝试了NSSet但是没有用.

let productIDSet: Set = [prodIDArray]
let paramDict = NSMutableDictionary()
paramDict.setObject(productIDSet, forKey: "id")
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?

Dan*_*sko 79

你需要的只是NSURLComponents.基本思想是为你的id创建一堆查询项.这是您可以粘贴到游乐场的代码:

import UIKit
import XCPlayground

let queryItems = [NSURLQueryItem(name: "id", value: "2121"), NSURLQueryItem(name: "id", value: "3232")]
let urlComps = NSURLComponents(string: "www.apple.com/help")!
urlComps.queryItems = queryItems
let URL = urlComps.URL!
XCPlaygroundPage.currentPage.captureValue(URL.absoluteString, withIdentifier: "URL")
Run Code Online (Sandbox Code Playgroud)

你应该看到一个输出

www.apple.com/help?id=2121&id=3232


Bhu*_*att 27

它可以将QueryItem添加到现有URL.

extension URL {

    func appending(_ queryItem: String, value: String?) -> URL {

        guard var urlComponents = URLComponents(string: absoluteString) else { return absoluteURL }

        // Create array of existing query items
        var queryItems: [URLQueryItem] = urlComponents.queryItems ??  []

        // Create query item
        let queryItem = URLQueryItem(name: queryItem, value: value)

        // Append the new query item in the existing query items array
        queryItems.append(queryItem)

        // Append updated query items array in the url component object
        urlComponents.queryItems = queryItems

        // Returns the url from new url components
        return urlComponents.url!
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用

var url = URL(string: "https://www.example.com")!
let finalURL = url.appending("test", value: "123")
                  .appending("test2", value: nil)
Run Code Online (Sandbox Code Playgroud)


Ami*_*n3t 10

iOS 16、Swift 5.7+ 更新

有一种更短的方法可以执行此操作:

var url = URL(string: "http://google.com/search")
url?.append(queryItems: [URLQueryItem(name: "q", value: "soccer")])
print(url) // http://www.google.com/search?q=soccer
Run Code Online (Sandbox Code Playgroud)

函数式风格和不可变对象:

let url = URL(string: "http://google.com/search")?
            .appending(queryItems: [URLQueryItem(name: "q", value: "soccer")])

print(url) // http://www.google.com/search?q=soccer
Run Code Online (Sandbox Code Playgroud)


Kir*_*ela 8

func queryString(_ value: String, params: [String: String]) -> String? {    
    var components = URLComponents(string: value)
    components?.queryItems = params.map { element in URLQueryItem(name: element.key, value: element.value) }

    return components?.url?.absoluteString
}
Run Code Online (Sandbox Code Playgroud)


Cœu*_*œur 8

附加查询项的 URL 扩展,类似于 Bhuvan Bhatt 的想法,但具有不同的签名:

  • 它可以检测失败(通过返回nil而不是self),从而允许自定义处理 URL 不符合 RFC 3986 的情况,例如。
  • 它允许 nil 值,通过实际将任何查询项作为参数传递。
  • 为了性能,它允许一次传递多个查询项。
extension URL {
    /// Returns a new URL by adding the query items, or nil if the URL doesn't support it.
    /// URL must conform to RFC 3986.
    func appending(_ queryItems: [URLQueryItem]) -> URL? {
        guard var urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: true) else {
            // URL is not conforming to RFC 3986 (maybe it is only conforming to RFC 1808, RFC 1738, and RFC 2732)
            return nil
        }
        // append the query items to the existing ones
        urlComponents.queryItems = (urlComponents.queryItems ?? []) + queryItems

        // return the url from new url components
        return urlComponents.url
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

let url = URL(string: "https://example.com/...")!
let queryItems = [URLQueryItem(name: "id", value: nil),
                  URLQueryItem(name: "id", value: "22"),
                  URLQueryItem(name: "id", value: "33")]
let newUrl = url.appending(queryItems)!
print(newUrl)
Run Code Online (Sandbox Code Playgroud)

输出:

https://example.com/...?id&id=22&id=33