web-dev-qa-db-fra.com

Comment puis-je créer une URL avec des paramètres de requête contenant plusieurs valeurs pour la même clé dans Swift?

J'utilise AFNetworking dans mon application iOS et pour toutes les demandes GET qu'elle fait, je crée l'URL à partir d'une URL de base et ajoute des paramètres à l'aide de paires NSDictionary Key-Value.

Le problème est que j'ai besoin de la même clé pour différentes valeurs.

Voici un exemple de ce dont j'ai besoin de l'URL enfin pour ressembler -

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

Il n'est pas possible dans NSDictionary d'avoir des valeurs différentes dans les mêmes clés. J'ai donc essayé NSSet mais je n'ai pas fonctionné.

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

Tout ce dont vous avez besoin est NSURLComponents. L'idée de base est de créer un tas d'éléments de requête pour vos identifiants. Voici le code que vous pouvez coller dans une aire de jeux:

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

Vous devriez voir une sortie de

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

70
Daniel Galasko

Il peut ajouter QueryItem à votre URL existante.

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

Comment utiliser

var url = URL(string: "https://www.example.com")!
let finalURL = url.appending("test", value: "123")
                  .appending("test2", value: nil)
24
Bhuvan Bhatt
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
}
8
Kirit Vaghela

Une extension d'URL pour ajouter des éléments de requête, similaire à l'idée de Bhuvan Bhatt, mais avec une signature différente:

  • il peut détecter les échecs (en renvoyant nil au lieu de self), permettant ainsi une gestion personnalisée des cas où l'URL n'est pas conforme à la RFC 3986 par exemple.
  • il autorise des valeurs nulles, en passant réellement tous les éléments de requête comme paramètres.
  • pour les performances, il permet de passer plusieurs éléments de requête à la fois.
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
    }
}

Usage

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)

Sortie:

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

1
Cœur