İos9'da stringByAddingPercentEscapesUsingEncoding yerine?


112

İOS8 ve önceki sürümlerde şunları kullanabilirim:

NSString *str = ...; // some URL
NSString *result = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

iOS9'da stringByAddingPercentEscapesUsingEncodingşu şekilde değiştirildi stringByAddingPercentEncodingWithAllowedCharacters:

NSString *str = ...; // some URL
NSCharacterSet *set = ???; // where to find set for NSUTF8StringEncoding?
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

ve sorum şu: uygun şekilde değiştirilmesi için gerekli NSCharacterSet( NSUTF8StringEncoding) nerede bulunur stringByAddingPercentEscapesUsingEncoding?

Yanıtlar:


131

Kullanımdan kaldırma mesajı (vurgu benim) diyor:

Bunun yerine stringByAddingPercentEncodingWithAllowedCharacters (_ :) kullanın; bu, her zaman önerilen UTF-8 kodlamasını kullanır ve her URL bileşeni veya alt bileşeni hangi karakterlerin geçerli olduğuna ilişkin farklı kurallara sahip olduğundan, belirli bir URL bileşeni veya alt bileşeni için kodlama yapar .

Yani sadece yeterli bir NSCharacterSetargüman sağlamanız gerekir . Neyse ki, URL'ler için URLHostAllowedCharacterSetşu şekilde kullanabileceğiniz çok kullanışlı bir sınıf yöntemi vardır :

let encodedHost = unencodedHost.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())

Swift 3 için güncelleme - yöntem statik özellik haline gelir urlHostAllowed:

let encodedHost = unencodedHost.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

Bununla birlikte, şunun farkında olun:

Bu yöntem, bir URL dizesinin tamamını DEĞİL, bir URL bileşenini veya alt bileşen dizesini yüzde olarak kodlamayı amaçlamaktadır.


6
Ayrıca, NSURLComponentssizin için yüzde kodlamayı kaldırabilecek olanı kullanmanızı şiddetle tavsiye ederim.
Antonio Favata

1
URL dizesinin tamamı için ne kullanılacağına dair herhangi bir öneriniz var mı?
Beceri M2

1
@ SkillM2 Bence NSURLComponents(karşılık gelen her bileşen yüzde olarak kodlanmış NSCharacterSet) doğru yol.
Antonio Favata

2
Asla ve asla bir URL dizesinin tamamını kodlamaya çalışmamalısınız. Beklenmeyen hatalara ve bazı durumlarda güvenlik açıklarına neden olabilir. Bir URL'yi kodlamanın garantili tek doğru yolu, her seferinde tek parça yapmaktır.
dgatwood

Harika. Çok teşekkürler dostum!
Felipe

100

Objective-C için :

NSString *str = ...; // some URL
NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

NSUTF8StringEncoding için set nerede bulunur?

Yüzde kodlamaya izin veren altı URL bileşeni ve alt bileşeni için önceden tanımlanmış karakter kümeleri vardır. Bu karakter kümelerine geçilir -stringByAddingPercentEncodingWithAllowedCharacters:.

 // Predefined character sets for the six URL components and subcomponents which allow percent encoding. These character sets are passed to -stringByAddingPercentEncodingWithAllowedCharacters:.
@interface NSCharacterSet (NSURLUtilities)
+ (NSCharacterSet *)URLUserAllowedCharacterSet;
+ (NSCharacterSet *)URLPasswordAllowedCharacterSet;
+ (NSCharacterSet *)URLHostAllowedCharacterSet;
+ (NSCharacterSet *)URLPathAllowedCharacterSet;
+ (NSCharacterSet *)URLQueryAllowedCharacterSet;
+ (NSCharacterSet *)URLFragmentAllowedCharacterSet;
@end

Kullanımdan kaldırma mesajı (vurgu benim) diyor:

