Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 64 additions & 57 deletions _layouts/new-layouts/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,76 @@
---

<section id="post" class="section">
<div class="swoop swoop-1"></div>
<div class="swoop swoop-1"></div>

<div class="content">
<h1>{{ page.title }}</h1>
<div class="content">
<h1>{{ page.title }}</h1>

{% include authors.html authors=page.author compact=true %}
{% include authors.html authors=page.author compact=true %}

<time pubdate datetime="{{ page.date | date_to_xmlschema }}">{{ page.date | date: "%B %-d, %Y" }}</time>
<time pubdate datetime="{{ page.date | date_to_xmlschema }}"
>{{ page.date | date: "%B %-d, %Y" }}</time
>
{% assign featured_image = page.featured-image %} {% assign
featured_image_dark = page.featured-image-dark %} {% if featured_image.url
%}
<img
class="featured{% if featured_image_dark.url %} hide-dark{% endif %}"
src="{{ featured_image.url }}"
alt="{{ featured_image.alt }}"
/>
{% endif %} {% if featured_image_dark.url %}
<img
class="featured hide-light"
src="{{ featured_image_dark.url }}"
alt="{{ featured_image_dark.alt }}"
/>
{% endif %}
<div class="details">
{{ content }} {% if page.author %}
<hr />
<h2>Authors</h2>
{% include authors.html authors=page.author %} {% endif %}

{% if page.image %}
<img class="featured" src="/assets/images/{{ page.image | split: '.' | first }}/{{ page.image }}"
alt="{{ page.title }} featured image" />
{% endif %}
<hr />

<div class="details">
{{ content }}
<h2>Continue Reading</h2>

{% if page.author %}
<hr />
<h2>Authors</h2>
{% include authors.html authors=page.author %}
{% endif %}

<hr />

<h2>Continue Reading</h2>

{% if page.previous or page.next %}
<nav class="section card-grid">
<div class="content">
<ul class="tertiary-cards">
{% if page.previous %}
<li>
<div>
<h3>{{ page.previous.title }}</h3>
<time pubdate datetime="{{ page.date | date_to_xmlschema }}">{{ page.previous.date | date: "%B %-d, %Y" }}</time>
<p class="nav-excerpt">
{{ page.previous.excerpt | strip_html | truncate: 80, '..' }}
</p>
<a href="{{ page.previous.url }}" rel="prev">
More
</a>
</div>
</li>
{% endif %}
{% if page.next %}
<li>
<div>
<h3>{{ page.next.title }}</h3>
<time pubdate datetime="{{ page.date | date_to_xmlschema }}">{{ page.next.date | date: "%B %-d, %Y" }}</time>
<p class="nav-excerpt">
{{ page.next.excerpt | strip_html | truncate: 80, '..' }}
</p>
<a href="{{ page.next.url }}" rel="next">
More
</a>
</div>
</li>
{% endif %}
</ul>
</div>
</nav>
{% if page.previous or page.next %}
<nav class="section card-grid">
<div class="content">
<ul class="tertiary-cards">
{% if page.previous %}
<li>
<div>
<h3>{{ page.previous.title }}</h3>
<time pubdate datetime="{{ page.date | date_to_xmlschema }}"
>{{ page.previous.date | date: "%B %-d, %Y" }}</time
>
<p class="nav-excerpt">
{{ page.previous.excerpt | strip_html | truncate: 80, '..' }}
</p>
<a href="{{ page.previous.url }}" rel="prev"> More </a>
</div>
</li>
{% endif %} {% if page.next %}
<li>
<div>
<h3>{{ page.next.title }}</h3>
<time pubdate datetime="{{ page.date | date_to_xmlschema }}"
>{{ page.next.date | date: "%B %-d, %Y" }}</time
>
<p class="nav-excerpt">
{{ page.next.excerpt | strip_html | truncate: 80, '..' }}
</p>
<a href="{{ page.next.url }}" rel="next"> More </a>
</div>
</li>
{% endif %}
</ul>
</div>
</nav>
{% endif %}
</div>
</section>
</div>
</section>
21 changes: 9 additions & 12 deletions _posts/2024-09-17-announcing-swift-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ date: 2024-09-17 10:00:00
title: Announcing Swift 6
author: [hborla]
category: "Language"
featured-image:
url: '/assets/images/placeholders/image_placeholder_large.png'
alt: 'An FPO image for a blog.'
---

