Skip to content

Commit

Permalink
Build in Swift 6 language mode when supported
Browse files Browse the repository at this point in the history
  • Loading branch information
tgoyne committed Aug 28, 2024
1 parent 7ffcc11 commit b56f1e6
Show file tree
Hide file tree
Showing 54 changed files with 2,441 additions and 711 deletions.
22 changes: 20 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
x.y.z Release notes (yyyy-MM-dd)
=============================================================

The minimum supported version of Xcode is now 15.3.

### Enhancements
* None.
* 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 (swift bug link). The actor is now automatically inferred.
- `@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.


### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-swift/issues/????), since v?.?.?)
Expand All @@ -14,7 +32,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 beta 5.

### Internal
* Upgraded realm-core from ? to ?
Expand Down
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.0")
let cocoaVersion = Version("10.53.0")

#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
)
6 changes: 6 additions & 0 deletions Realm.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2895,6 +2895,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3FEC91542A4B59A40044BFF5 /* Static.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Static;
};
Expand All @@ -2909,6 +2910,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 5D660FBD1BE98BEF0021E04F /* RealmSwift.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Static;
};
Expand Down Expand Up @@ -3087,13 +3089,15 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 5D660FBD1BE98BEF0021E04F /* RealmSwift.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Debug;
};
5D660FD31BE98C560021E04F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5D660FBD1BE98BEF0021E04F /* RealmSwift.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Release;
};
Expand Down Expand Up @@ -3233,13 +3237,15 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 5D659E6E1BE0398E006515A0 /* Debug.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Debug;
};
E8D89BAD1955FC6D00CF2B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5D659E6F1BE0398E006515A0 /* Release.xcconfig */;
buildSettings = {
SWIFT_VERSION = 6.0;
};
name = Release;
};
Expand Down
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 @@ -442,6 +447,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 @@ -535,10 +541,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 @@ -557,7 +564,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 @@ -567,7 +574,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 @@ -621,9 +628,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 @@ -639,10 +647,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 @@ -657,10 +666,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 @@ -698,6 +708,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 @@ -708,7 +719,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 @@ -825,7 +836,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 @@ -875,7 +886,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 @@ -890,12 +901,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 @@ -957,6 +974,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 @@ -1153,6 +1171,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

0 comments on commit b56f1e6

Please sign in to comment.