swift2 我如何在Swift中构建一个URL,其中查询参数包含同一个键的多个值?

dluptydi  于 2022-11-06  发布在  Swift
关注(0)|答案(8)|浏览(193)

我在我的iOS应用程序中使用AFNetworking,对于它发出的所有GET请求,我从一个基本URL构建URL,然后使用NSDictionary键值对添加参数。
问题是,我需要相同的键为不同的值。
下面是一个我需要的finally URL的示例-
http://example.com/.....&id=21212&id=21212&id=33232
在NSDictionary中不可能在相同的键中有不同的值。所以我尝试了NSSet,但没有成功。

let productIDSet: Set = [prodIDArray]
let paramDict = NSMutableDictionary()
paramDict.setObject(productIDSet, forKey: "id")
py49o6xq

py49o6xq1#

你只需要URLComponents(或者Obj-C中的NSURL组件),基本思想是为你的id创建一系列查询项。下面是你可以粘贴到游戏中的代码:

import Foundation
import XCPlayground

let queryItems = [URLQueryItem(name: "id", value: "1"), URLQueryItem(name: "id", value: "2")]
var urlComps = URLComponents(string: "www.apple.com/help")!
urlComps.queryItems = queryItems
let result = urlComps.url!
print(result)

您应该会看到以下输出
www.apple.com/help?id=1&id=2

zhte4eai

zhte4eai2#

方法1

它可以将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!
    }
}

如何使用

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

方法2

在此方法中,URL将自动更新。

extension URL {

    mutating func appendQueryItem(name: String, value: String?) {

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

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

        // Create query item
        let queryItem = URLQueryItem(name: name, 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
        self = urlComponents.url!
    }
}

// How to use
var url = URL(string: "https://www.example.com")!
url.appendQueryItem(name: "name", value: "bhuvan")
jtjikinw

jtjikinw3#

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
}
ggazkfy8

ggazkfy84#

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

  • 它可以检测故障(通过返回nil而不是self),从而允许自定义处理URL不符合RFC3986的情况。
  • 它通过实际传递任何查询项作为参数来允许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
    }
}

用法

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)

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

jhdbpxl9

jhdbpxl95#

2019年

private func tellServerSomething(_ d: String, _ s: String) {

    var c = URLComponents(string: "https://you.com/info")
    c?.queryItems = [
        URLQueryItem(name: "description", value: d),
        URLQueryItem(name: "summary", value: s)
    ]
    guard let u = c?.url else { return print("url fail") }
    do {
        let r = try String(contentsOf: u)
        print("Server response \(r)")
    }
    catch { return print("comms fail") }
}

百分比编码和其他一切都得到了处理。

c7rzv4ha

c7rzv4ha6#

在具有多个参数的快速形成URL中

func rateConversionURL(with array: [String]) -> URL? {
            var components = URLComponents()
            components.scheme = "https"
            components.host = "example.com"
            components.path = "/hello/"
            components.queryItems = array.map { URLQueryItem(name: "value", value: $0)}

        return components.url
    }
qlvxas9a

qlvxas9a7#

适用于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
wz3gfoph

wz3gfoph8#

我想你只需要做这样的事情:

let params = ["id" : [1, 2, 3, 4], ...];

其将被编码为:......“”“”“”“”

相关问题