5

When I use Japanese language at my code

func getChannelDetails(useChannelIDParam: Bool) {
    var urlString: String!
    if !useChannelIDParam {
        urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet%2Cid&maxResults=50&order=viewCount&q=ポケモンGO&key=\(apikey)"
    }

I face the problem

fatal error: unexpectedly found nil while unwrapping an Optional value

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Nishad
  • 203
  • 1
  • 2
  • 9
  • Helpful comment: if you know people who are upvoting your material, please ask them to desist. – halfer Jul 13 '16 at 21:37
  • 1
    So Pokemon GO has overtaken Stack Overflow as well :-) – Nicolas Miari Jul 14 '16 at 01:50
  • You can refer to this http://stackoverflow.com/questions/32064754/how-to-use-stringbyaddingpercentencodingwithallowedcharacters-for-a-url-in-swi – John Lee Jul 14 '16 at 06:11
  • You can refer to this http://stackoverflow.com/questions/32064754/how-to-use-stringbyaddingpercentencodingwithallowedcharacters-for-a-url-in-swi – John Lee Jul 14 '16 at 06:12
  • Hi @Rob, happy to clarify: the question was brief, needed editing work, and acquired +4 at 2 hours old. No intention to offend at all, just stating the expectation that friends should not "help out" with upvotes in order to improve visibility. – halfer Jul 14 '16 at 07:50

1 Answers1

3

The Japanese characters (as would be any international characters) definitely are a problem. The characters allowed in URLs are quite limited. If they are present in the string, the failable URL initializer will return nil. These characters must be percent-escaped.

Nowadays, we'd use URLComponents to percent encode that URL. For example:

var components = URLComponents(string: "https://www.googleapis.com/youtube/v3/search")!
components.queryItems = [
    URLQueryItem(name: "part",       value: "snippet,id"),
    URLQueryItem(name: "maxResults", value: "50"),
    URLQueryItem(name: "order",      value: "viewCount"),
    URLQueryItem(name: "q",          value: "ポケモンGO"),
    URLQueryItem(name: "key",        value: apikey)
]
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B") // you need this if your query value might have + character, because URLComponents doesn't encode this like it should
let url = components.url!

For Swift 2 answer with manual percent encoding, see prior revision of this answer.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • `URL.init(string: "https://ja.wikipedia.org/wiki/カレーライス")` fails :-/ That's a perfect URL, Apple. – Jonny Nov 29 '17 at 13:33
  • 1
    Well, technically, it's not. Web browsers just do all of this percent encoding so gracefully behind the scenes, that it seems like it is valid, but if you use, for example, the Safari Web Inspector, you can see that the URL actually is [`https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AC%E3%83%BC%E3%83%A9%E3%82%A4%E3%82%B9`](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AC%E3%83%BC%E3%83%A9%E3%82%A4%E3%82%B9). – Rob Nov 29 '17 at 14:32
  • Good luck. 頑張ってください – Rob Nov 29 '17 at 17:17
  • You're right, of course. Fixed it like this:```guard let stringurlfixed = stringurl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { print("Failed adding percent encoding to \(stringurl)") return nil } ``` – Jonny Nov 30 '17 at 03:52
  • And I'll rephrase myself. That should be a perfect URL, whoever decides what is a perfect URL. – Jonny Nov 30 '17 at 04:27
  • Lol. BTW, that `.urlQueryAllowed` character set is going to characters go through unescaped, so I'd be a bit wary about that (the `+` and `&` are the typical edge cases). If you know your query won't include any special characters, you can get away with that `.urlQueryAllowed` technique. Otherwise, `URLComponents` does a little better, but still lets `+` through unescaped (which is why I handle that manually above). – Rob Nov 30 '17 at 04:53
  • 1
    Okay I'm getting arbitrary urls from an API, maybe I should demand the API guys to send over "proper" urls in the first time. – Jonny Nov 30 '17 at 05:05