We're delighted to announce the general availability of Swift 6. This is a major new release that expands Swift to more platforms and domains.
Expand All @@ -22,7 +19,7 @@ Read on for a deep dive into changes to the language, standard libraries, debugg

### Concurrency

Swift has long offered memory safety, ensuring that variables are initialized before they’re used, memory isn’t accessed after it’s been deallocated, and array indices are checked for out-of-bounds errors. Swift 6 now includes a new, opt-in language mode that extends Swift’s safety guarantees to prevent data races in concurrent code by diagnosing potential data races in your code as compiler errors.
Swift has long offered memory safety, ensuring that variables are initialized before they’re used, memory isn’t accessed after it’s been deallocated, and array indices are checked for out-of-bounds errors. Swift 6 now includes a new, opt-in language mode that extends Swift’s safety guarantees to prevent data races in concurrent code by diagnosing potential data races in your code as compiler errors.

Data-race safety checks were previously available as warnings in Swift 5.10 through the `-strict-concurrency=complete` compiler flag. Thanks to improved `Sendable` inference and new compiler analysis for transferring mutable state from one actor to another, Swift 6 warnings about data-race safety have fewer false positives. You can find more information about the Swift 6 language mode and how to migrate at [Swift.org/migration](http://swift.org/migration).

Expand All @@ -37,8 +34,8 @@ Swift 6 enables functions to specify the type of error that they throw as part o
For example:

```swift
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
}
```

Expand All @@ -58,8 +55,8 @@ Typed throws can also be used in generic functions to propagate error types from

```swift
extension Sequence {
func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T] {
// ...
func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T] {
// ...
}
}
```
Expand Down Expand Up @@ -118,7 +115,7 @@ Swift 6 rounds out the set of low-level integer primitives with the addition of

### Productivity enhancements

Swift 6 introduces a number of productivity enhancements, including [`count(where:)`](https://developer.apple.com/documentation/swift/sequence/count(where:)) to streamline counting the number of elements in a sequence that satisfy a predicate, [pack iteration](https://www.swift.org/blog/pack-iteration/) for writing natural `for`-loops over the elements in a value parameter pack, access control for imports to keep implementation details from leaking into your public APIs, `@attached(body)` macros for synthesizing and augmenting function implementations, expression macros as default arguments, and more.
Swift 6 introduces a number of productivity enhancements, including [`count(where:)`](<https://developer.apple.com/documentation/swift/sequence/count(where:)>) to streamline counting the number of elements in a sequence that satisfy a predicate, [pack iteration](https://www.swift.org/blog/pack-iteration/) for writing natural `for`-loops over the elements in a value parameter pack, access control for imports to keep implementation details from leaking into your public APIs, `@attached(body)` macros for synthesizing and augmenting function implementations, expression macros as default arguments, and more.

You can find a complete list of language proposals that were accepted through the [Swift Evolution](https://github.com/swiftlang/swift-evolution) process and implemented in Swift 6 on the [Swift Evolution dashboard](https://www.swift.org/swift-evolution/#?version=6.0).

Expand All @@ -130,7 +127,7 @@ Swift 6 provides a new debugging macro to easily customize how an object is disp

Types that conform to `CustomDebugStringConvertible` provide a `debugDescription` property that returns a string describing the object. In LLDB, the `po` command calls this computed property on an object. In contrast, the `p` command uses LLDB’s type summary formatters to directly format the object using its stored property values.

[`@DebugDescription`](https://developer.apple.com/documentation/swift/debugdescription()) is a new macro in the standard library which lets you specify LLDB type summaries for your own types directly in code. The macro processes the `debugDescription` property, translating simple string interpolations involving stored properties into LLDB type summaries. This allows LLDB to use your custom formatting even when using `p`, and also in Xcode or VSCode’s variable display windows. The macro can use an existing conformance to `CustomDebugStringConvertible`, or you can provide a separate string interpolation only for use in LLDB’s `p` command. Providing a separate LLDB description string is useful if your `CustomDebugStringConvertible` implementation doesn’t meet the requirements of the `@DebugDescription` macro, or if you’re familiar with the [LLDB Summary String syntax](https://lldb.llvm.org/use/variable.html#summary-strings) and you want to use it directly.
[`@DebugDescription`](<https://developer.apple.com/documentation/swift/debugdescription()>) is a new macro in the standard library which lets you specify LLDB type summaries for your own types directly in code. The macro processes the `debugDescription` property, translating simple string interpolations involving stored properties into LLDB type summaries. This allows LLDB to use your custom formatting even when using `p`, and also in Xcode or VSCode’s variable display windows. The macro can use an existing conformance to `CustomDebugStringConvertible`, or you can provide a separate string interpolation only for use in LLDB’s `p` command. Providing a separate LLDB description string is useful if your `CustomDebugStringConvertible` implementation doesn’t meet the requirements of the `@DebugDescription` macro, or if you’re familiar with the [LLDB Summary String syntax](https://lldb.llvm.org/use/variable.html#summary-strings) and you want to use it directly.

For example, the following code customizes how `po` in LLDB displays the `Organization` type with a conformance to `CustomDebugStringConvertible`, and the `@DebugDescription` macro exposes this custom formatting to the `p` command and the variables view:

Expand All @@ -150,7 +147,7 @@ struct Organization: CustomDebugStringConvertible {

```
(lldb) p myOrg
(Organization) myOrg = "`#100 Worldwide Travel [Jonathan Swift]`"
(Organization) myOrg = "`#100 Worldwide Travel [Jonathan Swift]`"
```

### Improved startup performance with explicit modules
Expand Down Expand Up @@ -188,7 +185,7 @@ func mentionedContinents(videoName: String) async throws {

Swift Testing takes full advantage of macros. Its `@Test` and `@Suite` attached macros declare test functions and suite types respectively, and they accept arguments (known as traits) to customize various behaviors. The `#expect` and `#require` expression macros validate expected behaviors, and capture rich representation of expressions and their sub-values to produce detailed failure messages.

Since Swift Testing is included directly in Swift 6 toolchains, you can `import Testing` without needing to declare a package dependency. This means your tests do not need to build Swift Testing or its dependencies (including swift-syntax), and its macro implementation comes prebuilt. The package manager in Swift 6 automatically builds and runs Swift Testing tests in addition to XCTests (if present), and shows results from both libraries in log output. Swift Testing supports all platforms that Swift officially supports, including all Apple platforms, Linux, and Windows.
Since Swift Testing is included directly in Swift 6 toolchains, you can `import Testing` without needing to declare a package dependency. This means your tests do not need to build Swift Testing or its dependencies (including swift-syntax), and its macro implementation comes prebuilt. The package manager in Swift 6 automatically builds and runs Swift Testing tests in addition to XCTests (if present), and shows results from both libraries in log output. Swift Testing supports all platforms that Swift officially supports, including all Apple platforms, Linux, and Windows.

To learn more about this new open source project, visit the [swift-testing](https://github.com/swiftlang/swift-testing) repository on GitHub, and get involved with its ongoing development [on the forums](https://forums.swift.org/c/related-projects/swift-testing/103).

Expand Down
Binary file added assets/images/6.2-blog/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/6.2-blog/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 26 additions & 29 deletions assets/javascripts/new-javascripts/blog.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
const wrapper = document.querySelector('.blogs-and-filter-wrapper')
const postsWrapper = wrapper.querySelector('.blogs-wrapper')
const postData = JSON.parse(wrapper.querySelector('#post-data').textContent)
const checkboxes = [...wrapper.querySelectorAll('.category-filter')]
const filters = [...wrapper.querySelectorAll('.category-filter')]
const selectAllBox = document.querySelector('.select-all')
const dropdown = document.querySelector('.dropdown')
const allCheckboxes = [selectAllBox, ...checkboxes]
const allCheckboxes = [selectAllBox, ...filters]
const filterMenuToggle = document.querySelector('.dropdown-toggle')
const dropdownCloseButton = document.querySelector('.dropdown-close')

// create post links
const createAnchor = (postData) => {
const anchor = document.createElement('a')
const imgEl = postData['image-url']
? `<img src="${postData['image-url']}" alt="${postData['image-alt']}" />`
: ''
console.log(imgEl, postData.title)
anchor.href = postData.url
anchor.classList = imgEl ? 'post-link post-link-with-image' : 'post-link'
anchor.classList = 'post-link'
anchor.innerHTML = `
${imgEl}
${imgEl ? '<div>' : ''}
<h3 class="title">${postData.title}</h3>
<time pubdate datetime="${postData.date}" class="blog-date">${postData.date}</time>
<p class="body-copy">${postData.excerpt}</p>
${postData.categories.reduce((markup, category) => {
return markup + ` <span class="category body-copy">${category}</span>`
}, '')}
${imgEl ? '</div>' : ''}
`
return anchor
}

// checks all filters
const selectAllCategories = () => {
const selectAllCategories = (selectAllBox, checkboxes) => {
if (selectAllBox.checked) {
checkboxes.forEach((checkbox) => {
checkbox.checked = true
Expand Down Expand Up @@ -71,12 +64,12 @@ const elementsCache = postData.map((post) => {
}
})

updatePosts(filterPosts(elementsCache, checkboxes), postsWrapper, postsWrapper)
updatePosts(filterPosts(elementsCache, filters), postsWrapper, postsWrapper)

filterMenuToggle.addEventListener('click', () => {
dropdown.classList.toggle('active')

const isExpanded = this.getAttribute('aria-expanded') === 'true'
const isExpanded = filterMenuToggle.getAttribute('aria-expanded') === 'true'
filterMenuToggle.toggleAttribute('aria-expanded', !isExpanded)
})

Expand All @@ -89,28 +82,32 @@ window.addEventListener('click', (evt) => {
})

// Select all category filters
selectAllBox.addEventListener('click', selectAllCategories)

dropdownCloseButton.addEventListener('click', () => {
const dropdown = this.closest('.dropdown')
dropdown.classList.remove('active')
document
.querySelector('.dropdown-toggle')
.setAttribute('aria-expanded', 'false')
})
selectAllBox.addEventListener('click', () =>
selectAllCategories(selectAllBox, filters),
)

checkboxes.forEach((checkbox) => {
filters.forEach((checkbox) => {
checkbox.addEventListener('change', () => {
// If every box is either checked or none are, set all filter to checked
if (
checkboxes.every((checkbox) => checkbox.checked === checkboxes[0].checked)
) {
const enabledFilters = filters.filter((checkbox) => checkbox.checked)

if (enabledFilters.length === 1) {
enabledFilters[0].disabled = true
} else {
filters.forEach((checkbox) => (checkbox.disabled = false))
}

// If every box is checked, select all
if (enabledFilters.length === filters.length) {
selectAllBox.checked = true
selectAllBox.disabled = true
selectAllCategories()
return
// Uncheck all select all if filter was unchecked
} else if (!checkbox.checked && selectAllBox.checked) {
selectAllBox.checked = false
selectAllBox.disabled = false
}
updatePosts(filterPosts(elementsCache, checkboxes), postsWrapper)

updatePosts(filterPosts(elementsCache, filters), postsWrapper)
})
})
14 changes: 14 additions & 0 deletions assets/stylesheets/new-stylesheets/_helpers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@
}
}

body[data-color-scheme='light'] {
.hide-light {
display: none
}
}

body[data-color-scheme='dark'] {
.hide-dark {
display: none
}
}



@mixin underline {
text-decoration: underline;
text-decoration-color: color-mix(in srgb, currentColor 50%, transparent);
Expand Down
3 changes: 2 additions & 1 deletion assets/stylesheets/new-stylesheets/pages/_blog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
}

.dropdown-header {
padding: 53px 0 20px;
padding: 23px 0 20px;
}

&.active {
Expand Down Expand Up @@ -361,6 +361,7 @@
width: 25px;
height: 25px;
border-radius: 5px;
outline: 1px solid var(--site-text-color);
}

label {
Expand Down
Loading