0

I want use URL Scheme for open apple maps from my app.

let url = URL(string: "http://maps.apple.com/?q=대한민국")

Using this URL for Test but it always nil.

here is my guess.

  1. URL must contain only english, umbers and some kind characters.
  2. url scheme can't initialize with URL.
  3. something to do on my project.

is there anybody know about this or how can solve this problem?

Martin Q
  • 7
  • 2

3 Answers3

3

The encodings in the various answers here are correct, but you should generally not use .addingPercentEncoding on an entire URL. As the parameter urlQueryAllowed notes, that encoding is only appropriate for the query section, not other sections, like the path, host, or authority.

For a hard-coded URL, you can just hand-encode it, but if you're building a URL programmatically, you should use URLComponents:

var components = URLComponents(string: "http://maps.apple.com/")!

components.queryItems = [
    URLQueryItem(name: "q", value: "대한민국")
]

// Or, if more convenient:
// components.query = "q=대한민국"

let url = components.url!

This ensures that each piece is encoded correctly, and avoids messy string-interpolation when building URLs programmatically.

As an example of where addingPercentEncoding goes wrong, consider an IDN domain such as Bücher.example:

let urlString = "https://Bücher.example/?q=대한민국"
print(urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed))

// https://B%C3%BCcher.example/?q=%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD

This in incorrect. IDN domains must be encoded in Punycode, not percent-encoding.

var components = URLComponents(string: "http://Bücher.example/")!
components.query = "q=대한민국"
print(components.url!)

// http://xn--bcher-kva.example/?q=%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Simply converting it can lead to other problems. I just solved the problem by converting to coordinate and using that, but I'm curious what developers prefer. Of course, I'll keep an eye on how I use the encoding. – Martin Q May 04 '23 at 13:41
0

You have to encode your path, since it contains characters not allowed in an URL:

let urlString = "http://maps.apple.com/?q=대한민국"
let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
let url = URL(string: encodedUrlString!)
print(url)

Output:

http://maps.apple.com/?q=%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD
Q.u.a.n.g L.
  • 1,564
  • 1
  • 12
  • 27
  • every developer handling non-latin character to url, use percent decoding? damn... it little bit annoying. – Martin Q May 05 '23 at 13:37
  • A URL is composed of only a limited number of characters and those are digits(0-9), letters(A-Z, a-z), and a few special characters("-", ".", "_", "~"). Even with the latin, url should encode as well. For ex:`http://www.example.com/?video=funny cat plays piano.`, browser will make it into `http://www.example.com/?video=funny%20cat%20plays%20piano.` . See ? – Q.u.a.n.g L. May 05 '23 at 16:48
  • Oh, so it also applies to whitespace? I see now, I'll make a note of that. – Martin Q May 06 '23 at 10:54
0

URLs were originally defined as ASCII only.

w3.org

When you try to convert a string that contains non-ascii characters into URL, it can't do that due to above reason. You need to somehow encode it with %xx (hexadecimal value of UTF-8) format.

Since the non-ascii characters are in the query string, you can do this in Swift by using this code:

urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
frenzy_funky
  • 416
  • 6
  • 6