Ceci est ma URL
.
Le problème est que le champ address
n'est pas ajouté à urlpath
.
Est-ce que quelqu'un sait pourquoi c'est?
var address:string
address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address="+"\(address)")
Utilisez stringByAddingPercentEncodingWithAllowedCharacters
:
var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
Utilisez Déconseillé dans iOS 9 et OS X v10.11stringByAddingPercentEscapesUsingEncoding:
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var escapedAddress = address.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
Swift 3
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
S'il est possible que la valeur que vous ajoutez à votre URL puisse avoir des caractères réservés (comme défini dans la section 2 de RFC 3986 ), vous devrez peut-être affiner votre échappement à pourcentage. Notamment, alors que &
et +
sont des caractères valides dans une URL, ils ne sont pas valides dans une valeur de paramètre de requête d'URL (car &
est utilisé comme séparateur entre des paramètres de requête qui mettraient fin prématurément à votre valeur, et +
est traduit en espace). . Malheureusement, le pourcentage standard de fuite laisse ces délimiteurs sans échappatoire.
Ainsi, vous voudrez peut-être échapper en pourcentage tous les caractères qui ne figurent pas dans la liste des caractères non réservés de la RFC 3986:
Caractères autorisés dans un URI mais n'ayant pas de réservé but sont appelés sans réserve. Ceux-ci incluent les majuscules et les minuscules lettres, chiffres décimaux, trait d'union, point, trait de soulignement et tilde.
sans réserve = ALPHA/DIGIT/"-"/"."/"_"/"~"
Plus tard, dans la section 3.4, la RFC envisage en outre d'ajouter ?
et /
à la liste des caractères autorisés dans une requête:
Les caractères barre oblique ("/") et le point d'interrogation ("?") Peuvent représenter des données dans le composant de requête. Attention, certains plus vieux, erronés les implémentations peuvent ne pas gérer correctement ces données lorsqu'elles sont utilisées en tant que l'URI de base pour les références relatives (Section 5.1), apparemment car ils ne parviennent pas à distinguer les données de requête des données de chemin lorsque à la recherche de séparateurs hiérarchiques. Cependant, en tant que composants de requête sont souvent utilisés pour transporter des informations d'identification sous la forme de "clé = valeur" paires et une valeur fréquemment utilisée est une référence à Pour un autre URI, il est parfois préférable, pour des raisons de convivialité, d’éviter les pourcentages - encoder ces caractères.
De nos jours, vous utiliseriez généralement URLComponents
pour échapper à la valeur de la requête:
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var components = URLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
components.queryItems = [URLQueryItem(name: "address", value: address)]
let url = components.url!
En passant, bien que cela ne soit pas envisagé dans la RFC susmentionnée, le section 4.10.22.6, données de formulaire codées par URL } de la spécification HTML du W3C indique que les demandes application/x-www-form-urlencoded
doivent également remplacer les caractères espace par les caractères +
l'astérisque dans les caractères à ne pas échapper). Et, malheureusement, URLComponents
n'échappera pas correctement à ce problème. Apple vous conseille donc de le faire manuellement avant de récupérer la propriété url
de l'objet URLComponents
:
// configure `components` as shown above, and then:
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let url = components.url!
Pour le rendu de Swift 2, où je fais manuellement tout ce pour cent échapper moi-même, voir le révision précédente de cette réponse .
Swift 3:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
Swift 2.0
let needsLove = "string needin some URL love"
let safeURL = needsLove.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
URLQueryAllowedCharacterSet
ne doit pas être utilisé pour le codage d’URL des paramètres de requête, car ce jeu de caractères inclut &
, ?
, /
etc. qui servent de délimiteurs dans une requête d’URL, par exemple.
/?paramname=paramvalue¶mname=paramvalue
Ces caractères sont autorisés dans les requêtes d'URL dans leur ensemble, mais pas dans les valeurs de paramètre.
La RFC 3986 parle spécifiquement des caractères non réservés, qui sont différents des caractères autorisés:
2.3. Caractères non réservés
Caractères autorisés dans un URI mais n'ayant pas de caractère réservé
but sont appelés sans réserve. Ceux-ci incluent les majuscules et les minuscules lettres, chiffres décimaux, trait d'union, point, trait de soulignement et tilde.unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
En conséquence:
extension String {
var URLEncoded:String {
let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
let unreservedCharset = NSCharacterSet(charactersInString: unreservedChars)
let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(unreservedCharset)
return encodedString ?? self
}
}
Le code ci-dessus n'appelle pas alphanumericCharacterSet
en raison de la taille énorme du jeu de caractères qu'il renvoie (103806 caractères). Et compte tenu du nombre de caractères Unicode que alphanumericCharacterSet
permet, son utilisation à des fins de codage d'URL serait tout simplement erronée.
Usage:
let URLEncodedString = myString.URLEncoded
Swift 4.1
Créez un "jeu de caractères" en fonction de l'option souhaitée (urlQueryAllowed). Supprimez ensuite les caractères supplémentaires que vous ne voulez pas (+ &). Puis passez ce jeu de caractères à "addedPercentEncoding".
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&")
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
XCODE 8, Swift 3.0
De grokswift
La création d'URL à partir de chaînes est un terrain miné pour les bugs. Il suffit de manquer un seul/ou accidentellement URL encoder le? Dans une requête, votre appel d'API échouera et votre application n'aura pas de données à afficher (ou même se bloquerait si vous n'aviez pas anticipé cette possibilité). _ {Depuis iOS 8, il existe un meilleur moyen de créer des URL en utilisant NSURLComponents
et NSURLQueryItems
.
func createURLWithComponents() -> URL? {
var urlComponents = URLComponents()
urlComponents.scheme = "http"
urlComponents.Host = "maps.googleapis.com"
urlComponents.path = "/maps/api/geocode/json"
let addressQuery = URLQueryItem(name: "address", value: "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India")
urlComponents.queryItems = [addressQuery]
return urlComponents.url
}
Voici le code pour accéder à l'URL à l'aide de l'instruction guard
.
guard let url = createURLWithComponents() else {
print("invalid URL")
return nil
}
print(url)
Sortie:
http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India
En savoir plus: Création d'URL avec NSURLComponents et NSURLQueryItems
Mise à jour pour Swift 3:
var escapedAddress = address.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)
Dans Mac OS 10.9, Maverics et iOS 7 ont été introduits dans NSURLComponents
, qui gère l'encodage des différentes parties d'URL de manière très pratique.
La classe NSURLComponents est une classe conçue pour analyser les URL basé sur la RFC 3986 et de construire des URL à partir de leurs éléments constitutifs . Son comportement diffère légèrement de la classe NSURL, qui se conforme à anciennes RFC. Cependant, vous pouvez facilement obtenir un objet NSURL basé sur le contenu d'un objet composants URL ou vice versa.
let address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let components = NSURLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
// create a query item key=value
let queryItem = NSURLQueryItem(name: "address", value: address)
// add the query item to the URL, NSURLComponents takes care of adding the question mark.
components.queryItems = [queryItem]
// get the properly percent encoded string
let urlpath = components.string!
print(urlpath)
En complétant simplement la réponse de Desmond Hume pour étendre la classe String pour un fonction de codage valide RFC 3986 non réservée (nécessaire si vous codez des paramètres FORM de requête):
extension String {
var RFC3986UnreservedEncoded:String {
let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
let unreservedCharsSet: CharacterSet = CharacterSet(charactersIn: unreservedChars)
let encodedString: String = self.addingPercentEncoding(withAllowedCharacters: unreservedCharsSet)!
return encodedString
}
}
J'avais besoin de coder mes paramètres avec ISO-8859-1, donc la méthode addPercentEncoding () ne fonctionne pas pour moi .
extension String {
// Url percent encoding according to RFC3986 specifications
// https://tools.ietf.org/html/rfc3986#section-2.1
func urlPercentEncoded(withAllowedCharacters allowedCharacters:
CharacterSet, encoding: String.Encoding) -> String {
var returnStr = ""
// Compute each char seperatly
for char in self {
let charStr = String(char)
let charScalar = charStr.unicodeScalars[charStr.unicodeScalars.startIndex]
if allowedCharacters.contains(charScalar) == false,
let bytesOfChar = charStr.data(using: encoding) {
// Get the hexStr of every notAllowed-char-byte and put a % infront of it, append the result to the returnString
for byte in bytesOfChar {
returnStr += "%" + String(format: "%02hhX", byte as CVarArg)
}
} else {
returnStr += charStr
}
}
return returnStr
}
}
Usage:
"aouäöü!".urlPercentEncoded(withAllowedCharacters: .urlQueryAllowed,
encoding: .isoLatin1)
// Results in -> "aou%E4%F6%FC!"
Ajoutant à la réponse de Bryan Chen ci-dessus:
Au cas où quelqu'un d'autre obtiendrait quelque chose de similaire avec Alamofire:
erreur: Alamofire a été compilé avec optimisation - la progression peut se comporter étrangement; les variables peuvent ne pas être disponibles.
Ce n'est pas une erreur très descriptive. Je recevais cette erreur lors de la construction d'une URL pour les services Google Geo. J'ajoutais une adresse postale à la fin de l'URL SANS encoder d'abord l'adresse postale elle-même. J'ai pu résoudre le problème en utilisant la solution de Bryan Chen:
var streetAdress = "123 fake street, new york, ny"
var escapedStreetAddress = streetAddress.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = "\(self.baseUrl)&address=\(escapedAddress!)"
Cela l'a corrigé pour moi! Il n'a pas aimé que l'adresse avait des espaces et des virgules, etc.
J'espère que ceci aide quelqu'un d'autre!