Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - encode URL

If I encode a string like this:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) 

it doesn't escape the slashes /.

I've searched and found this Objective C code:

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

Is there an easier way to encode an URL and if not, how do I write this in Swift?

like image 471
MegaCookie Avatar asked Jul 03 '14 10:07

MegaCookie


2 Answers

Swift 3

In Swift 3 there is addingPercentEncoding

let originalString = "test/test" let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) print(escapedString!) 

Output:

test%2Ftest

Swift 1

In iOS 7 and above there is stringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test" var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet()) println("escapedString: \(escapedString)") 

Output:

test%2Ftest

The following are useful (inverted) character sets:

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

If you want a different set of characters to be escaped create a set:
Example with added "=" character:

var originalString = "test/test=42" var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet) println("escapedString: \(escapedString)") 

Output:

test%2Ftest%3D42

Example to verify ascii characters not in the set:

func printCharactersInSet(set: NSCharacterSet) {     var characters = ""     let iSet = set.invertedSet     for i: UInt32 in 32..<127 {         let c = Character(UnicodeScalar(i))         if iSet.longCharacterIsMember(i) {             characters = characters + String(c)         }     }     print("characters not in set: \'\(characters)\'") } 
like image 108
zaph Avatar answered Sep 23 '22 19:09

zaph


You can use URLComponents to avoid having to manually percent encode your query string:

let scheme = "https" let host = "www.google.com" let path = "/search" let queryItem = URLQueryItem(name: "q", value: "Formula One")   var urlComponents = URLComponents() urlComponents.scheme = scheme urlComponents.host = host urlComponents.path = path urlComponents.queryItems = [queryItem]  if let url = urlComponents.url {     print(url)   // "https://www.google.com/search?q=Formula%20One" } 

extension URLComponents {     init(scheme: String = "https",          host: String = "www.google.com",          path: String = "/search",          queryItems: [URLQueryItem]) {         self.init()         self.scheme = scheme         self.host = host         self.path = path         self.queryItems = queryItems     } } 

let query = "Formula One" if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {     print(url)  // https://www.google.com/search?q=Formula%20One } 
like image 34
Leo Dabus Avatar answered Sep 24 '22 19:09

Leo Dabus