NSURL errors with caret ^ in string

Attempting to get data on the S&P500 (symbol: ^GSPC) from Yahoo Finance. In playgrounds and scripts, the presence of a caret (^) in the string passed to NSURL errors with “Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, sub code=0x0)”. Xcode 6b6 and b7.

Works fine with other ticker symbols (AAPL, MSFT, etc).

  • Erasing part of an image that overlaps with text from a UILabel
  • Xcode 6 / Beta 4: using bridging headers with framework targets is unsupported
  • How to Rotate Only One View Controller to Landscape Orientation in iOS Swift 3
  • Underlying type for Tuple in Swift
  • How to build a free version from a paid version without duplicating the Xcode 4 project?
  • How can one use XCTAssertNil with optional structs?
  • Any suggestions for how to get this working?

    let symbols:String = "^GSPC"
    let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
    
    var financeNSURL: NSURL = NSURL(string: financeURL) // ERROR (see above)
    let tickerNSData: NSData = NSData(contentsOfURL: financeNSURL)
    
    var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
    

    2 Solutions Collect From Internet About “NSURL errors with caret ^ in string”

    It’s crashing because Swift (at least in Xcode6-Beta7) doesn’t support returning nil from an object initializer. From the release notes:

    Swift does not support object initializers that fail by returning
    null. (16480364)

    Workaround: If there is a factory method, use it instead. Otherwise,
    capture the result in an optional. For example:

    let url: NSURL? = NSURL(string: "not a url")

    So, to avoid a crash, declare your financeNSURL as NSURL? (as in the example from the docs above), or use NSURL.URLWithString() instead of init(string:).

    However, the root of the problem is that you’re not encoding your URL parameters correctly.

    If you call stringByAddingPercentEncodingWithAllowedCharacters(...) on symbols it works:

    let symbols:String = "^GSPC".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
    
    let financeNSURL: NSURL? = NSURL(string: financeURL)
    if let url = financeNSURL {
        let tickerNSData: NSData = NSData(contentsOfURL: url)
    
        var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
    }
    

    Output:

    "^GSPC",1999.83,"-2.45","-0.12%"
    

    When creating a NSURLwith init method NSURLWithString: the parameter URLString must be a properly encoded URL string. Your’s is not. So, what is this a “properly encoded URL string”?

    The corresponding official documentation gives a few more hints where to read:

    URLString: The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808.”
    (links are mine).

    So basically, you need to separately encode each URL component from your source string component using the correct variant of the percent encoding algorithm. Then, compose all encoded string components to the final URL string.

    This can be tedious and is certainly error prone. Thus, since iOS 8 there is NSURLComponents (see docs here) which can aid you in this task.