Ich habe eine URL-Zeichenfolge ( NSString
) mit Leerzeichen und &
Zeichen. Wie codiere ich die gesamte Zeichenfolge (einschließlich des &
kaufmännischen Und-Zeichens und der Leerzeichen)?
Ich habe eine URL-Zeichenfolge ( NSString
) mit Leerzeichen und &
Zeichen. Wie codiere ich die gesamte Zeichenfolge (einschließlich des &
kaufmännischen Und-Zeichens und der Leerzeichen)?
Antworten:
Funktioniert leider stringByAddingPercentEscapesUsingEncoding
nicht immer 100%. Es codiert Nicht-URL-Zeichen, lässt jedoch die reservierten Zeichen (wie Schrägstrich /
und kaufmännisches Und &
) in Ruhe. Anscheinend ist dies ein Fehler , den Apple kennt, aber da er noch nicht behoben wurde, habe ich diese Kategorie verwendet, um eine Zeichenfolge per URL zu codieren:
@implementation NSString (NSString_Extended)
- (NSString *)urlencode {
NSMutableString *output = [NSMutableString string];
const unsigned char *source = (const unsigned char *)[self UTF8String];
int sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = source[i];
if (thisChar == ' '){
[output appendString:@"+"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
return output;
}
So verwendet:
NSString *urlEncodedString = [@"SOME_URL_GOES_HERE" urlencode];
// Or, with an already existing string:
NSString *someUrlString = @"someURL";
NSString *encodedUrlStr = [someUrlString urlencode];
Das funktioniert auch:
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Einige gute Lektüre zu diesem Thema:
Objective-c iPhone Prozent codieren eine Zeichenfolge?
Objective-C- und Swift-URL-Codierung
http://cybersam.com/programming/proper-url-percent-encoding-in-ios
https://devforums.apple.com/message/15674#15674
http://simonwoodside.com/weblog/2009/4/ 22 / how_to_really_url_encode /
Dies könnte hilfreich sein
NSString *sampleUrl = @"http://www.google.com/search.jsp?params=Java Developer";
NSString* encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
Für iOS 7+ wird empfohlen:
NSString* encodedUrl = [sampleUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Sie können den zulässigen Zeichensatz gemäß den Anforderungen der URL-Komponente auswählen.
-stringByAddingPercentEncodingWithAllowedCharacters:
stattdessen die empfohlene UTF-8-Codierung und die Codierung für eine bestimmte URL-Komponente oder Unterkomponente, da jede URL-Komponente oder Unterkomponente unterschiedliche Regeln für die Gültigkeit der Zeichen hat."
Seit Auswahl der Antwort wurden neue APIs hinzugefügt. Sie können jetzt NSURLUtilities verwenden. Verwenden Sie den entsprechenden Zeichensatz, da verschiedene Teile von URLs unterschiedliche Zeichen zulassen. Das folgende Beispiel codiert für die Aufnahme in die Abfragezeichenfolge:
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
Um '&' spezifisch zu konvertieren, müssen Sie es aus dem URL-Abfragesatz entfernen oder einen anderen Satz verwenden, da '&' in einer URL-Abfrage zulässig ist:
NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
[chars removeCharactersInRange:NSMakeRange('&', 1)]; // %26
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:chars];
NSMakeRange('&', 1)
funktioniert in Swift nicht, da Swift nicht zulässt, dass char ohne Hacks konvertiert wird. Um diese Lösung in Swift-Code zu verwenden, verwenden Sie removeCharactersInString("&")
anstelle von.removeCharactersInRange(...)
Swift 2.0 Beispiel (iOS 9 kompatibel)
extension String {
func stringByURLEncoding() -> String? {
let characters = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet
characters.removeCharactersInString("&")
guard let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(characters) else {
return nil
}
return encodedString
}
}
iOS 7 Update
NSString *encode = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *decode = [encode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Ich habe mich für die Verwendung des CFURLCreateStringByAddingPercentEscapes
Anrufs gemäß der akzeptierten Antwort entschieden. In der neuesten Version von XCode (und IOS) führte dies jedoch zu einem Fehler. Verwenden Sie stattdessen Folgendes:
NSString *apiKeyRaw = @"79b|7Qd.jW=])(fv|M&W0O|3CENnrbNh4}2E|-)J*BCjCMrWy%dSfGs#A6N38Fo~";
NSString *apiKey = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)apiKeyRaw, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
Versuchen Sie, eine stringByAddingPercentEncodingWithAllowedCharacters
Methode zu verwenden [NSCharacterSet URLUserAllowedCharacterSet]
, die alle Fälle abdeckt
Ziel c
NSString *value = @"Test / Test";
value = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLUserAllowedCharacterSet]];
schnell
var value = "Test / Test"
value.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLUserAllowedCharacterSet())
Ausgabe
Test%20%2F%20Test
Nachdem ich alle Antworten zu diesem Thema und die ( falsch ) akzeptierte gelesen habe , möchte ich meinen Beitrag hinzufügen.
WENN das Ziel iOS7 + ist und es 2017 sein sollte, da XCode es wirklich schwierig macht, Kompatibilität unter iOS8 zu liefern, ist der beste Weg, threadsicher, schnell und mit vollständiger UTF-8-Unterstützung, dies zu tun:
(Ziel C-Code)
@implementation NSString (NSString_urlencoding)
- (NSString *)urlencode {
static NSMutableCharacterSet *chars = nil;
static dispatch_once_t pred;
if (chars)
return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
// to be thread safe
dispatch_once(&pred, ^{
chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
[chars removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
});
return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
}
@end
Dadurch wird NSString erweitert, verbotene RFC-Zeichen ausgeschlossen, UTF-8-Zeichen unterstützt und Sie können Folgendes verwenden:
NSString *myusername = "I'm[evil]&want(to)break!!!$->àéìòù";
NSLog(@"Source: %@ -> Dest: %@", myusername, [myusername urlencode]);
Das wird auf Ihrer Debug-Konsole gedruckt:
Quelle: Ich bin [böse] und möchte brechen !!! $ -> àéìòù -> Ziel: I% 27m% 5Bevil% 5D% 26want% 28to% 29break% 21% 21% 21% 24-% 3E% C3 % A0% C3% A9% C3% AC% C3% B2% C3% B9
... beachten Sie auch die Verwendung von dispatch_once, um Mehrfachinitialisierungen in Multithread-Umgebungen zu vermeiden.
Hier ist ein produktionsbereiter flexibler Ansatz in Swift 5.x :
public extension CharacterSet {
static let urlQueryParameterAllowed = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "&?"))
static let urlQueryDenied = CharacterSet.urlQueryAllowed.inverted()
static let urlQueryKeyValueDenied = CharacterSet.urlQueryParameterAllowed.inverted()
static let urlPathDenied = CharacterSet.urlPathAllowed.inverted()
static let urlFragmentDenied = CharacterSet.urlFragmentAllowed.inverted()
static let urlHostDenied = CharacterSet.urlHostAllowed.inverted()
static let urlDenied = CharacterSet.urlQueryDenied
.union(.urlQueryKeyValueDenied)
.union(.urlPathDenied)
.union(.urlFragmentDenied)
.union(.urlHostDenied)
func inverted() -> CharacterSet {
var copy = self
copy.invert()
return copy
}
}
public extension String {
func urlEncoded(denying deniedCharacters: CharacterSet = .urlDenied) -> String? {
return addingPercentEncoding(withAllowedCharacters: deniedCharacters.inverted())
}
}
print("Hello, World!".urlEncoded()!)
print("You&Me?".urlEncoded()!)
print("#Blessed 100%".urlEncoded()!)
print("Pride and Prejudice".urlEncoded(denying: .uppercaseLetters)!)
Hello,%20World!
You%26Me%3F
%23Blessed%20100%25
%50ride and %50rejudice
Verwenden Sie NSURLComponents, um HTTP-GET-Parameter zu codieren:
var urlComponents = NSURLComponents(string: "https://www.google.de/maps/")!
urlComponents.queryItems = [
NSURLQueryItem(name: "q", value: String(51.500833)+","+String(-0.141944)),
NSURLQueryItem(name: "z", value: String(6))
]
urlComponents.URL // returns https://www.google.de/maps/?q=51.500833,-0.141944&z=6
http://www.ralfebert.de/snippets/ios/encoding-nsurl-get-parameters/
Dieser Code hat mir beim Codieren von Sonderzeichen geholfen
NSString* encPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
Schneller Code basierend auf der objc-Antwort von chown in diesem Thread.
extension String {
func urlEncode() -> String {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}
Probieren Sie in Swift 3 Folgendes aus:
let stringURL = "YOUR URL TO BE ENCODE";
let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(encodedURLString)
Da stringByAddingPercentEscapesUsingEncoding
nicht URL-Zeichen codiert werden, aber die reservierten Zeichen (wie !*'();:@&=+$,/?%#[]
) verbleiben, können Sie die URL wie folgt codieren:
let stringURL = "YOUR URL TO BE ENCODE";
let characterSetTobeAllowed = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: characterSetTobeAllowed) {
print(encodedURLString)
}
In den Versionshinweisen zu 10.11 lautet der Rat von Apple:
Wenn Sie eine gesamte URL-Zeichenfolge prozentual codieren müssen, können Sie diesen Code verwenden, um einen NSString zu codieren, der als URL gedacht ist (in urlStringToEncode):
NSString *percentEncodedURLString =
[[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
In meinem Fall, in dem die letzte Komponente arabische Buchstaben waren, habe ich Folgendes getan Swift 2.2
:
extension String {
func encodeUTF8() -> String? {
//If I can create an NSURL out of the string nothing is wrong with it
if let _ = NSURL(string: self) {
return self
}
//Get the last component from the string this will return subSequence
let optionalLastComponent = self.characters.split { $0 == "/" }.last
if let lastComponent = optionalLastComponent {
//Get the string from the sub sequence by mapping the characters to [String] then reduce the array to String
let lastComponentAsString = lastComponent.map { String($0) }.reduce("", combine: +)
//Get the range of the last component
if let rangeOfLastComponent = self.rangeOfString(lastComponentAsString) {
//Get the string without its last component
let stringWithoutLastComponent = self.substringToIndex(rangeOfLastComponent.startIndex)
//Encode the last component
if let lastComponentEncoded = lastComponentAsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()) {
//Finally append the original string (without its last component) to the encoded part (encoded last component)
let encodedString = stringWithoutLastComponent + lastComponentEncoded
//Return the string (original string/encoded string)
return encodedString
}
}
}
return nil;
}
}
Verwendung:
let stringURL = "http://xxx.dev.com/endpoint/nonLatinCharacters"
if let encodedStringURL = stringURL.encodeUTF8() {
if let url = NSURL(string: encodedStringURL) {
...
}
}
-(NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(
CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);
}
laut folgendem blog
So viele Antworten, die aber bei mir nicht funktionierten, also habe ich Folgendes versucht:
fun simpleServiceCall(for serviceUrl: String, appendToUrl: String) {
let urlString: String = serviceUrl + appendToUrl.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let finalUrl = URL(string: urlString)!
//continue to execute your service call...
}
Hoffentlich hilft es jemandem. Vielen Dank
Für einzelne www-formularcodierte Abfrageparameter habe ich eine Kategorie für NSString erstellt:
- (NSString*)WWWFormEncoded{
NSMutableCharacterSet *chars = NSCharacterSet.alphanumericCharacterSet.mutableCopy;
[chars addCharactersInString:@" "];
NSString* encodedString = [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
encodedString = [encodedString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
return encodedString;
}
// Dies ist ohne Test
NSMutableCharacterSet* set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[set addCharactersInString:@"-_.~"];
NSString *encode = [test stringByAddingPercentEncodingWithAllowedCharacters:set];
Ich hatte ein ähnliches Problem beim Übergeben komplexer Zeichenfolgen als POST-Parameter. Meine Zeichenfolgen können asiatische Zeichen, Leerzeichen, Anführungszeichen und alle Arten von Sonderzeichen enthalten. Die Lösung, die ich schließlich fand, bestand darin, meine Zeichenfolge in die passende Reihe von Unicodes zu konvertieren, z. B. "Hu0040Hu0020Hu03f5 ....", wobei [NSString stringWithFormat: @ "Hu% 04x", [ZeichenfolgenzeichenAtIndex: i]] verwendet wurde, um den Unicode von jedem zu erhalten Zeichen in der ursprünglichen Zeichenfolge. Das gleiche kann in Java gemacht werden.
Diese Zeichenfolge kann sicher als POST-Parameter übergeben werden.
Auf der Serverseite (PHP) ändere ich das gesamte "H" in "\" und übergebe die resultierende Zeichenfolge an json_decode. Der letzte Schritt besteht darin, einfache Anführungszeichen zu umgehen, bevor die Zeichenfolge in MySQL gespeichert wird.
Auf diese Weise kann ich jede UTF8-Zeichenfolge auf meinem Server speichern.
Dieser arbeitet für mich.
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
}
Ich habe die obige Funktion über diesen Link gefunden: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/
Sie können diese Funktion auch mit schneller Erweiterung verwenden. Bitte lassen Sie mich wissen, wenn es ein Problem gibt.