Yanıtlar:
Ne yazık ki, stringByAddingPercentEscapesUsingEncoding
her zaman% 100 çalışmıyor. URL olmayan karakterleri kodlar, ancak ayrılmış karakterleri (eğik çizgi /
ve "ve" işareti gibi &
) tek başına bırakır . Görünüşe göre bu Apple'ın farkında olduğu bir hatadır , ancak henüz düzeltmedikleri için, bir dizeyi url kodlamak için bu kategoriyi kullanıyorum:
@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;
}
Bunun gibi kullanılır:
NSString *urlEncodedString = [@"SOME_URL_GOES_HERE" urlencode];
// Or, with an already existing string:
NSString *someUrlString = @"someURL";
NSString *encodedUrlStr = [someUrlString urlencode];
Bu da işe yarar:
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Konu hakkında iyi okumalar:
Objective-c iPhone yüzde bir dize kodlar?
Objective-C ve Swift URL kodlaması
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 /
Bu yardımcı olabilir
NSString *sampleUrl = @"http://www.google.com/search.jsp?params=Java Developer";
NSString* encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
İOS 7+ için önerilen yol:
NSString* encodedUrl = [sampleUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
URL bileşeninin gereksinimine göre izin verilen karakter kümesini seçebilirsiniz.
-stringByAddingPercentEncodingWithAllowedCharacters:
Her zaman önerilen UTF-8 kodlamasını kullanan ve her bir URL bileşeni veya alt bileşeni geçerli karakterler için farklı kurallara sahip olduğundan belirli bir URL bileşeni veya alt bileşeni için kodlayan bunun yerine kullanın ."
Yanıt seçildiğinden beri yeni API'ler eklendi; Artık NSURLUtilities'i kullanabilirsiniz. URL'lerin farklı bölümleri farklı karakterlere izin verdiğinden, geçerli karakter kümesini kullanın. Aşağıdaki örnek, sorgu dizesine dahil edilmek üzere kodlar:
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
'&' Kelimesini özel olarak dönüştürmek için URL sorgusunda URL sorgusu kümesinden kaldırmanız veya farklı bir küme kullanmanız gerekir.
NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
[chars removeCharactersInRange:NSMakeRange('&', 1)]; // %26
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:chars];
NSMakeRange('&', 1)
Swift'te çalışmaz, çünkü Swift, charların korsan olmadan int dönüşümüne izin vermez. Bu çözümü Swift kodunda kullanmak için removeCharactersInString("&")
,.removeCharactersInRange(...)
Swift 2.0 Örneği (iOS 9 Uyumlu)
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 güncellemesi
NSString *encode = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *decode = [encode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
CFURLCreateStringByAddingPercentEscapes
Aramayı kabul edilen cevapla verilen şekilde kullanmayı tercih ettim , ancak XCode'un (ve IOS) en yeni sürümünde, bir hatayla sonuçlandı, bu nedenle aşağıdaki kullanılır:
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));
stringByAddingPercentEncodingWithAllowedCharacters
Yöntemi kullanmaya çalışın [NSCharacterSet URLUserAllowedCharacterSet]
tüm vakaları kapsayacak
Hedef C
NSString *value = @"Test / Test";
value = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLUserAllowedCharacterSet]];
hızlı
var value = "Test / Test"
value.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLUserAllowedCharacterSet())
Çıktı
Test%20%2F%20Test
Bu konuyla ilgili tüm cevapları ve ( yanlış ) kabul edileni okuduktan sonra katkımı eklemek istiyorum.
EĞER hedef iOS7 + olduğu ve 2017 yılında bu XCode hızlı, iOS8, en iyi şekilde, iplik kasa altında uyumluluğu sağlamak için gerçekten zor kılan gerektiğinden, amd tam UTF-8 desteği Bunu yapmanın olacaktır:
(Amaç C kodu)
@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
Bu, NSString'i genişletir, RFC yasak karakterlerini hariç tutar, UTF-8 karakterlerini destekler ve aşağıdaki gibi şeyleri kullanmanıza izin verir:
NSString *myusername = "I'm[evil]&want(to)break!!!$->àéìòù";
NSLog(@"Source: %@ -> Dest: %@", myusername, [myusername urlencode]);
Hata ayıklama konsolunuza yazdırılacaktır:
Kaynak: Ben [şeytan] ve kırmak istiyorum !!! % A0% C3% A9% C3% AC% C3% B2% C3% B9
... ayrıca çok iş parçacıklı ortamlarda birden çok başlatmayı önlemek için dispatch_once kullanımını unutmayın.
İşte Swift 5.x'te üretime hazır esnek bir yaklaşım :
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
HTTP GET parametrelerini kodlamak için NSURLComponents kullanın:
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/
Bu kod özel karakterleri kodlamama yardımcı oldu
NSString* encPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
Bu konudaki chown cevabı cevabını temel alan swift kodu .
extension String {
func urlEncode() -> String {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}
In Swift 3 , aşağıda deneyin:
let stringURL = "YOUR URL TO BE ENCODE";
let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(encodedURLString)
stringByAddingPercentEscapesUsingEncoding
URL olmayan karakterleri kodladığı , ancak ayrılmış karakterleri bıraktığı (gibi !*'();:@&=+$,/?%#[]
), URL'yi aşağıdaki kod gibi kodlayabilirsiniz:
let stringURL = "YOUR URL TO BE ENCODE";
let characterSetTobeAllowed = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: characterSetTobeAllowed) {
print(encodedURLString)
}
Hızlı 3'te:
// exclude alpha and numeric == "full" encoding
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!;
// exclude hostname and symbols &,/ and etc
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!;
Apple'ın 10.11 sürüm notlarındaki tavsiyesi:
Bir URL dizesinin tamamını yüzde olarak kodlamanız gerekiyorsa, URL olması amaçlanan bir NSString kodlamasını (urlStringToEncode içinde) kodlamak için bu kodu kullanabilirsiniz:
NSString *percentEncodedURLString =
[[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
Son bileşenin Arap harfleri olduğu durumumda aşağıdakileri yaptım 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;
}
}
kullanımı:
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)
);
}
göre aşağıdaki blogda
Çok fazla cevap ama benim için çalışmadı, bu yüzden aşağıdakileri denedim:
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...
}
Umarım birine yardım eder. Teşekkürler
Bireysel www form kodlu sorgu parametreleri için NSString üzerinde bir kategori yaptım:
- (NSString*)WWWFormEncoded{
NSMutableCharacterSet *chars = NSCharacterSet.alphanumericCharacterSet.mutableCopy;
[chars addCharactersInString:@" "];
NSString* encodedString = [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
encodedString = [encodedString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
return encodedString;
}
POST parametresi olarak karmaşık dizeleri geçen benzer bir sorunla karşılaştım. Dizelerim Asya karakterleri, boşluklar, tırnak işaretleri ve her türlü özel karakter içerebilir. Sonunda bulduğum çözüm, her biri Unicode'u almak için [NSString stringWithFormat: @ "Hu% 04x", [string characterAtIndex: i]] kullanarak dizimi eşleşen unicodes serisine dönüştürmekti, örneğin "Hu0040Hu0020Hu03f5 ...." karakter. Aynı şey Java için de yapılabilir.
Bu dize bir POST parametresi olarak güvenli bir şekilde geçirilebilir.
Sunucu tarafında (PHP), tüm "H" "\" değiştirmek ve ortaya çıkan dize json_decode için geçirin. Son adım, dizeyi MySQL'e kaydetmeden önce tek tırnaklardan kaçmaktır.
Bu şekilde herhangi bir UTF8 dizesini sunucumda saklayabilirim.
Bu benim için çalışıyor.
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
}
Yukarıdaki işlevi bu bağlantıdan buldum: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/
Bu işlevi hızlı uzantı ile de kullanabilirsiniz. Herhangi bir sorun olursa lütfen bize bildirin.