Objective-C ve Swift URL kodlaması


137

Ben böyle bir şey var NSString:

http://www.

ama ben bunu dönüştürmek istiyorum:

http%3A%2F%2Fwww.

Bunu nasıl yapabilirim?


1
Gibi şifreli bir dize var ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~- aşağıdaki çözümlerin hiçbiri bu adres gibi görünüyor!
Mahendra Liya

Yanıtlar:


324

İstediğiniz karakterlerden kaçmak biraz daha fazla iş.

Örnek kod

iOS7 ve üstü:

NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);

NSLog çıkışı:

EscapedString: http% 3A% 2F% 2Fwww

Aşağıdakiler yararlı URL kodlama karakter kümeleridir:

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

Yukarıdakilerin tümünü birleştiren bir karakter seti oluşturma:

NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];

Temel Oluşturma64

Base64 karakter kümesi için:

NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];

Swift 3.0 için:

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)

Swift 2.x için:

var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())

Not: stringByAddingPercentEncodingWithAllowedCharacterskodlamaya ihtiyaç duyan UTF-8 karakterlerini de kodlar.

İOS7 öncesi
Core Foundation'ı ARC ile Core Foundation'ı kullanarak kullanın :

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));

ARC'siz Core Foundation'ı kullanma:

NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (CFStringRef)unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8);

Not: -stringByAddingPercentEscapesUsingEncodingdoğru kodlamayı üretmez, bu durumda aynı dizeyi döndüren hiçbir şeyi kodlamaz.

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding 14 karakter kodlar:

`#% ^ {} [] | \" <> artı yüzde kaçarken boşluk karakteri.

testString:

" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  

encodedString:

"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"  

Not: Bu karakter kümesinin ihtiyaçlarınızı karşılayıp karşılamadığını düşünün, gerekiyorsa değiştirin.

Kodlama gerektiren RFC 3986 karakterleri (kodlama öneki karakteri olduğu için% eklendi):

"# $ & '() * +, /:;!? = @ []%"

Bazı "kaydedilmemiş karakterler" ek olarak kodlanmıştır:

"\ n \ r \"% -. <> \ ^ _ `{|} ~"


1
Ayrıca NSString'in -stringByAddingPercentEscapesUsingEncodingyöntemini kullanabileceğinizi unutmayın .
Mike Weller

2
Ah evet, şimdi korkak stringByAddingPercentEscapesUsingEncodingdavranışı hatırlıyorum . Sadece '&' ve '=' veya bunun gibi saçma bir şey kodlar.
Mike Weller

2
RFC1738'e göre ek karakterleri de kodlamanız gerekir. Bu, OP'nin sorusunu yanıtlasa da, genel amaçlı bir URL kodlayıcı olarak yararlılığı sınırlıdır. Örneğin, Alman mermisi gibi alfasayısal olmayanlarla başa çıkmaz.
Alex Nauda

3
Bu işe yaramaz (iOS 7 bölümü için). Bu, &% 26'ya dönüştürülmez.
coolcool1994

1
İhtiyacınız olan karakter setini bir NSStringile oluşturun characterSetWithCharactersInString, tersini alın ve ile invertedSetkullanın stringByAddingPercentEncodingWithAllowedCharacters. Bir örnek için bu SO cevabına bakınız .
zaph

22

Buna URL kodlaması denir . Daha burada .

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
           (CFStringRef)self,
           NULL,
           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
           CFStringConvertNSStringEncodingToEncoding(encoding));
}

3
Yanıtladığınız bağlantılardan bazı içerikler cevaba eklenmişse, bu çok daha yararlı olacaktır.
chown

1
CFURLCreateStringByAddingPercentEscapes()kullanımdan kaldırıldı. [NSString stringByAddingPercentEncodingWithAllowedCharacters:]Bunun yerine kullanın .
Pang Pang

7

Bu benim çözümüm değil. Birisi stackoverflow yazdı ama nasıl unuttum.

