21

I’m using CharacterSet.urlQueryAllowed to add percent-encoding to a String.

Some characters are not encoded the way I expected (i.e. & and ? are not changed). That being said, I had the idea to build a custom CharacterSet, ideally based on an existing one.

What’s the best approach to do so?

ixany
  • 4,551
  • 8
  • 37
  • 62
  • 1
    Look at `NSMutableCharacterSet` that should give you possibility to play with existing `NSCharacterSet`. – Larme Sep 11 '15 at 16:09

2 Answers2

44

The most typical way to create a new character set is using CharacterSet(charactersIn:), giving a String with all the characters of the set.

Adding some characters to an existing set can be achieved using:

let characterSet = NSMutableCharacterSet() //create an empty mutable set
characterSet.formUnionWithCharacterSet(NSCharacterSet.URLQueryAllowedCharacterSet())
characterSet.addCharactersInString("?&")

or in Swift 3+ simply:

var characterSet = CharacterSet.urlQueryAllowed
characterSet.insert(charactersIn: "?&")

For URL encoding, also note Objective-C and Swift URL encoding

Sulthan
  • 123,697
  • 21
  • 207
  • 260
  • Works perfectly fine, thank you! But when I try to add "ÄÖÜäöü" it hasn't any effect? – ixany Sep 11 '15 at 17:41
  • @mrtn.lxo You will have to add more context to your comment. How are you adding them? What are you doing later with the character set? – Sulthan Sep 11 '15 at 20:03
  • I simply used myCaracterSet.addCharactersInString("Ä") – ixany Sep 11 '15 at 20:24
7

You can try my method:

let password = "?+=!@#$%^&*()-_abcdABCD1234`~"

// Swift 2.3
extension NSCharacterSet {
    static var rfc3986Unreserved: NSCharacterSet {
        let mutable = NSMutableCharacterSet()
        mutable.formUnionWithCharacterSet(.alphanumericCharacterSet())
        mutable.addCharactersInString("-_.~")
        return mutable
    }
}

let encoding = password.stringByAddingPercentEncodingWithAllowedCharacters(.rfc3986Unreserved)

// Swift 3
extension CharacterSet {
    static var rfc3986Unreserved: CharacterSet {
        return CharacterSet(charactersIn: "-_.~").union(.alphanumerics)
    }
}

let encoding = password.addingPercentEncoding(withAllowedCharacters: .rfc3986Unreserved)

Print:
original -> ?+=!@#$%^&*()-_abcdABCD1234`~
encoding -> %3F%2B%3D%21%40%23%24%25%5E%26%2A%28%29-_abcdABCD1234%60~

rfc3986: https://www.rfc-editor.org/rfc/rfc3986 reference

Community
  • 1
  • 1
Arco
  • 357
  • 2
  • 10