İ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.