Bunun yerine stringByAddingPercentEncodingWithAllowedCharacters (_ :) kullanın, bu, her zaman önerilen UTF-8 kodlamasını kullanır ve her URL bileşeni veya alt bileşeni hangi karakterlerin geçerli olduğuna ilişkin farklı kurallara sahip olduğundan, belirli bir URL bileşeni veya alt bileşeni için kodlama yapar .

Bu nedenle, yalnızca yeterli bir NSCharacterSetargüman . Neyse ki, URL'ler için URLHostAllowedCharacterSetşu şekilde kullanabileceğiniz çok kullanışlı bir sınıf yöntemi vardır :

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 

Bununla birlikte, şunun farkında olun:

Bu yöntem, bir URL dizesinin tamamını DEĞİL, bir URL bileşenini veya alt bileşen dizesini yüzde olarak kodlamayı amaçlamaktadır.


4
Apple'ın hayatı kolaylaştırmasını seviyorum. Teşekkürler apple.
Duck

5
"Bu yöntem, bir URL bileşenini veya alt bileşen dizesini, tüm bir URL dizesini DEĞİL, yüzde olarak kodlamayı amaçlamaktadır." ?
GeneCode

4
URLHostAllowedCharacterSet "Desteklenmeyen URL" hatası veriyordu, URLFragmentAllowedCharacterSet kullandım ve düzgün çalışıyor.
anoop4real

1
bu + ile çalışmaz, kodlamaz ve spesifikasyon gereği sunucu tarafında boşluk ile değiştirilir.
Torge

45

URLHostAllowedCharacterSetolduğu ÇALIŞMA DEĞİL BENİM İÇİN. Onun URLFragmentAllowedCharacterSetyerine kullanıyorum.

HEDEF -C

NSCharacterSet *set = [NSCharacterSet URLFragmentAllowedCharacterSet];
NSString * encodedString = [@"url string" stringByAddingPercentEncodingWithAllowedCharacters:set];

SWIFT - 4

"url string".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

Aşağıdakiler yararlı (ters çevrilmiş) karakter kümeleridir:

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

Teşekkürler ve size de aynısı
Arpit B Parekh

Bu setlerin hiçbirinin içermediğini fark etmeye değer +. Bu nedenle, sorgu parametrelerinde iletilirse dizedeki artı işaretleri karışır - sunucu tarafında boşluk olarak kabul edilir.
Asmo Soinio

21

Objective-C

bu kod benim için çalışıyor:

urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];

4

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

2

Swift 3.0 için

urlHostAllowedCharacterSet'i kullanabilirsiniz .

/// Bir ana bilgisayar URL alt bileşeninde izin verilen karakter kümesini döndürür.

public static var urlHostAllowed: CharacterSet { get }

WebserviceCalls.getParamValueStringForURLFromDictionary(settingsDict as! Dictionary<String, AnyObject>).addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)

1

"Bu yöntem, bir URL bileşenini veya alt bileşen dizesini, tüm bir URL dizesini DEĞİL, yüzde olarak kodlamayı amaçlamaktadır." ? - GeneCode 1 Eylül 2016, saat 08: 30'da

Bu https://xpto.example.com/path/subpath, url'yi kodlamamanız gerektiği anlamına gelir, yalnızca ?.

Diyelim ki, çünkü aşağıdaki gibi durumlarda bunu yapmak için kullanım durumları var:

https://example.com?redirectme=xxxxx

xxxxxTam olarak kodlanmış bir URL nerede .


0

Kabul edilen cevaba ekleniyor. Bu notu dikkate alarak

Bu yöntem, bir URL dizesinin tamamını DEĞİL, bir URL bileşenini veya alt bileşen dizesini yüzde olarak kodlamayı amaçlamaktadır.

URL'nin tamamı kodlanmamalıdır:

let param = "=color:green|\(latitude),\(longitude)&\("zoom=13&size=\(width)x\(height)")&sensor=true&key=\(staticMapKey)".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) 
let url = "https://maps.google.com/maps/api/staticmap?markers" + param!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.