Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RCOCOA-2394 RCOCOA-2396 RCOCOA-2397 Build in Swift 6 language mode when supported #8673

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 2 additions & 7 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ jobs:
core-version: ${{ steps.get-core-version.outputs.version }}
strategy:
matrix:
target: [macosx, iphoneos, iphonesimulator, appletvos, appletvsimulator, watchos, watchsimulator, maccatalyst]
xcode: ["15.1"]
include:
- target: xros
xcode: "15.2.0"
- target: xrsimulator
xcode: "15.2.0"
target: [macosx, iphoneos, iphonesimulator, appletvos, appletvsimulator, watchos, watchsimulator, maccatalyst, xros, xrsimulator]
xcode: ["15.3"]
steps:
- uses: actions/checkout@v4

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/master-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- "master"
- "release/**"
env:
XCODE_VERSION: "['15.1', '15.2', '15.3', '15.4']"
XCODE_VERSION: "['15.3', '15.4', '16_beta_6', '16.1_beta']"
PLATFORM: "['ios', 'osx', 'watchos', 'tvos', 'catalyst', 'visionos']"
DOC_VERSION: '15.4'
RELEASE_VERSION: '15.4'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Publish release
on: workflow_dispatch
env:
XCODE_VERSION: "['15.1', '15.2', '15.3', '15.4']"
TEST_XCODE_VERSION: '15.3'
XCODE_VERSION: "['15.3', '15.4', '16_beta_6', '16.1_beta']"
TEST_XCODE_VERSION: '15.4'
jobs:
prepare:
runs-on: ubuntu-latest
Expand Down
33 changes: 30 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
x.y.z Release notes (yyyy-MM-dd)
=============================================================
### Enhancements
* None.

The minimum supported version of Xcode is now 15.3.

### Enhancements
* Build in Swift 6 language mode when using Xcode 16. Libraries build in Swift
6 mode can be consumed by apps built in Swift 5 mode, so this should not have
any immediate effects beyond eliminating some warnings and ensuring that all
Realm APIs can be used in Swift 6 mode. Some notes about using Realm Swift in
Swift 6:
- `try await Realm(actor: actor)` has been replaced with `try await
Realm.open()` to work around isolated parameters not being implemented for
initializers (https://github.com/swiftlang/swift/issues/71174). The actor is
now automatically inferred and should not be manually passed in.
- `@ThreadSafe` is not usable as a property wrapper on local variables and
function arguments in Swift 6 mode. Sendability checking for property
wrappers never got implemented due to them being quietly deprecated in favor
of macros. It can still be used as a property wrapper for class properties
and as a manual wrapper locally, but note that it does not combine well with
actor-isolated Realms.
- In Swift 6 mode a few mongo client functions have changed from returning
`[AnyHashable: Any]` to `Document`. These should have been `Document` all
along, and the old return type no longer compiles due to not being Sendable.
* Some SwiftUI components are now explicitly marked as `@MainActor`. These
types were implicitly `@MainActor` in Swift 5, but became nonisolated when
using Xcode 16 in Swift 5 mode due to the removal of implicit isolation when
using property wrappers on member variables. This resulted in some new
sendability warnings in Xcode 16 (or errors in Swift 6 mode).
* Add Xcode 16 and 16.1 binaries to the release packages (currently built with
beta 6 and beta 1 respectively).

### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-swift/issues/????), since v?.?.?)
Expand All @@ -14,7 +41,7 @@ x.y.z Release notes (yyyy-MM-dd)
* APIs are backwards compatible with all previous releases in the 10.x.y series.
* Carthage release for Swift is built with Xcode 15.4.0.
* CocoaPods: 1.10 or later.
* Xcode: 15.1.0-16 beta 5.
* Xcode: 15.3.0-16.1 beta.

### Internal
* Upgraded realm-core from ? to ?
Expand Down
5 changes: 4 additions & 1 deletion Configuration/Base.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ APPLICATION_EXTENSION_API_ONLY = YES;
REALM_MACH_O_TYPE = mh_dylib;
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator watchos watchsimulator appletvos appletvsimulator xros xrsimulator;
SUPPORTS_MACCATALYST = YES;
SWIFT_VERSION = 5.7;
TARGETED_DEVICE_FAMILY = 1,2,3,4,6,7;

SWIFT_VERSION_1500 = 5.7;
SWIFT_VERSION_1600 = 5.7;
SWIFT_VERSION = $(SWIFT_VERSION_$(XCODE_VERSION_MAJOR));

9 changes: 8 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
// swift-tools-version:5.7
// swift-tools-version:5.10

import PackageDescription
import Foundation

let coreVersion = Version("14.12.1")
let cocoaVersion = Version("10.53.1")

#if compiler(>=6)
let swiftVersion = [SwiftVersion.version("6")]
#else
let swiftVersion = [SwiftVersion.v5]
#endif

let cxxSettings: [CXXSetting] = [
.headerSearchPath("."),
.headerSearchPath("include"),
Expand Down Expand Up @@ -392,5 +398,6 @@ let package = Package(
]
)
],
swiftLanguageVersions: swiftVersion,
cxxLanguageStandard: .cxx20
)
39 changes: 29 additions & 10 deletions Realm/ObjectServerTests/AsyncSyncTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,14 @@ class AsyncAwaitSyncTests: SwiftSyncTestCase {

let configuration = try configuration()
func isolatedOpen(_ actor: isolated CustomExecutorActor) async throws {
#if compiler(<6)
_ = try await Realm(configuration: configuration, actor: actor, downloadBeforeOpen: .always)
#else
_ = try await Realm.open(configuration: configuration, downloadBeforeOpen: .always)
#endif
}


// Try opening the Realm with the Task being cancelled at every possible
// point between executor invocations. This doesn't really test that
// cancellation is *correct*; just that cancellation never results in
Expand Down Expand Up @@ -440,6 +445,7 @@ class AsyncAwaitSyncTests: SwiftSyncTestCase {
XCTAssertEqual(app.allUsers.count, 0)
}

@MainActor
func testSwiftAddObjectsAsync() async throws {
let realm = try await openRealm()
checkCount(expected: 0, realm, SwiftPerson.self)
Expand Down Expand Up @@ -533,10 +539,11 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
try await populateSwiftPerson(5)

let user = try await createUser()
let name = self.name
try await Task {
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 0 && $0.firstName == self.name
$0.age > 0 && $0.firstName == name
})
})
config.objectTypes = [SwiftPerson.self]
Expand All @@ -555,7 +562,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 5 && $0.firstName == self.name
$0.age > 5 && $0.firstName == name
})
})
config.objectTypes = [SwiftPerson.self]
Expand All @@ -565,7 +572,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

