Skip to content

Instantly share code, notes, and snippets.

@pwightman
Last active March 10, 2021 13:29
Show Gist options
  • Save pwightman/64c57076b89c5d7f8e8c to your computer and use it in GitHub Desktop.
Save pwightman/64c57076b89c5d7f8e8c to your computer and use it in GitHub Desktop.
How to escape a string of JSON/JavaScript in iOS.
extension String {
func javaScriptEscapedString() -> String {
// Because JSON is not a subset of JavaScript, the LINE_SEPARATOR and PARAGRAPH_SEPARATOR unicode
// characters embedded in (valid) JSON will cause the webview's JavaScript parser to error. So we
// must encode them first. See here: http://timelessrepo.com/json-isnt-a-javascript-subset
// Also here: http://media.giphy.com/media/wloGlwOXKijy8/giphy.gif
let str = self
.stringByReplacingOccurrencesOfString("\u{2028}", withString: "\\u2028")
.stringByReplacingOccurrencesOfString("\u{2029}", withString: "\\u2029")
// Because escaping JavaScript is a non-trivial task (https://github.com/johnezang/JSONKit/blob/master/JSONKit.m#L1423)
// we proceed to hax instead:
let data = try! NSJSONSerialization.dataWithJSONObject([str], options: [])
let encodedString = NSString(data: data, encoding: NSUTF8StringEncoding)!
return encodedString.substringWithRange(NSMakeRange(1, encodedString.length - 2))
}
}
@Tulakshana
Copy link

Hi,
I need to pass the contents of the file attached to a javascript function. Your escape function didn't work :(

Link to the file: https://drive.google.com/file/d/0B_Co3TU_E9CCQlpTSEdSbmF4cXc/view?usp=sharing

@psksvp
Copy link

psksvp commented Jan 24, 2020

Thanks pwightman. This is the version of the code in swift 5

extension String 
{
    func javaScriptEscapedString() -> String 
    {
        // Because JSON is not a subset of JavaScript, the LINE_SEPARATOR and PARAGRAPH_SEPARATOR unicode
        // characters embedded in (valid) JSON will cause the webview's JavaScript parser to error. So we
        // must encode them first. See here: http://timelessrepo.com/json-isnt-a-javascript-subset
        // Also here: http://media.giphy.com/media/wloGlwOXKijy8/giphy.gif
        let str = self.replacingOccurrences(of: "\u{2028}", with: "\\u2028")
                      .replacingOccurrences(of: "\u{2029}", with: "\\u2029")
        // Because escaping JavaScript is a non-trivial task (https://github.com/johnezang/JSONKit/blob/master/JSONKit.m#L1423)
        // we proceed to hax instead:
        let data = try! JSONSerialization.data(withJSONObject:[str], options: [])
        let encodedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)!
        return encodedString.substring(with: NSMakeRange(1, encodedString.length - 2))
    }
}

@makleso6
Copy link

makleso6 commented Mar 10, 2021

swift 5.1

extension String {
    var javaScriptEscapedString: String {
        // Because JSON is not a subset of JavaScript, the LINE_SEPARATOR and PARAGRAPH_SEPARATOR unicode
        // characters embedded in (valid) JSON will cause the webview's JavaScript parser to error. So we
        // must encode them first. See here: http://timelessrepo.com/json-isnt-a-javascript-subset
        // Also here: http://media.giphy.com/media/wloGlwOXKijy8/giphy.gif
        let str = self.replacingOccurrences(of: "\u{2028}", with: "\\u2028")
                      .replacingOccurrences(of: "\u{2029}", with: "\\u2029")
        // Because escaping JavaScript is a non-trivial task (https://github.com/johnezang/JSONKit/blob/master/JSONKit.m#L1423)
        // we proceed to hax instead:
        do {
            let encoder = JSONEncoder()
            let data = try encoder.encode([str])
            let encodedString = String(decoding: data, as: UTF8.self)
            return String(encodedString.dropLast().dropFirst())
        } catch {
            return self
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment