# URL

[frameworks](..) ⟩ [Foundation]() ⟩ URL

{% tabs %}
{% tab title="💾 程式" %}
```swift
var parts = URLComponents()
parts.scheme = "https"
parts.host = "example.com"
parts.path = "/v1/player"
parts.queryItems = [
    URLQueryItem(name: "name", value: "艾佛森")
]
// ⭐️ URLQueryItem 會自動做 URL encoding，所以有空格或中文都沒關係。
//                               ╭───────── query item ─────────╮
// https://example.com/v1/player?name=%E8%89%BE%E4%BD%9B%E6%A3%AE

if let url = parts.url { ... }
```
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="warning" %}
只有以下所列的 ASCII 字元能出現在網址裡，其它文字生成 URL 時將得到 **nil**。

```
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789-._~:/?#[]@!$&'()*+,;=`.
```

:point\_right: 彼得潘 ⟩ [使用 baseURL，URLComponents & URLQueryItem 產生 URL](https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86/%E4%BD%BF%E7%94%A8-baseurl-urlcomponents-urlqueryitem-%E7%94%A2%E7%94%9F-url-1e4539a33a89)
{% endhint %}

{% hint style="warning" %}
* [appendingPathComponent(\_:)](https://developer.apple.com/documentation/foundation/nsurl/1410614-appendingpathcomponent) may read <mark style="color:orange;">**file metadata**</mark> to determine whether **the resulting path** is a <mark style="color:orange;">**directory**</mark>. This is done <mark style="color:red;">**synchronously**</mark>, and may have **significant performance costs** if the receiver is a location on a **network mounted filesystem**.&#x20;
* call [`appendingPathComponent(_:isDirectory:)`](https://developer.apple.com/documentation/foundation/nsurl/1413953-appendingpathcomponent) instead if you know whether **the resulting path** is a <mark style="color:orange;">**directory**</mark> to **avoid** this **file metadata operation**.
{% endhint %}
{% endtab %}

{% tab title="URI" %}
![URI](https://1830103165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5-JmwCZMKh_d7RfBaN%2Fuploads%2F0UQwIBiwmGk05PFlqhX0%2Furi.png?alt=media\&token=377e3ca0-6825-47e0-8e13-0e9e4f7d0fc7)

![URI syntax](https://1830103165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5-JmwCZMKh_d7RfBaN%2Fuploads%2FvAPPRqfMOq3qEvg6Vs9K%2FURI_syntax.svg?alt=media\&token=45544d17-4e0f-47ff-85c2-115a86b348ba)

```
https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                    Authority

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+
```
{% endtab %}

{% tab title="📘 手冊" %}
* [Foundation](https://developer.apple.com/documentation/foundation) ⟩ [Numbers, Data, and Basic Values](https://developer.apple.com/documentation/foundation/numbers_data_and_basic_values) ⟩&#x20;
  * [URL](https://developer.apple.com/documentation/foundation/url) ⟩&#x20;
    * [appendingPathComponent(\_:)](https://developer.apple.com/documentation/foundation/nsurl/1410614-appendingpathcomponent)
  * [URLComponents](https://developer.apple.com/documentation/foundation/urlcomponents)
  * [NSString](https://developer.apple.com/documentation/foundation/nsstring)
    * [appendingPathComponent(\_:)](https://developer.apple.com/documentation/foundation/nsstring/1417069-appendingpathcomponent) \
      👉 compare: URL ⟩ [appendingPathComponent(\_:)](https://developer.apple.com/documentation/foundation/nsurl/1410614-appendingpathcomponent)
    * [addingPercentEncoding(withAllowedCharacters:)](https://developer.apple.com/documentation/foundation/nsstring/1411946-addingpercentencoding) - 將非 ASCII 字元轉換成 % 搭配十六進位數字 (**URL encoded**)
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [Swift 建立 URL](https://dafu1231.medium.com/swift%E5%BB%BA%E7%AB%8Burl-dec8a26d794e) - URLComponents
* [ ] 彼得潘 ⟩ [使用 baseURL，URLComponents & URLQueryItem 產生 URL](https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86/%E4%BD%BF%E7%94%A8-baseurl-urlcomponents-urlqueryitem-%E7%94%A2%E7%94%9F-url-1e4539a33a89)
* [ ] Sundell ⟩ [Constructing URLs in Swift](https://www.swiftbysundell.com/articles/constructing-urls-in-swift/) ⭐️
* [ ] SwiftLee ⟩ [URLs in Swift: Common scenarios explained in-depth](https://www.avanderlee.com/swift/url-components/)  ⭐️
* [ ] Swift Playgrounds ⟩ Image Gallery ([Data Model: Gathering Image URLs](https://developer.apple.com/tutorials/sample-apps/imagegallery#Data-Model%3A-Gathering-Image-URLs))
* [ ] [Get URLs for system folders in iOS 16](https://nilcoalescing.com/blog/GetURLsForSystemFolders/) (:star: [16](../../../../../features/ios/16 "mention"))
{% endtab %}

{% tab title="🛠 工具" %}
* [URL Decode Encode](https://www.urlencoder.org/)
{% endtab %}

{% tab title="👥 相關" %}
* [filemanager](filemanager "mention") uses URLs to locate files.
{% endtab %}
{% endtabs %}