var config2 = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 0 && $0.firstName == self.name
$0.age > 0 && $0.firstName == name
})
})
config2.objectTypes = [SwiftPerson.self]
Expand Down Expand Up @@ -619,9 +626,10 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
}

let user = try await createUser()
let name = self.name
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subscriptions in
subscriptions.append(QuerySubscription<SwiftPerson>(name: "person_age_10") {
$0.age > 10 && $0.firstName == "\(self.name)"
$0.age > 10 && $0.firstName == "\(name)"
})
})
config.objectTypes = [SwiftPerson.self]
Expand All @@ -637,10 +645,11 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

@MainActor
func testFlexibleSyncInitialSubscriptionsNotRerunOnOpen() async throws {
let name = self.name
let user = try await createUser()
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subscriptions in
subscriptions.append(QuerySubscription<SwiftPerson>(name: "person_age_10") {
$0.age > 10 && $0.firstName == "\(self.name)"
$0.age > 10 && $0.firstName == "\(name)"
})
})
config.objectTypes = [SwiftPerson.self]
Expand All @@ -655,10 +664,11 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
@MainActor
func testFlexibleSyncInitialSubscriptionsRerunOnOpenNamedQuery() async throws {
let user = try await createUser()
let name = self.name
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subscriptions in
if subscriptions.first(named: "person_age_10") == nil {
subscriptions.append(QuerySubscription<SwiftPerson>(name: "person_age_10") {
$0.age > 20 && $0.firstName == "\(self.name)"
$0.age > 20 && $0.firstName == "\(name)"
})
}
}, rerunOnOpen: true)
Expand Down Expand Up @@ -696,6 +706,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

let user = try await createUser()
let isFirstOpen = Locked(true)
let name = self.name
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subscriptions in
subscriptions.append(QuerySubscription<SwiftTypesSyncObject>(query: {
let date = isFirstOpen.wrappedValue ? Calendar.current.date(
Expand All @@ -706,7 +717,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
value: -20,
to: Date())
isFirstOpen.wrappedValue = false
return $0.stringCol == self.name && $0.dateCol < Date() && $0.dateCol > date!
return $0.stringCol == name && $0.dateCol < Date() && $0.dateCol > date!
}))
}, rerunOnOpen: true)
config.objectTypes = [SwiftTypesSyncObject.self, SwiftPerson.self]
Expand Down Expand Up @@ -823,7 +834,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
.subscribe(name: "8 or older")
realm.syncSession!.suspend()
let ex = XCTestExpectation(description: "no attempt to re-create subscription, returns immediately")
Task {
Task { @MainActor in
_ = try await realm.objects(SwiftPerson.self)
.where { $0.firstName == name && $0.age >= 8 }
.subscribe(name: "8 or older")
Expand Down Expand Up @@ -873,7 +884,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
let user = try await createUser()
var config = user.flexibleSyncConfiguration()
config.objectTypes = [SwiftPerson.self]
let realm = try await Realm(configuration: config, actor: MainActor.shared)
let realm = try await Realm(configuration: config)
let results1 = try await realm.objects(SwiftPerson.self)
.where { $0.firstName == name && $0.age > 8 }.subscribe(waitForSync: .onCreation)
XCTAssertEqual(results1.count, 2)
Expand All @@ -888,12 +899,18 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

@CustomGlobalActor
func testSubscribeOnRealmConfinedCustomActor() async throws {
try await populateSwiftPerson()
nonisolated(unsafe) let unsafeSelf = self
try await unsafeSelf.populateSwiftPerson()

let user = try await createUser()
var config = user.flexibleSyncConfiguration()
config.objectTypes = [SwiftPerson.self]
#if compiler(<6)
let realm = try await Realm(configuration: config, actor: CustomGlobalActor.shared)
#else
let realm = try await Realm.open(configuration: config)
#endif
let name = self.name
let results1 = try await realm.objects(SwiftPerson.self)
.where { $0.firstName == name && $0.age > 8 }.subscribe(waitForSync: .onCreation)
XCTAssertEqual(results1.count, 2)
Expand Down Expand Up @@ -955,6 +972,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
XCTAssertEqual(realm.subscriptions.first!.name, "sub1")
}

@MainActor
func testUnsubscribeNoExistingMatch() async throws {
try await populateSwiftPerson()
let realm = try await openRealm()
Expand Down Expand Up @@ -1151,6 +1169,7 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {

// MARK: - Custom Column

@MainActor
func testCustomColumnFlexibleSyncSchema() throws {
let realm = try openRealm()
for property in realm.schema.objectSchema.first(where: { $0.className == "SwiftCustomColumnObject" })!.properties {
Expand Down
Loading
Loading