Swift - encoder l'URL
si JE CODE une chaîne comme celle-ci:
var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
il n'échappe pas aux slashs /
.
j'ai cherché et trouvé ce code objectif C:
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8 );
y a-t-il un moyen plus simple d'encoder une URL et si ce n'est pas le cas, comment dois-je l'écrire dans Swift?
10 réponses
Swift 3
dans Swift 3 Il y a addingPercentEncoding
var originalString = "test/test"
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)
sortie:
test%2Ftest
Swift 1
En iOS 7 et il y a en haut stringByAddingPercentEncodingWithAllowedCharacters
var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")
sortie:
test%2Ftest
ce qui suit sont utiles (inversé) jeux de caractères:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
si vous voulez qu'un ensemble différent de caractères soit échappé créer un ensemble:
Exemple avec le caractère "=" ajouté:
var originalString = "test/test=42"
var customAllowedSet = NSCharacterSet(charactersInString:"=\"#%/<>?@\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")
sortie:
test%2Ftest%3D42
exemple pour vérifier les caractères ascii ne figurant pas dans l'ensemble:
func printCharactersInSet(set: NSCharacterSet) {
var characters = ""
let iSet = set.invertedSet
for i: UInt32 in 32..<127 {
let c = Character(UnicodeScalar(i))
if iSet.longCharacterIsMember(i) {
characters = characters + String(c)
}
}
print("characters not in set: \'\(characters)\'")
}
vous pouvez utiliser URLComponents pour éviter d'avoir à échapper manuellement pourcentage de votre chaîne de requête:
let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]
if let url = urlComponents.url {
print(url) // "https://www.google.com/search?q=Formula%20One"
}
extension URLComponents {
init(scheme: String, host: String, path: String, queryItems: [URLQueryItem]) {
self.init()
self.scheme = scheme
self.host = host
self.path = path
self.queryItems = queryItems
}
}
if let url = URLComponents(scheme: "https",
host: "www.google.com",
path: "/search",
queryItems: [URLQueryItem(name: "q", value: "Formula One")]).url {
print(url) // https://www.google.com/search?q=Formula%20One
}
Swift 3:
let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
//do something with escaped string
}
Swift 3:
let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"
1. encodingQuery:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
résultat:
"http://www.ihtc.cc?name=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
2. encodingURL:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
résultat:
"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
tout est pareil
var str = CFURLCreateStringByAddingPercentEscapes(
nil,
"test/test",
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
// test%2Ftest
Swift 4
pour encoder un paramètre dans L'URL je trouve en utilisant .alphanumerics
jeu de caractères l'option la plus facile:
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(encoded!)"
utilisant l'un des jeux de caractères standard pour le codage D'URL (comme URLQueryAllowedCharacterSet
ou URLHostAllowedCharacterSet
) ne fonctionnera pas, parce qu'ils n'excluent pas =
ou &
caractères.
Note qu'en utilisant .alphanumerics
il encodera certains caractères qui ne sont pas besoin d'être encodé (comme -
, .
, _
ou ~
-- voir 2.3. Caractères non réservés dans la RFC 3986). Je trouve l'utilisation de .alphanumerics
plus simple que la construction d'un jeu de caractères personnalisé et ne me dérange pas certains caractères supplémentaires à encoder. Si cela vous dérange, construisez un jeu de caractères personnalisé comme est décrit dans comment coder en pourcentage une chaîne D'URL , comme par exemple:
var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: "-._~") // as per RFC 3986
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: allowed)
let url = "http://www.example.com/?name=\(encoded!)"
Avertissement: Le encoded
paramètre est la force déballé. Pour une chaîne unicode invalide, il pourrait se planter. Voir Pourquoi est la valeur de retour de la chaîne.addingPercentEncoding () optional? . Au lieu de déballer la force encoded!
, vous pouvez utiliser encoded ?? ""
ou if let encoded = ...
.
Swift 4 (non testé - veuillez commenter si cela fonctionne ou non. Merci @sumizome pour la suggestion)
var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 3
let allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 2.2 (emprunt auprès de Zaph et correction des valeurs des clés et des paramètres des requêtes url)
var allowedQueryParamAndKey = NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)
exemple:
let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"
C'est un version abrégée de la réponse de Bryan Chen. Je suppose que urlQueryAllowed
permet les caractères de contrôle par lequel est très bien sauf s'ils font partie de la clé ou de la valeur dans votre chaîne de requête à quel point ils doivent être échappés.
Swift 4:
cela dépend des règles d'encodage suivies par votre serveur.
Apple offre cette méthode de classe, mais il ne rend pas compte du type de protocole RCF qu'il suit.
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
après cet utile outil vous devez garantir l'encodage de ces caractères pour vos paramètres:
- $ (signe Dollar) devient %24
- & (Ampersand) devient %26
- + (Plus) devient %2B
- , (virgule) devient %2C
- : (Colon) devient % 3A
- ; (Semi-Colon) devient %3B
- = (égal) devient % 3D
- ? (Point d'interrogation) devient %3F
- @ (Commercial A / At) devient % 40
en d'autres termes, en parlant D'encodage URL, vous devriez suite au RFC 1738 protocole .
et Swift ne couvrent pas l'encodage du + char par exemple , mais cela fonctionne bien avec ces trois @:? chars.
ainsi, pour encoder correctement chacun de vos paramètres , l'option .urlHostAllowed
n'est pas suffisante, vous devez ajouter aussi les caractères spéciaux comme par exemple:
encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")
Espérons que cela aide quelqu'un qui devenez fou de rechercher ces informations.
avait besoin de cela moi-même, donc j'ai écrit une extension de chaîne qui permet à la fois des chaînes URLEncoding, ainsi que le but final plus commun, la conversion d'un dictionnaire de paramètres en" GET "style URL Parameters:
extension String {
func URLEncodedString() -> String? {
var escapedString = self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
return escapedString
}
static func queryStringFromParameters(parameters: Dictionary<String,String>) -> String? {
if (parameters.count == 0)
{
return nil
}
var queryString : String? = nil
for (key, value) in parameters {
if let encodedKey = key.URLEncodedString() {
if let encodedValue = value.URLEncodedString() {
if queryString == nil
{
queryString = "?"
}
else
{
queryString! += "&"
}
queryString! += encodedKey + "=" + encodedValue
}
}
}
return queryString
}
}
Profitez-en!
celui-ci travaille pour moi.
func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
let unreserved = "*-._"
let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
allowed.addCharactersInString(unreserved)
if plusForSpace {
allowed.addCharactersInString(" ")
}
var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
if plusForSpace {
encoded = encoded?.stringByReplacingOccurrencesOfString(" ", withString: "+")
}
return encoded
}
j'ai trouvé la fonction ci-dessus à partir de ce lien: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string / .