Bir şekilde bu çözüm "iyi" çalışıyor. Aksan, çince karakterler ve hemen hemen her şeyi işler.

- (NSString *) URLEncodedString {
    NSMutableString * output = [NSMutableString string];
    const char * source = [self UTF8String];
    int sourceLen = strlen(source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = (const unsigned char)source[i];
        if (false && 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;
}

Birisi bana bu kodu kimin yazdığını söylese, gerçekten takdir edeceğim. Temel olarak, bu kodlanmış dizenin neden tam olarak istediği gibi çözüleceğine dair bazı açıklamaları var.

Çözümü biraz değiştirdim. Alanın + yerine% 20 ile temsil edilmesini seviyorum. Bu kadar.



[self UTF8String] nedir?
Yuchao Zhou

1
@yuchaozh bu, bir NSString kategorisine koyduğunuz bir işlevdir. Yani, self NSStirng'dir ve [self UTF8String], dizesini UTF8 biçiminde döndürdüğü varsayılır.
Kelsey

4
 NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );

NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];

1
encodedString ve url'yi serbest bırakın. Bu kod encode parametresiyle ilgilidir. "Parametre" yerine tüm adres geçiş dizesini kodlamak için.
Zahi

Bu benim için çalıştı ... hatta sorunları olan & karakteri kodladı.
Виктор Иванов


2

Hızlı iOS:

Sadece Bilgi İçin: Bunu kullandım:

extension String {

    func urlEncode() -> CFString {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }

}// end extension String

1
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                             NULL,
                             (CFStringRef)yourString, 
                             NULL, 
                             CFSTR("/:"), 
                             kCFStringEncodingUTF8);

strKendinizi serbest bırakmanız veya otomatik olarak serbest bırakmanız gerekir .


1

İşte kullandığım. @autoreleasepoolÖzelliği kullanmanız gerektiğini unutmayın; aksi takdirde program IDE'yi kilitleyebilir veya kilitleyebilir. Düzeltmeyi fark edene kadar IDE'mi üç kez yeniden başlatmam gerekiyordu. Bu kodun ARC uyumlu olduğu anlaşılıyor.

Bu soru birçok kez soruldu ve birçok cevap verildi, ancak ne yazık ki seçilenlerin (ve birkaçının önerdiği) yanlış.

İşte kullandığım test dizesi: This is my 123+ test & test2. Got it?!

Bunlar benim Objective C ++ sınıf yöntemleri:

static NSString * urlDecode(NSString *stringToDecode) {
    NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "];
    result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return result;
}

static NSString * urlEncode(NSString *stringToEncode) {
    @autoreleasepool {
        NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
                NULL,
                (CFStringRef)stringToEncode,
                NULL,
                (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                kCFStringEncodingUTF8
            ));
        result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"];
        return result;
    }
}

0

Google bunu Mac için Google Araç Kutusunda uygular . Bu, onların nasıl yaptıklarını zirveye çıkarmak için iyi bir yer. Başka bir seçenek de Araç Kutusu'nu dahil etmek ve uygulamalarını kullanmaktır.

Uygulamayı buradan kontrol edin . (Bu da tam olarak insanların burada ne yayınladığına bağlıdır).


0

Bunu çabucak yapıyorum.

extension String {
    func encodeURIComponent() -> String {
        return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    }

    func decodeURIComponent() -> String {
        return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
    }
}

-1

// NSString örnek yöntemini şu şekilde kullanın:

+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

Unutmayın, sadece parametre değeriniz için kodlama veya kod çözme yapmalısınız, istediğiniz tüm URL'leri değil.


2
stringByReplacingPercentEscapeusingencoding: sadece kaçar & ve = :-(
Sébastien Stormacq

1
Doğru, bu yüzden + gibi şeyler, gerektiğinde kodlanmaz. Yukarıdaki cevabı kullanmayın
John Ballinger

-8
int strLength = 0;
NSString *urlStr = @"http://www";
NSLog(@" urlStr : %@", urlStr );
NSMutableString *mutableUrlStr = [urlStr mutableCopy];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
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.