Skip to content

Commit

Permalink
The Xcode 14 Update (#10)
Browse files Browse the repository at this point in the history
- Adds Xcode 14 information (#4)
  - Adds URL style
  - Adds Duration style
  - Updates Byte count styles with new information
  - Updates Verbatim Date format style with new information
  - Updates measurement style to reference byte count format style
- Splits site into individual pages to solve site crashing on mobie (#5)
- Updates minimum requirements to reference Xcode 13 and 14 support
  - Adds version badges
  • Loading branch information
brettohland committed Jul 31, 2022
1 parent 4aeb73f commit 0ae3ba7
Show file tree
Hide file tree
Showing 39 changed files with 2,258 additions and 569 deletions.
2 changes: 1 addition & 1 deletion config.toml
Expand Up @@ -53,7 +53,7 @@ enableRobotsTXT = true

# (Optional, default true) Show page navigation links at the bottom of each
# docs page (bundle menu only).
# geekdocNextPrev = false
geekdocNextPrev = false

# (Optional, default true) Show a breadcrumb navigation bar at the top of each docs page.
# You can also specify this parameter per page in front matter.
Expand Down
2 changes: 0 additions & 2 deletions content/_includes/attributedStrings.md
@@ -1,8 +1,6 @@
---
sitemap_ignore: true
---
## Attributed String Output

{{< hint type=tip title=TL;DR >}}

Some of the built-in styles will output `AttributedString` values instead.
Expand Down
122 changes: 85 additions & 37 deletions content/_includes/bytes.md

Large diffs are not rendered by default.

46 changes: 30 additions & 16 deletions content/_includes/datetime.md

Large diffs are not rendered by default.

283 changes: 283 additions & 0 deletions content/_includes/duration.md

Large diffs are not rendered by default.

18 changes: 8 additions & 10 deletions content/_includes/measurement.md
@@ -1,6 +1,7 @@
---
sitemap_ignore: true
---

[If you're curious, here's Apple's list of supported units.](https://developer.apple.com/documentation/foundation/dimension)

Regardless of which unit you're using, the format style has three possible widths:
Expand All @@ -27,16 +28,6 @@ gForce.<span class="call token">formatted</span>(.<span class="call token">measu
gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">narrow</span>).<span class="call token">locale</span>(franceLocale)) <span class="comment token">// "1G"</span>
gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">abbreviated</span>).<span class="call token">locale</span>(franceLocale)) <span class="comment token">// "1 force g")</span></code></pre>

### Setting the locale

You can set the locale by appending the `locale()` method onto the end of the format style.

<pre class="splash"><code><span class="keyword token">let</span> franceLocale = <span class="type token">Locale</span>(identifier: <span class="string token">"fr_FR"</span>)

gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">wide</span>).<span class="call token">locale</span>(franceLocale)) <span class="comment token">// "1 fois l’accélération de pesanteur terrestre"</span>
gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">narrow</span>).<span class="call token">locale</span>(franceLocale)) <span class="comment token">// "1G"</span>
gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">abbreviated</span>).<span class="call token">locale</span>(franceLocale)) <span class="comment token">// "1 force g"</span></code></pre>

### Initializing a Measurement Style

Due to the associated types required by the Measurement API, initializing a measurement style requires you to set the associated type.
Expand All @@ -55,3 +46,10 @@ gForce.<span class="call token">formatted</span>(inFrench) <span class="comment
You can output Attributed Strings by appending the `attributed` method onto the end of the format style.

<pre class="splash"><code>gForce.<span class="call token">formatted</span>(.<span class="call token">measurement</span>(width: .<span class="dotAccess token">wide</span>).<span class="property token">attributed</span>)</code></pre>

{{< hint type=note >}}
In Xcode 14, there is the `Measurement<UnitInformationStorage>.FormatStyle.ByteCount` format style available to you that lets you easily format byte counts

<a href="/byte-count-style">See the byte count format style section for all of the details</a>

{{< /hint >}}
205 changes: 150 additions & 55 deletions content/_includes/quiz.md

Large diffs are not rendered by default.

29 changes: 21 additions & 8 deletions content/_includes/requirements.md
Expand Up @@ -3,12 +3,25 @@ sitemap_ignore: true
---
## Minimum Requirements

- Xcode 13.0+

- iOS 15.0+
- iPadOS 15.0+
- macOS 12.0+
- Mac Catalyst 15.0+
- tvOS 15.0+
- watchOS 8.0+
<h3 id="xcode13">{{< xcode13-badge >}}</h3>

This badge represents a style that is available on any platform that is built by Xcode 13 and above (iOS 15.0+, iPadOS 15.0+, Mac Catalyst 15.0+, tvOS 15.0+, watchOS 8.0+, macOS 12.0+):

- Number styles (including currency and percent styles)
- Date styles (including iso8601, relative, and verbatim styles)
- Date range styles (interval, and components)
- Measurement styles
- List styles
- Person name styles
- Byte count styles

<h3 id="xcode14">{{< xcode14-badge >}}</h3>

This badge represents a style that has been updated, or is only available only, on platforms built by Xcode 14 and above (iOS 16.0+, iPadOS 16.0+, Mac Catalyst 16.0+, tvOS 16.0+, watchOS 9.0+, macOS 13.0+):

- (Updated) Byte count style
- (Updated) Measurement style
- Duration style
- URL style
- (Updated) Verbatim date style

2 changes: 0 additions & 2 deletions content/_includes/swiftui.md
@@ -1,8 +1,6 @@
---
sitemap_ignore: true
---
## SwiftUI Integration

{{< hint type=tip title=TL;DR >}}

Never write `Text("\()")` again. Just pass in the right `FormatStyle`
Expand Down
185 changes: 185 additions & 0 deletions content/_includes/url.md
@@ -0,0 +1,185 @@
---
sitemap_ignore: true
---

## Available Options

| Parameter | Description |
| ------------------------- | ------------------------------------------------- |
| `.always` | Always display this value |
| `.never` | Omit this value |
| `.omitIfHTTPFamily` | Omit this value if the URL is `http` or `https` |
| `.displayWhen(_:matches)` | Only display this value when the condition is met |
| `.omitWhen(:matches)` | Omit this value when the condition is met |

{{< hint type=important >}}

Brushing up on the [URLComponents documentation](https://developer.apple.com/documentation/foundation/urlcomponents/) can be very helpful to know the use cases for each individual component.

{{< /hint >}}

<pre class="splash"><code><span class="type token">Swift</span>
<span class="keyword token">let</span> appleURL = <span class="type token">URL</span>(string: <span class="string token">"https://apple.com"</span>)!
appleURL.<span class="call token">formatted</span>() <span class="comment token">// "https://apple.com"</span>
appleURL.<span class="call token">formatted</span>(.<span class="dotAccess token">url</span>) <span class="comment token">// "https://apple.com"</span>
appleURL.<span class="call token">formatted</span>(.<span class="dotAccess token">url</span>.<span class="call token">locale</span>(<span class="type token">Locale</span>(identifier: <span class="string token">"fr_FR"</span>))) <span class="comment token">// "https://apple.com"</span>

<span class="keyword token">var</span> httpComponents = <span class="type token">URLComponents</span>(url: appleURL, resolvingAgainstBaseURL: <span class="keyword token">false</span>)!
httpComponents.<span class="property token">scheme</span> = <span class="string token">"https"</span>
httpComponents.<span class="property token">user</span> = <span class="string token">"jAppleseed"</span>
httpComponents.<span class="property token">password</span> = <span class="string token">"Test1234"</span>
httpComponents.<span class="property token">host</span> = <span class="string token">"apple.com"</span>
httpComponents.<span class="property token">port</span> = <span class="number token">80</span>
httpComponents.<span class="property token">path</span> = <span class="string token">"/macbook-pro"</span>
httpComponents.<span class="property token">query</span> = <span class="string token">"get-free"</span>
httpComponents.<span class="property token">fragment</span> = <span class="string token">"someFragmentOfSomething"</span>

<span class="keyword token">let</span> complexURL = httpComponents.<span class="property token">url</span>!
<span class="keyword token">let</span> everythingStyle = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">always</span>,
user: .<span class="dotAccess token">always</span>,
password: .<span class="dotAccess token">always</span>,
host: .<span class="dotAccess token">always</span>,
port: .<span class="dotAccess token">always</span>,
path: .<span class="dotAccess token">always</span>,
query: .<span class="dotAccess token">always</span>,
fragment: .<span class="dotAccess token">always</span>
)

everythingStyle.<span class="call token">format</span>(complexURL) <span class="comment token">// "https://jAppleseed:Test1234@apple.com:80/macbook-pro?get-free#someFragmentOfSomething"</span>

<span class="keyword token">let</span> omitStyle = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">omitIfHTTPFamily</span>,
user: .<span class="dotAccess token">omitIfHTTPFamily</span>,
password: .<span class="dotAccess token">omitIfHTTPFamily</span>,
host: .<span class="dotAccess token">omitIfHTTPFamily</span>,
port: .<span class="dotAccess token">omitIfHTTPFamily</span>,
path: .<span class="dotAccess token">omitIfHTTPFamily</span>,
query: .<span class="dotAccess token">omitIfHTTPFamily</span>,
fragment: .<span class="dotAccess token">omitIfHTTPFamily</span>
)

<span class="keyword token">var</span> httpsComponent = httpComponents
httpsComponent.<span class="property token">scheme</span> = <span class="string token">"https"</span>
<span class="keyword token">let</span> httpsURL = httpsComponent.<span class="property token">url</span>!

<span class="keyword token">var</span> ftpComponents = httpComponents
ftpComponents.<span class="property token">scheme</span> = <span class="string token">"ftp"</span>
<span class="keyword token">let</span> ftpURL = ftpComponents.<span class="property token">url</span>!

omitStyle.<span class="call token">format</span>(complexURL) <span class="comment token">// ""</span>
omitStyle.<span class="call token">format</span>(httpsURL) <span class="comment token">// ""</span>
omitStyle.<span class="call token">format</span>(ftpURL) <span class="comment token">// "ftp://jAppleseed@apple.com:80/macbook-pro?get-free#someFragmentOfSomething"</span>

<span class="keyword token">let</span> localhostURL = <span class="type token">URL</span>(string: <span class="string token">"https://localhost:80/macbook-pro"</span>)!

<span class="keyword token">let</span> displayWhen = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">always</span>,
user: .<span class="dotAccess token">never</span>,
password: .<span class="dotAccess token">never</span>,
host: .<span class="call token">displayWhen</span>(.<span class="dotAccess token">host</span>, matches: [<span class="string token">"localhost"</span>]),
port: .<span class="dotAccess token">always</span>,
path: .<span class="dotAccess token">always</span>,
query: .<span class="dotAccess token">never</span>,
fragment: .<span class="dotAccess token">never</span>
)

displayWhen.<span class="call token">format</span>(complexURL) <span class="comment token">// "https://:80/macbook-pro"</span>
displayWhen.<span class="call token">format</span>(localhostURL) <span class="comment token">// "https://localhost:80/macbook-pro"</span>

<span class="keyword token">let</span> omitWhen = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">always</span>,
user: .<span class="dotAccess token">never</span>,
password: .<span class="dotAccess token">never</span>,
host: .<span class="call token">omitWhen</span>(.<span class="dotAccess token">host</span>, matches: [<span class="string token">"localhost"</span>]),
port: .<span class="dotAccess token">always</span>,
path: .<span class="dotAccess token">always</span>,
query: .<span class="dotAccess token">never</span>,
fragment: .<span class="dotAccess token">never</span>
)

omitWhen.<span class="call token">format</span>(complexURL) <span class="comment token">// "https://apple.com:80/macbook-pro"</span>
omitWhen.<span class="call token">format</span>(localhostURL) <span class="comment token">// "https://:80/macbook-pro"</span>

<span class="keyword token">let</span> omitSpecificWhen = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">always</span>,
user: .<span class="dotAccess token">never</span>,
password: .<span class="dotAccess token">never</span>,
host: .<span class="call token">omitSpecificSubdomains</span>([<span class="string token">"secret"</span>], includeMultiLevelSubdomains: <span class="keyword token">false</span>),
port: .<span class="dotAccess token">always</span>,
path: .<span class="dotAccess token">always</span>,
query: .<span class="dotAccess token">never</span>,
fragment: .<span class="dotAccess token">never</span>
)

<span class="keyword token">var</span> secretAppleURL = <span class="type token">URL</span>(string: <span class="string token">"https://secret.apple.com/macbook-pro"</span>)!

omitSpecificWhen.<span class="call token">format</span>(complexURL) <span class="comment token">// "https://apple.com:80/macbook-pro"</span>
omitSpecificWhen.<span class="call token">format</span>(secretAppleURL) <span class="comment token">// "https://apple.com/macbook-pro"</span>

<span class="keyword token">let</span> omitSpecificWhenWhere = <span class="type token">URL</span>.<span class="type token">FormatStyle</span>(
scheme: .<span class="dotAccess token">always</span>,
user: .<span class="dotAccess token">never</span>,
password: .<span class="dotAccess token">never</span>,
host: .<span class="call token">omitSpecificSubdomains</span>([<span class="string token">"secret"</span>], includeMultiLevelSubdomains: <span class="keyword token">false</span>, when: .<span class="dotAccess token">user</span>, matches: [<span class="string token">"jAppleseed"</span>]),
port: .<span class="dotAccess token">always</span>,
path: .<span class="dotAccess token">always</span>,
query: .<span class="dotAccess token">never</span>,
fragment: .<span class="dotAccess token">never</span>
)

<span class="keyword token">let</span> complexSecretURL = <span class="type token">URL</span>(string: <span class="string token">"https://jAppleseed:Test1234@secret.apple.com:80/macbook-pro?get-free#someFragmentOfSomething"</span>)!

omitSpecificWhenWhere.<span class="call token">format</span>(complexSecretURL) <span class="comment token">// "https://apple.com:80/macbook-pro"</span>
omitSpecificWhenWhere.<span class="call token">format</span>(secretAppleURL) <span class="comment token">// "https://secret.apple.com/macbook-pro"</span></code></pre>

## Parsing URLs

The venerable URL initializer `URL(string:relativeTo:)` has been available to us since Xcode 10.2. In most cases this will work well for most use cases.

If you're looking to parse URLs in a structured way, you can use the URL parse strategy on the URL.FormatStyle struct.

### Available Options

For each component of the URL (scheme, user, password, host, port, path, query, or fragment) you can configure them with the following options:

| Parameter | Description |
| ----------------- | ----------------------------------------- |
| `.optional` | Sets the unit as optional |
| `.required` | Sets the unit as required for a valid URL |
| `.defaultValue()` | If missing, uses the default value |

{{< hint type=note >}}

By default, only the scheme and the host are set as required.

{{< /hint >}}

<pre class="splash"><code><span class="type token">Swift</span>
<span class="keyword token">try</span> <span class="type token">URL</span>.<span class="type token">FormatStyle</span>.<span class="type token">Strategy</span>(port: .<span class="call token">defaultValue</span>(<span class="number token">80</span>)).<span class="call token">parse</span>(<span class="string token">"http://www.apple.com"</span>) <span class="comment token">// http://www.apple.com:80</span>
<span class="keyword token">try</span> <span class="type token">URL</span>.<span class="type token">FormatStyle</span>.<span class="type token">Strategy</span>(port: .<span class="dotAccess token">optional</span>).<span class="call token">parse</span>(<span class="string token">"http://www.apple.com"</span>) <span class="comment token">// http://www.apple.com</span>
<span class="keyword token">try</span> <span class="type token">URL</span>.<span class="type token">FormatStyle</span>.<span class="type token">Strategy</span>(port: .<span class="dotAccess token">required</span>).<span class="call token">parse</span>(<span class="string token">"http://www.apple.com"</span>) <span class="comment token">// throws an error

// This returns a valid URL</span>
<span class="keyword token">try</span> <span class="type token">URL</span>.<span class="type token">FormatStyle</span>.<span class="type token">Strategy</span>()
.<span class="call token">scheme</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">user</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">password</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">host</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">port</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">path</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">query</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">fragment</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">parse</span>(<span class="string token">"https://jAppleseed:Test1234@apple.com:80/macbook-pro?get-free#someFragmentOfSomething"</span>)

<span class="comment token">// This throws an error (the port is missing)</span>
<span class="keyword token">try</span> <span class="type token">URL</span>.<span class="type token">FormatStyle</span>.<span class="type token">Strategy</span>()
.<span class="call token">scheme</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">user</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">password</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">host</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">port</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">path</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">query</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">fragment</span>(.<span class="dotAccess token">required</span>)
.<span class="call token">parse</span>(<span class="string token">"https://jAppleseed:Test1234@apple.com/macbook-pro?get-free#someFragmentOfSomething"</span>)</code></pre>

0 comments on commit 0ae3ba7

Please sign in to comment.