Skip to content

Commit

Permalink
Merge pull request #8618 from realm/tg/xcode-16
Browse files Browse the repository at this point in the history
RCOCOA-2393 Add support for Xcode 16
  • Loading branch information
tgoyne authored Jun 18, 2024
2 parents c3492ed + 4f58799 commit b30dcd4
Show file tree
Hide file tree
Showing 80 changed files with 1,753 additions and 880 deletions.
69 changes: 55 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
x.y.z Release notes (yyyy-MM-dd)
=============================================================
### Enhancements
* Add `@ObservedSectionedResults.remove(atOffsets:section:)` which adds the ability to
* Add `@ObservedSectionedResults.remove(atOffsets:section:)` which adds the ability to
remove a Realm Object when using `onDelete` on `ForEach` in a SwiftUI `List`.
* Add support for Xcode 16 beta 1 and fix some of the new warnings. Note that
this does not yet include full support for Swift 6 language mode
([#8618](https://github.com/realm/realm-swift/pull/8618)).
* `Realm.asyncWrite()` and `Realm.asyncRefresh()` now use the new `#isolation`
feature to avoid sendability warnings when building with Xcode 16
([#8618](https://github.com/realm/realm-swift/pull/8618)).
* Include the originating client reset error message in errors reporting that
automatic client reset handling failed. ([Core #7761](https://github.com/realm/realm-core/pull/7761))
* Improve the performance of insertion-heavy write transactions, particularly
when setting a large number of properties on each object created
([Core #7734](https://github.com/realm/realm-core/pull/7734)).
* App now trims trailing slashes from the base url rather than producing
confusing 404 errors. ([Core #7791](https://github.com/realm/realm-core/pull/7791)).

### Fixed
* Deleting a Realm Object used in a `@ObservedSectionedResults` collection in `SwiftUI`
would cause a crash during the diff on the `View`. ([#8294](https://github.com/realm/realm-swift/issues/8294), since v10.29.0)
* Fix some client resets (such as migrating to flexible sync) potentially
failing if a new client reset condition (such as rolling back a flexible sync
migration) occurred before the first one completed.
([Core #7542](https://github.com/realm/realm-core/pull/7542), since v10.40.0)
* The encryption code no longer behaves differently depending on the system
page size, which should entirely eliminate a recurring source of bugs related
to copying encrypted Realm files between platforms with different page sizes.
One known outstanding bug was ([RNET-1141](https://github.com/realm/realm-dotnet/issues/3592)),
where opening files on a system with a larger page size than the writing
system would attempt to read sections of the file which had never been
written to ([Core #7698](https://github.com/realm/realm-core/pull/7698)).
* There were several complicated scenarios which could result in stale reads
from encrypted files in multiprocess scenarios. These were very difficult to
hit and would typically lead to a crash, either due to an assertion failure
or DecryptionFailure being thrown ([Core #7698](https://github.com/realm/realm-core/pull/7698), since v10.38.0).
* Encrypted files have some benign data races where we can memcpy a block of
memory while another thread is writing to a limited range of it. It is
logically impossible to ever read from that range when this happens, but
Thread Sanitizer quite reasonably complains about this. We now perform a
slower operations when running with TSan which avoids this benign race
([Core #7698](https://github.com/realm/realm-core/pull/7698)).
* `Realm.asyncOpen()` on a flexible sync Realm would sometimes fail to wait for
pending subscriptions to complete, resulting in it not actually waiting for
all data to be downloaded. ([Core #7720](https://github.com/realm/realm-core/issues/7720),
since flexible sync was introduced).
* `List<AnyRealmValue>.clear()` would hit an assertion failure when used on a
file originally created by a version of Realm older than v10.49.0.
([Core #7771](https://github.com/realm/realm-core/issues/7771), since 10.49.0)

<!-- ### Breaking Changes - ONLY INCLUDE FOR NEW MAJOR version -->

Expand All @@ -15,10 +56,10 @@ 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-15.4.0.
* Xcode: 15.1.0-16 beta

### Internal
* Upgraded realm-core from ? to ?
* Upgraded realm-core from v14.9.0 to 14.10.1

10.51.0 Release notes (2024-06-06)
=============================================================
Expand Down Expand Up @@ -48,29 +89,29 @@ x.y.z Release notes (yyyy-MM-dd)
```swift
realm.objects(MixedObject.self).where { $0.anyValue[0][0][1] == .double(76.54) }
```

The `.any` operator allows looking up in all keys or indexes.
```swift
realm.objects(MixedObject.self).where { $0.anyValue["key"].any == .bool(false) }
```
* Report the originating error that caused a client reset to occur.
* Report the originating error that caused a client reset to occur.
([Core #6154](https://github.com/realm/realm-core/issues/6154))

### Fixed

* Accessing `App.currentUser` from within a notification produced by `App.switchToUser()`
(which includes notifications for a newly logged in user) would deadlock.
* Accessing `App.currentUser` from within a notification produced by `App.switchToUser()`
(which includes notifications for a newly logged in user) would deadlock.
([Core #7670](https://github.com/realm/realm-core/issues/7670), since v10.50.0).
* Inserting the same link to the same key in a dictionary more than once would incorrectly create
multiple backlinks to the object. This did not appear to cause any crashes later, but would
have affecting explicit backlink count queries and possibly notifications.
* Inserting the same link to the same key in a dictionary more than once would incorrectly create
multiple backlinks to the object. This did not appear to cause any crashes later, but would
have affecting explicit backlink count queries and possibly notifications.
([Core #7676](https://github.com/realm/realm-core/issues/7676), since v10.49.2).
* A non-streaming progress notifier would not immediately call its callback after registration.
Instead you would have to wait for a download message to be received to get your first
* A non-streaming progress notifier would not immediately call its callback after registration.
Instead you would have to wait for a download message to be received to get your first
update - if you were already caught up when you registered the notifier you could end up waiting a
long time for the server to deliver a download that would call/expire your notifier
long time for the server to deliver a download that would call/expire your notifier
([Core #7627](https://github.com/realm/realm-core/issues/7627), since v10.50.0).
* After compacting, a file upgrade would be triggered. This could cause loss of data
* After compacting, a file upgrade would be triggered. This could cause loss of data
if `deleteRealmIfMigrationNeeded` is set to true.
([Core #7747](https://github.com/realm/realm-core/issues/7747), since v10.49.0).

Expand Down
8 changes: 4 additions & 4 deletions Configuration/Base.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ HEADER_SEARCH_PATHS = $(inherited) core/include;
CODE_SIGN_IDENTITY[sdk=iphone*] = iPhone Developer;
CODE_SIGNING_REQUIRED[sdk=macosx] = NO;

IPHONEOS_DEPLOYMENT_TARGET_1400 = 11.0;
IPHONEOS_DEPLOYMENT_TARGET_1500 = 12.0;
IPHONEOS_DEPLOYMENT_TARGET_1600 = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = $(IPHONEOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR));
MACOSX_DEPLOYMENT_TARGET_1400 = 10.13;
MACOSX_DEPLOYMENT_TARGET_1500 = 10.14;
MACOSX_DEPLOYMENT_TARGET_1600 = 10.14;
MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR));
WATCHOS_DEPLOYMENT_TARGET_1400 = 4.0;
WATCHOS_DEPLOYMENT_TARGET_1500 = 4.0;
WATCHOS_DEPLOYMENT_TARGET_1600 = 4.0;
WATCHOS_DEPLOYMENT_TARGET = $(WATCHOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR));
TVOS_DEPLOYMENT_TARGET_1400 = 11.0;
TVOS_DEPLOYMENT_TARGET_1500 = 12.0;
TVOS_DEPLOYMENT_TARGET_1600 = 12.0;
TVOS_DEPLOYMENT_TARGET = $(TVOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR));

APPLICATION_EXTENSION_API_ONLY = YES;
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import PackageDescription
import Foundation

let coreVersion = Version("14.9.0")
let coreVersion = Version("14.10.1")
let cocoaVersion = Version("10.51.0")

let cxxSettings: [CXXSetting] = [
Expand Down
8 changes: 4 additions & 4 deletions Realm.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,17 @@ Pod::Spec.new do |s|
'OTHER_CPLUSPLUSFLAGS' => '-isystem "${PODS_ROOT}/Realm/include/core" -fvisibility-inlines-hidden',
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/Realm/include" "${PODS_ROOT}/Realm/include/Realm"',

'IPHONEOS_DEPLOYMENT_TARGET_1400' => '11.0',
'IPHONEOS_DEPLOYMENT_TARGET_1500' => '12.0',
'IPHONEOS_DEPLOYMENT_TARGET_1600' => '12.0',
'IPHONEOS_DEPLOYMENT_TARGET' => '$(IPHONEOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR))',
'MACOSX_DEPLOYMENT_TARGET_1400' => '10.13',
'MACOSX_DEPLOYMENT_TARGET_1500' => '10.13',
'MACOSX_DEPLOYMENT_TARGET_1600' => '10.13',
'MACOSX_DEPLOYMENT_TARGET' => '$(MACOSX_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR))',
'WATCHOS_DEPLOYMENT_TARGET_1400' => '4.0',
'WATCHOS_DEPLOYMENT_TARGET_1500' => '4.0',
'WATCHOS_DEPLOYMENT_TARGET_1600' => '4.0',
'WATCHOS_DEPLOYMENT_TARGET' => '$(WATCHOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR))',
'TVOS_DEPLOYMENT_TARGET_1400' => '11.0',
'TVOS_DEPLOYMENT_TARGET_1500' => '12.0',
'TVOS_DEPLOYMENT_TARGET_1600' => '12.0',
'TVOS_DEPLOYMENT_TARGET' => '$(TVOS_DEPLOYMENT_TARGET_$(XCODE_VERSION_MAJOR))',

'OTHER_LDFLAGS' => '"-Wl,-unexported_symbols_list,${PODS_ROOT}/Realm/Configuration/Realm/PrivateSymbols.txt"',
Expand Down
2 changes: 1 addition & 1 deletion Realm/ObjectServerTests/SwiftObjectServerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ class SwiftObjectServerTests: SwiftSyncTestCase {
proxy.stop()
}

class LocationOverrideTransport: RLMNetworkTransport {
class LocationOverrideTransport: RLMNetworkTransport, Sendable {
let hostname: String
let wsHostname: String
init(hostname: String = "http://localhost:9090", wsHostname: String = "ws://invalid.com:9090") {
Expand Down
2 changes: 1 addition & 1 deletion Realm/RLMCollection.mm
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ - (bool)invalidate {
}

RLMThreadSafeReference *tsr = [RLMThreadSafeReference referenceWithThreadConfined:collection];
RLMRealmConfiguration *config = realm.configuration;
RLMRealmConfiguration *config = realm.configurationSharingSchema;
dispatch_async(queue, ^{
std::lock_guard lock(token->_mutex);
if (!token->_realm) {
Expand Down
2 changes: 1 addition & 1 deletion Realm/RLMObjectBase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ - (void)registrationComplete:(void (^)())completion {
RLMThreadSafeReference *tsr = [RLMThreadSafeReference referenceWithThreadConfined:(id)obj];
auto token = [[RLMObjectNotificationToken alloc] init];
token->_realm = obj->_realm;
RLMRealmConfiguration *config = obj->_realm.configuration;
RLMRealmConfiguration *config = obj->_realm.configurationSharingSchema;
dispatch_async(queue, ^{
@autoreleasepool {
[token addNotificationBlock:block threadSafeReference:tsr config:config keyPaths:keyPaths queue:queue];
Expand Down
2 changes: 1 addition & 1 deletion Realm/RLMObservation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ void RLMClearTable(RLMClassInfo &objectSchema) {
return;
}

_group.set_cascade_notification_handler([=](realm::Group::CascadeNotification const& cs) {
_group.set_cascade_notification_handler([this](realm::Group::CascadeNotification const& cs) {
cascadeNotification(cs);
});
}
Expand Down
3 changes: 0 additions & 3 deletions Realm/RLMQueryUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ namespace realm {
@class RLMObjectSchema, RLMProperty, RLMSchema, RLMSortDescriptor;
class RLMClassInfo;

extern NSString * const RLMPropertiesComparisonTypeMismatchException;
extern NSString * const RLMUnsupportedTypesFoundInPropertyComparisonException;

realm::Query RLMPredicateToQuery(NSPredicate *predicate, RLMObjectSchema *objectSchema,
RLMSchema *schema, realm::Group &group);

Expand Down
6 changes: 1 addition & 5 deletions Realm/RLMQueryUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,9 @@

using namespace realm;

namespace {
NSString * const RLMPropertiesComparisonTypeMismatchException = @"RLMPropertiesComparisonTypeMismatchException";
NSString * const RLMUnsupportedTypesFoundInPropertyComparisonException = @"RLMUnsupportedTypesFoundInPropertyComparisonException";

NSString * const RLMPropertiesComparisonTypeMismatchReason = @"Property type mismatch between %@ and %@";
NSString * const RLMUnsupportedTypesFoundInPropertyComparisonReason = @"Comparison between %@ and %@";

namespace {

// small helper to create the many exceptions thrown when parsing predicates
[[gnu::cold]] [[noreturn]]
Expand Down
10 changes: 9 additions & 1 deletion Realm/RLMRealm.mm
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,14 @@ - (RLMRealmConfiguration *)configuration {
return configuration;
}

- (RLMRealmConfiguration *)configurationSharingSchema {
RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init];
configuration.configRef = _realm->config();
configuration.dynamic = _dynamic;
[configuration setCustomSchemaWithoutCopying:_schema];
return configuration;
}

- (void)beginWriteTransaction {
[self beginWriteTransactionWithError:nil];
}
Expand Down Expand Up @@ -1076,7 +1084,7 @@ - (RLMRealm *)freeze {

- (RLMRealm *)thaw {
[self verifyThread];
return self.isFrozen ? [RLMRealm realmWithConfiguration:self.configuration error:nil] : self;
return self.isFrozen ? [RLMRealm realmWithConfiguration:self.configurationSharingSchema error:nil] : self;
}

- (RLMRealm *)frozenCopy {
Expand Down
2 changes: 1 addition & 1 deletion Realm/RLMRealmUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ @implementation RLMPinnedRealm {
- (instancetype)initWithRealm:(RLMRealm *)realm {
if (self = [super init]) {
_pin = realm->_realm->duplicate();
_configuration = realm.configuration;
_configuration = realm.configurationSharingSchema;
}
return self;
}
Expand Down
5 changes: 5 additions & 0 deletions Realm/RLMRealm_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ FOUNDATION_EXTERN void RLMRealmSubscribeToAll(RLMRealm *);
@property (nonatomic, readonly, nullable) id actor;
@property (nonatomic, readonly) bool isFlexibleSync;

// `-configuration` does a deep copy of the schema as if the user mutates the
// RLMSchema in use by a RLMRealm things will break horribly. When we know that
// the configuration won't be exposed we can skip the copy.
- (RLMRealmConfiguration *)configurationSharingSchema NS_RETURNS_RETAINED;

+ (void)resetRealmState;

- (void)registerEnumerator:(RLMFastEnumerator *)enumerator;
Expand Down
2 changes: 1 addition & 1 deletion Realm/RLMResults.mm
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ - (void)completionWithThreadSafeReference:(RLMThreadSafeReference * _Nullable)re
confinedTo:(RLMScheduler *)confinement
completion:(RLMResultsCompletionBlock)completion
error:(NSError *_Nullable)error {
RLMRealmConfiguration *configuration = _realm.configuration;
RLMRealmConfiguration *configuration = _realm.configurationSharingSchema;
[confinement invoke:^{
if (error) {
return completion(nil, error);
Expand Down
9 changes: 8 additions & 1 deletion Realm/Swift/RLMSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ extension RLMObject {
}

/// A protocol defining iterator support for RLMArray, RLMSet & RLMResults.
public protocol _RLMCollectionIterator {
public protocol _RLMCollectionIterator: Sequence {
/**
Returns a `RLMCollectionIterator` that yields successive elements in the collection.
This enables support for sequence-style enumeration of `RLMObject` subclasses in Swift.
Expand Down Expand Up @@ -97,10 +97,17 @@ extension _RLMDictionaryIterator where Self: RLMCollection {

// Sequence conformance for RLMArray, RLMDictionary, RLMSet and RLMResults is provided by RLMCollection's
// `makeIterator()` implementation.
#if compiler(<6.0)
extension RLMArray: Sequence, _RLMCollectionIterator { }
extension RLMDictionary: Sequence, _RLMDictionaryIterator {}
extension RLMSet: Sequence, _RLMCollectionIterator {}
extension RLMResults: Sequence, _RLMCollectionIterator {}
#else
extension RLMArray: @retroactive Sequence, _RLMCollectionIterator { }
extension RLMDictionary: @retroactive Sequence, _RLMDictionaryIterator {}
extension RLMSet: @retroactive Sequence, _RLMCollectionIterator {}
extension RLMResults: @retroactive Sequence, _RLMCollectionIterator {}
#endif

/**
This struct enables sequence-style enumeration for RLMObjects in Swift via `RLMCollection.makeIterator`
Expand Down
2 changes: 1 addition & 1 deletion Realm/TestUtils/include/RLMAssertions.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ FOUNDATION_EXTERN bool RLMHasCachedRealmForPath(NSString *path);
#define RLMAssertThrowsWithCodeMatching(expression, expectedCode, ...) \
({ \
NSException *exception = RLMAssertThrows(expression, __VA_ARGS__); \
XCTAssertEqual([exception.userInfo[NSUnderlyingErrorKey] code], expectedCode, __VA_ARGS__); \
XCTAssertEqual([(NSError *)exception.userInfo[NSUnderlyingErrorKey] code], expectedCode, __VA_ARGS__); \
})

#define RLMValidateError(error, errDomain, errCode, msg) do { \
Expand Down
4 changes: 2 additions & 2 deletions Realm/Tests/EncryptionTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ - (void)testReopenWithWrongKeyThrows {
NSData *key = RLMGenerateKey();
RLMAssertRealmExceptionContains([self realmWithKey:key],
RLMErrorInvalidDatabase,
@"Failed to open Realm file at path '%@': Realm file decryption failed (Decryption failed: unable to decrypt after 0 seconds",
@"Failed to open Realm file at path '%@': Realm file decryption failed (Decryption failed: page 0 in file of size",
RLMDefaultRealmURL().path);
}

Expand All @@ -100,7 +100,7 @@ - (void)testOpenUnencryptedWithKeyThrows {
NSData *key = RLMGenerateKey();
RLMAssertRealmExceptionContains([self realmWithKey:key],
RLMErrorInvalidDatabase,
@"Failed to open Realm file at path '%@': Realm file decryption failed (Decryption failed: failed to decrypt block 0 in file of size",
@"Failed to open Realm file at path '%@': Realm file decryption failed (Decryption failed: page 0 in file of size",
RLMDefaultRealmURL().path);
}

Expand Down
Loading

0 comments on commit b30dcd4

Please sign in to comment.