Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/ios.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarinofaggiana <marino@marinofaggiana.com>2020-02-05 14:25:21 +0300
committermarinofaggiana <marino@marinofaggiana.com>2020-02-05 14:25:21 +0300
commitd16225d79ed91d4e07476537b932d8e8eadd4de2 (patch)
tree089461486bfd015d2c937eb7e6e15a5580ac811d /Carthage
parent7ad8fcae881f006715ae218f234ebf1a94c9c507 (diff)
Update DB - fix split view controller - onlyoffice useragent + fix
Diffstat (limited to 'Carthage')
-rw-r--r--Carthage/Checkouts/CocoaLumberjack/.travis.yml1
-rw-r--r--Carthage/Checkouts/CocoaLumberjack/CHANGELOG.md14
-rw-r--r--Carthage/Checkouts/CocoaLumberjack/CocoaLumberjack.podspec2
-rw-r--r--Carthage/Checkouts/realm-cocoa/.jenkins.yml372
-rw-r--r--Carthage/Checkouts/realm-cocoa/CHANGELOG.md86
-rw-r--r--Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig2
-rw-r--r--Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig5
-rw-r--r--Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig5
-rw-r--r--Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability7
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm126
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.h25
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.m44
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.h7
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.mm40
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift42
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftSyncTestCase.swift2
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/test-ros-server.js59
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list4
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/CMakeLists.txt6
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp3
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.cpp24
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.hpp6
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMConstants.h4
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMNetworkClient.mm16
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMObjectBase.mm6
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMPlatform.h.in2
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h77
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm38
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.h9
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.mm127
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration_Private.hpp5
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.h98
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.mm188
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager_Private.h7
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSessionRefreshHandle.mm78
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMSyncUser.mm5
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/RLMUtil.mm21
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist4
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m4
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm85
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Tests/SchemaTests.mm2
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift4
-rw-r--r--Carthage/Checkouts/realm-cocoa/Realm/Tests/TestHost/main.m8
-rw-r--r--Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift39
-rw-r--r--Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift94
-rw-r--r--Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/PerformanceTests.swift2
-rw-r--r--Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift9
-rwxr-xr-xCarthage/Checkouts/realm-cocoa/build.sh46
-rw-r--r--Carthage/Checkouts/realm-cocoa/dependencies.list6
-rwxr-xr-xCarthage/Checkouts/realm-cocoa/scripts/generate-rlmplatform.sh7
-rwxr-xr-xCarthage/Checkouts/realm-cocoa/scripts/package_examples.rb2
51 files changed, 1435 insertions, 440 deletions
diff --git a/Carthage/Checkouts/CocoaLumberjack/.travis.yml b/Carthage/Checkouts/CocoaLumberjack/.travis.yml
index ffa3446a1..9c73d2a9a 100644
--- a/Carthage/Checkouts/CocoaLumberjack/.travis.yml
+++ b/Carthage/Checkouts/CocoaLumberjack/.travis.yml
@@ -58,7 +58,6 @@ script:
- xcodebuild clean build -project Integration/Integration.xcodeproj -scheme 'watchOSSwiftIntegration' -configuration Release -sdk watchsimulator -destination 'platform=iOS Simulator,name=iPhone 11 Pro' | xcpretty -c
- echo "Run the tests"
- - xcodebuild test -skip-testing:'iOS Tests/DDFileLoggerPerformanceTests' -project Tests/Tests.xcodeproj -scheme 'iOS Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.3.1' GCC_GENERATE_TEST_COVERAGE_FILES=YES | xcpretty -c
- xcodebuild test -skip-testing:'iOS Tests/DDFileLoggerPerformanceTests' -project Tests/Tests.xcodeproj -scheme 'iOS Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11 Pro,OS=latest' GCC_GENERATE_TEST_COVERAGE_FILES=YES | xcpretty -c
- xcodebuild test -skip-testing:'OS X Tests/DDFileLoggerPerformanceTests' -project Tests/Tests.xcodeproj -scheme 'OS X Tests' -sdk macosx GCC_GENERATE_TEST_COVERAGE_FILES=YES | xcpretty -c
diff --git a/Carthage/Checkouts/CocoaLumberjack/CHANGELOG.md b/Carthage/Checkouts/CocoaLumberjack/CHANGELOG.md
index ec0009e14..9d6cf60bb 100644
--- a/Carthage/Checkouts/CocoaLumberjack/CHANGELOG.md
+++ b/Carthage/Checkouts/CocoaLumberjack/CHANGELOG.md
@@ -1,3 +1,17 @@
+## [3.6.1 - Xcode 11.3.1 on Jan 25th, 2020](https://github.com/CocoaLumberjack/CocoaLumberjack/releases/tag/3.6.1)
+
+### Public
+- Improve error handling during log file creation in DDFileLogger & DDLogFileManager (#1103 / #1111)
+- Improve nullability annotations in public headers (#1111 / #1112 / #1119)
+- Added support for thread QOS in DDLogMessage class (#1124)
+
+### Internal
+- Fix rolling timer being rescheduled rapidly due to leeway (#1106 / #1107)
+- Fix -didArchiveLogFile: returning the file name instead of the file path (#1078)
+- Fix setxattr() function usage (#1118)
+- Fix NSDateFormatter thread safety (#1121)
+- Fix -lt_dataForMessage: duplicated code (#1122)
+
## [3.6.0 - Xcode 11 on October 2nd, 2019](https://github.com/CocoaLumberjack/CocoaLumberjack/releases/tag/3.6.0)
### Public
diff --git a/Carthage/Checkouts/CocoaLumberjack/CocoaLumberjack.podspec b/Carthage/Checkouts/CocoaLumberjack/CocoaLumberjack.podspec
index 0f04f1dda..c7e196c9a 100644
--- a/Carthage/Checkouts/CocoaLumberjack/CocoaLumberjack.podspec
+++ b/Carthage/Checkouts/CocoaLumberjack/CocoaLumberjack.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'CocoaLumberjack'
- s.version = '3.6.0'
+ s.version = '3.6.1'
s.license = 'BSD'
s.summary = 'A fast & simple, yet powerful & flexible logging framework for Mac and iOS.'
s.homepage = 'https://github.com/CocoaLumberjack/CocoaLumberjack'
diff --git a/Carthage/Checkouts/realm-cocoa/.jenkins.yml b/Carthage/Checkouts/realm-cocoa/.jenkins.yml
index 0097ef2ad..864ef1c25 100644
--- a/Carthage/Checkouts/realm-cocoa/.jenkins.yml
+++ b/Carthage/Checkouts/realm-cocoa/.jenkins.yml
@@ -6,10 +6,10 @@
xcode_version:
- 10.0
- 10.1
- - 10.2.1
- 10.3
- 11.1
- - 11.2
+ - 11.2.1
+ - 11.3
target:
- docs
- swiftlint
@@ -20,9 +20,11 @@ target:
- ios-dynamic
- watchos
- tvos
- - ios-swift
- osx-swift
+ - ios-swift
- tvos-swift
+ - catalyst
+ - catalyst-swift
- cocoapods-osx
- cocoapods-ios
- cocoapods-ios-dynamic
@@ -52,31 +54,31 @@ exclude:
target: docs
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: docs
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: docs
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: docs
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: docs
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: docs
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: docs
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: docs
configuration: Debug
@@ -96,31 +98,31 @@ exclude:
target: swiftlint
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftlint
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftlint
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftlint
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftlint
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftlint
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftlint
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: swiftlint
configuration: Debug
@@ -136,31 +138,31 @@ exclude:
target: osx-encryption
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: osx-encryption
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: osx-encryption
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: osx-encryption
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: osx-encryption
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: osx-encryption
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: osx-encryption
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: osx-encryption
configuration: Debug
@@ -176,31 +178,31 @@ exclude:
target: osx-object-server
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: osx-object-server
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: osx-object-server
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: osx-object-server
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: osx-object-server
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: osx-object-server
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: osx-object-server
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: osx-object-server
configuration: Debug
@@ -212,16 +214,36 @@ exclude:
target: ios-static
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: ios-static
+ configuration: Release
+
+ - xcode_version: 10.3
target: ios-static
configuration: Debug
- xcode_version: 10.3
target: ios-static
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: ios-static
configuration: Debug
- xcode_version: 11.1
target: ios-static
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: ios-static
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: ios-static
+ configuration: Release
+
+ - xcode_version: 11.3
+ target: ios-static
configuration: Debug
- xcode_version: 10.0
@@ -232,16 +254,36 @@ exclude:
target: ios-dynamic
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: ios-dynamic
+ configuration: Release
+
+ - xcode_version: 10.3
target: ios-dynamic
configuration: Debug
- xcode_version: 10.3
target: ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: ios-dynamic
configuration: Debug
- xcode_version: 11.1
target: ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: ios-dynamic
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.3
+ target: ios-dynamic
configuration: Debug
- xcode_version: 10.0
@@ -252,16 +294,36 @@ exclude:
target: watchos
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: watchos
+ configuration: Release
+
+ - xcode_version: 10.3
target: watchos
configuration: Debug
- xcode_version: 10.3
target: watchos
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: watchos
configuration: Debug
- xcode_version: 11.1
target: watchos
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: watchos
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: watchos
+ configuration: Release
+
+ - xcode_version: 11.3
+ target: watchos
configuration: Debug
- xcode_version: 10.0
@@ -272,16 +334,36 @@ exclude:
target: tvos
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: tvos
+ configuration: Release
+
+ - xcode_version: 10.3
target: tvos
configuration: Debug
- xcode_version: 10.3
target: tvos
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: tvos
configuration: Debug
- xcode_version: 11.1
target: tvos
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: tvos
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: tvos
+ configuration: Release
+
+ - xcode_version: 11.3
+ target: tvos
configuration: Debug
- xcode_version: 10.0
@@ -292,67 +374,147 @@ exclude:
target: ios-swift
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: ios-swift
+ configuration: Release
+
+ - xcode_version: 10.3
target: ios-swift
configuration: Debug
- xcode_version: 10.3
target: ios-swift
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: ios-swift
configuration: Debug
- xcode_version: 11.1
target: ios-swift
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: ios-swift
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: ios-swift
+ configuration: Release
+
+ - xcode_version: 11.3
+ target: ios-swift
configuration: Debug
- xcode_version: 10.0
- target: osx-swift
+ target: tvos-swift
configuration: Debug
- xcode_version: 10.1
- target: osx-swift
+ target: tvos-swift
configuration: Debug
- - xcode_version: 10.2.1
- target: osx-swift
- configuration: Debug
+ - xcode_version: 10.1
+ target: tvos-swift
+ configuration: Release
- xcode_version: 10.3
- target: osx-swift
+ target: tvos-swift
configuration: Debug
+ - xcode_version: 10.3
+ target: tvos-swift
+ configuration: Release
+
- xcode_version: 11.1
- target: osx-swift
+ target: tvos-swift
configuration: Debug
- - xcode_version: 10.0
+ - xcode_version: 11.1
target: tvos-swift
- configuration: Debug
+ configuration: Release
- - xcode_version: 10.1
+ - xcode_version: 11.2.1
target: tvos-swift
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 11.2.1
+ target: tvos-swift
+ configuration: Release
+
+ - xcode_version: 11.3
target: tvos-swift
configuration: Debug
+ - xcode_version: 10.0
+ target: catalyst
+ configuration: Debug
+
+ - xcode_version: 10.0
+ target: catalyst
+ configuration: Release
+
+ - xcode_version: 10.1
+ target: catalyst
+ configuration: Debug
+
+ - xcode_version: 10.1
+ target: catalyst
+ configuration: Release
+
- xcode_version: 10.3
- target: tvos-swift
+ target: catalyst
configuration: Debug
+ - xcode_version: 10.3
+ target: catalyst
+ configuration: Release
+
- xcode_version: 11.1
- target: tvos-swift
+ target: catalyst
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: catalyst
configuration: Debug
- xcode_version: 10.0
- target: cocoapods-osx
+ target: catalyst-swift
+ configuration: Debug
+
+ - xcode_version: 10.0
+ target: catalyst-swift
+ configuration: Release
+
+ - xcode_version: 10.1
+ target: catalyst-swift
configuration: Debug
- xcode_version: 10.1
+ target: catalyst-swift
+ configuration: Release
+
+ - xcode_version: 10.3
+ target: catalyst-swift
+ configuration: Debug
+
+ - xcode_version: 10.3
+ target: catalyst-swift
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: catalyst-swift
+ configuration: Debug
+
+ - xcode_version: 11.2.1
+ target: catalyst-swift
+ configuration: Debug
+
+ - xcode_version: 10.0
target: cocoapods-osx
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
target: cocoapods-osx
configuration: Debug
@@ -364,7 +526,11 @@ exclude:
target: cocoapods-osx
configuration: Debug
- - xcode_version: 11.2
+ - xcode_version: 11.2.1
+ target: cocoapods-osx
+ configuration: Debug
+
+ - xcode_version: 11.3
target: cocoapods-osx
configuration: Debug
@@ -376,19 +542,35 @@ exclude:
target: cocoapods-ios
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: cocoapods-ios
+ configuration: Release
+
+ - xcode_version: 10.3
target: cocoapods-ios
configuration: Debug
- xcode_version: 10.3
target: cocoapods-ios
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: cocoapods-ios
configuration: Debug
- xcode_version: 11.1
target: cocoapods-ios
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: cocoapods-ios
configuration: Debug
- - xcode_version: 11.2
+ - xcode_version: 11.2.1
+ target: cocoapods-ios
+ configuration: Release
+
+ - xcode_version: 11.3
target: cocoapods-ios
configuration: Debug
@@ -400,19 +582,35 @@ exclude:
target: cocoapods-ios-dynamic
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: cocoapods-ios-dynamic
+ configuration: Release
+
+ - xcode_version: 10.3
target: cocoapods-ios-dynamic
configuration: Debug
- xcode_version: 10.3
target: cocoapods-ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: cocoapods-ios-dynamic
configuration: Debug
- xcode_version: 11.1
target: cocoapods-ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: cocoapods-ios-dynamic
configuration: Debug
- - xcode_version: 11.2
+ - xcode_version: 11.2.1
+ target: cocoapods-ios-dynamic
+ configuration: Release
+
+ - xcode_version: 11.3
target: cocoapods-ios-dynamic
configuration: Debug
@@ -424,19 +622,35 @@ exclude:
target: cocoapods-watchos
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.1
+ target: cocoapods-watchos
+ configuration: Release
+
+ - xcode_version: 10.3
target: cocoapods-watchos
configuration: Debug
- xcode_version: 10.3
target: cocoapods-watchos
+ configuration: Release
+
+ - xcode_version: 11.1
+ target: cocoapods-watchos
configuration: Debug
- xcode_version: 11.1
target: cocoapods-watchos
+ configuration: Release
+
+ - xcode_version: 11.2.1
+ target: cocoapods-watchos
configuration: Debug
- - xcode_version: 11.2
+ - xcode_version: 11.2.1
+ target: cocoapods-watchos
+ configuration: Release
+
+ - xcode_version: 11.3
target: cocoapods-watchos
configuration: Debug
@@ -456,27 +670,19 @@ exclude:
target: swiftpm
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftpm
configuration: Debug
- - xcode_version: 10.2.1
- target: swiftpm
- configuration: Release
-
- xcode_version: 10.3
target: swiftpm
- configuration: Debug
+ configuration: Release
- xcode_version: 11.1
target: swiftpm
configuration: Debug
- - xcode_version: 11.1
- target: swiftpm
- configuration: Release
-
- - xcode_version: 11.2
+ - xcode_version: 11.2.1
target: swiftpm
configuration: Debug
@@ -496,31 +702,31 @@ exclude:
target: swiftpm-address
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftpm-address
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftpm-address
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftpm-address
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftpm-address
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftpm-address
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftpm-address
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: swiftpm-address
configuration: Debug
@@ -540,30 +746,30 @@ exclude:
target: swiftpm-thread
configuration: Release
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftpm-thread
configuration: Debug
- - xcode_version: 10.2.1
+ - xcode_version: 10.3
target: swiftpm-thread
configuration: Release
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftpm-thread
configuration: Debug
- - xcode_version: 10.3
+ - xcode_version: 11.1
target: swiftpm-thread
configuration: Release
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftpm-thread
configuration: Debug
- - xcode_version: 11.1
+ - xcode_version: 11.2.1
target: swiftpm-thread
configuration: Release
- - xcode_version: 11.2
+ - xcode_version: 11.3
target: swiftpm-thread
configuration: Debug
diff --git a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md
index a0052b131..e918effe7 100644
--- a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md
+++ b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md
@@ -1,3 +1,89 @@
+4.3.1 Release notes (2020-01-16)
+=============================================================
+
+### Enhancements
+
+* Reduce the encrypted page reclaimer's impact on battery life when encryption
+ is used. ([Core #3461](https://github.com/realm/realm-core/pull/3461)).
+
+### Fixed
+
+* macOS binaries were built with the incorrect deployment target (10.14 rather
+ than 10.9), resulting in linker warnings. ([#6299](https://github.com/realm/realm-cocoa/issues/6299), since 3.18.0).
+* An internal datastructure for List properties could be double-deleted if the
+ last reference was released from a thread other than the one which the List
+ was created on at the wrong time. This would typically manifest as
+ "pthread_mutex_destroy() failed", but could also result in other kinds of
+ crashes. ([#6333](https://github.com/realm/realm-cocoa/issues/6333)).
+* Sorting on float or double properties containing NaN values had inconsistent
+ results and would sometimes crash due to out-of-bounds memory accesses.
+ ([#6357](https://github.com/realm/realm-cocoa/issues/6357)).
+* A NOT query on a `List<Object>` which happened to have the objects in a
+ different order than the underlying table would sometimes include the object
+ immediately before an object which matches the query. ([#6289](https://github.com/realm/realm-cocoa/issues/6289), since 0.90.0).
+
+### Compatibility
+
+* File format: Generates Realms with format v9 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Carthage release for Swift is built with Xcode 11.3.
+
+### Internal
+
+* Upgraded realm-core from 5.23.6 to 5.23.8.
+* Upgraded realm-sync from 4.9.0 to 4.9.4.
+
+4.3.0 Release notes (2019-12-19)
+=============================================================
+
+### Enhancements
+
+* Add the ability to set a custom logger function on `RLMSyncManager` which is
+ called instead of the default NSLog-based logger.
+* Expose configuration options for the various types of sync connection
+ timeouts and heartbeat intervals on `RLMSyncManager`.
+* Add an option to have `Realm.asyncOpen()` report an error if the connection
+ times out rather than swallowing the error and attempting to reconnect until
+ it succeeds.
+
+### Fixed
+
+* Fix a crash when using value(forKey:) on a LinkingObjects property (including
+ when doing so indirectly, such as by querying on that property).
+ ([#6366](https://github.com/realm/realm-cocoa/issues/6366), since 4.0.0).
+* Fix a rare crash in `ClientHistoryImpl::integrate_server_changesets()` which
+ would only happen in Debug builds (since v3.0.0).
+
+### Compatibility
+
+* File format: Generates Realms with format v9 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Carthage release for Swift is built with Xcode 11.3.
+
+### Internal
+
+* Upgraded realm-sync from 4.8.2 to 4.9.0.
+
+4.2.0 Release notes (2019-12-16)
+=============================================================
+
+### Enhancements
+
+* Add `-[RLMRealm fileExistsForConfiguration:]`/`Realm.fileExists(for:)`,
+ which checks if a local Realm file exists for the given configuration.
+* Add `-[RLMRealm deleteFilesForConfiguration:]`/`Realm.deleteFiles(for:)`
+ to delete the Realm file and all auxiliary files for the given configuration.
+
+### Fixed
+
+* None.
+
+### Compatibility
+
+* File format: Generates Realms with format v9 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Carthage release for Swift is built with Xcode 11.3.
+
4.1.1 Release notes (2019-11-18)
=============================================================
diff --git a/Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig b/Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig
index f4266e6b7..4405fcd10 100644
--- a/Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig
+++ b/Carthage/Checkouts/realm-cocoa/Configuration/Base.xcconfig
@@ -61,3 +61,5 @@ WATCHOS_DEPLOYMENT_TARGET = 2.0;
TVOS_DEPLOYMENT_TARGET = 9.0;
SWIFT_VERSION = 4.0;
+TARGETED_DEVICE_FAMILY = 1,2,3,4;
+SDKROOT = $(REALM_SDKROOT);
diff --git a/Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig b/Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig
index e293c34d2..38cc2fdca 100644
--- a/Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig
+++ b/Carthage/Checkouts/realm-cocoa/Configuration/Realm/Realm.xcconfig
@@ -28,7 +28,10 @@ LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks
LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
-REALM_PLATFORM_SUFFIX = $(PLATFORM_NAME);
+REALM_PLATFORM_SUFFIX_ = $(PLATFORM_NAME); // Xcode 10 does not define SDK_VARIANT
+REALM_PLATFORM_SUFFIX_macos = macosx;
+REALM_PLATFORM_SUFFIX_iosmac = maccatalyst;
+REALM_PLATFORM_SUFFIX = $(REALM_PLATFORM_SUFFIX_$(SDK_VARIANT));
OTHER_LDFLAGS[sdk=macosx*] = -lrealm-$(REALM_PLATFORM_SUFFIX)$(REALM_LIBRARY_SUFFIX) $(REALM_CATALYST_FLAGS);
OTHER_LIBTOOLFLAGS[sdk=macosx*] = -lrealm-$(REALM_PLATFORM_SUFFIX)$(REALM_LIBRARY_SUFFIX) $(REALM_CATALYST_FLAGS);
OTHER_LDFLAGS[sdk=iphone*] = -lrealm-ios$(REALM_LIBRARY_SUFFIX);
diff --git a/Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig b/Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig
index d8b905a3b..c8cc93fc3 100644
--- a/Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig
+++ b/Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig
@@ -11,9 +11,12 @@ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
PRODUCT_BUNDLE_IDENTIFIER = io.realm.TestHost;
+REALM_UI_FRAMEWORK_ = Cocoa;
+REALM_UI_FRAMEWORK_uikit = UIKit;
+
OTHER_LDFLAGS[sdk=iphone*] = -framework UIKit;
OTHER_LDFLAGS[sdk=appletv*] = -framework UIKit;
-OTHER_LDFLAGS[sdk=macosx*] = -framework Cocoa;
+OTHER_LDFLAGS[sdk=macosx*] = -framework $(REALM_UI_FRAMEWORK_$(RESOURCES_UI_FRAMEWORK_FAMILY));
PRINCIPAL_CLASS[sdk=iphone*] = UIApplication;
PRINCIPAL_CLASS[sdk=appletv*] = UIApplication;
diff --git a/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability b/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability
index da57f86de..07889287b 100644
--- a/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability
+++ b/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability
@@ -1,10 +1,10 @@
-xcodeVersions = ['10.0', '10.1', '10.2.1', '10.3', '11.1', '11.2']
+xcodeVersions = ['10.0', '10.1', '10.3', '11.1', '11.2.1', '11.3']
platforms = ['osx', 'ios', 'watchos', 'tvos', 'catalyst']
carthagePlatforms = ['osx', 'ios', 'watchos', 'tvos']
platformNames = ['osx': 'macOS', 'ios': 'iOS', 'watchos': 'watchOS', 'tvos': 'tvOS', 'catalyst': 'Catalyst']
-carthageXcodeVersion = '11.2'
+carthageXcodeVersion = '11.3'
objcXcodeVersion = '10.1'
-docsSwiftVersion = '5.1'
+docsSwiftVersion = '5.1.2'
def installationTest(platform, test, language) {
return {
@@ -65,6 +65,7 @@ def doBuild() {
unstash 'source'
sh """
export REALM_SWIFT_VERSION=${docsSwiftVersion}
+ export PATH='/Users/realm/.rbenv/bin:/Users/realm/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/realm/.gems/bin'
./scripts/reset-simulators.sh
./build.sh docs
cd docs
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm
index 17ed01203..fc403b9ac 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm
@@ -219,10 +219,11 @@
__block XCTestExpectation *ex;
[RLMSyncSessionRefreshHandle calculateFireDateUsingTestLogic:YES
blockOnRefreshCompletion:^(BOOL success) {
- XCTAssertTrue(success);
- refreshCount++;
- [ex fulfill];
- }];
+ XCTAssertTrue(success);
+ if (refreshCount++ == 3) { // arbitrary choice; refreshes every second
+ [ex fulfill];
+ }
+ }];
// Open the Realm.
NSURL *url = REALM_URL();
RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
@@ -232,7 +233,91 @@
ex = [self expectationWithDescription:@"Timer fired"];
[self waitForExpectationsWithTimeout:10 handler:nil];
XCTAssertTrue(errorCount == 0);
- XCTAssertTrue(refreshCount > 0);
+ XCTAssertTrue(refreshCount >= 4);
+}
+
+- (void)testLoginConnectionTimeoutFromManager {
+ // First create the user, talking directly to ROS
+ NSString *userName = NSStringFromSelector(_cmd);
+ @autoreleasepool {
+ RLMSyncCredentials *credentials = [RLMObjectServerTests basicCredentialsWithName:userName register:YES];
+ RLMSyncUser *user = [self logInUserForCredentials:credentials server:[NSURL URLWithString:@"http://127.0.0.1:9080"]];
+ [user logOut];
+ }
+
+ RLMSyncTimeoutOptions *timeoutOptions = [RLMSyncTimeoutOptions new];
+
+ // 9082 is a proxy which delays responding to requests
+ NSURL *authURL = [NSURL URLWithString:@"http://127.0.0.1:9082"];
+
+ // Login attempt should time out
+ timeoutOptions.connectTimeout = 1000.0;
+ RLMSyncManager.sharedManager.timeoutOptions = timeoutOptions;
+
+ RLMSyncCredentials *credentials = [RLMObjectServerTests basicCredentialsWithName:userName register:NO];
+ XCTestExpectation *ex = [self expectationWithDescription:@"Login should time out"];
+ [RLMSyncUser logInWithCredentials:credentials authServerURL:authURL
+ onCompletion:^(RLMSyncUser *user, NSError *error) {
+ XCTAssertNil(user);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, NSURLErrorDomain);
+ XCTAssertEqual(error.code, NSURLErrorTimedOut);
+ [ex fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
+
+ // Login attempt should succeeed
+ timeoutOptions.connectTimeout = 3000.0;
+ RLMSyncManager.sharedManager.timeoutOptions = timeoutOptions;
+
+ ex = [self expectationWithDescription:@"Login should succeed"];
+ [RLMSyncUser logInWithCredentials:credentials authServerURL:authURL
+ onCompletion:^(RLMSyncUser *user, NSError *error) {
+ [user logOut];
+ XCTAssertNotNil(user);
+ XCTAssertNil(error);
+ [ex fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:3.0 handler:nil];
+}
+
+- (void)testLoginConnectionTimeoutDirect {
+ // First create the user, talking directly to ROS
+ NSString *userName = NSStringFromSelector(_cmd);
+ @autoreleasepool {
+ RLMSyncCredentials *credentials = [RLMObjectServerTests basicCredentialsWithName:userName register:YES];
+ RLMSyncUser *user = [self logInUserForCredentials:credentials server:[NSURL URLWithString:@"http://127.0.0.1:9080"]];
+ [user logOut];
+ }
+
+ // 9082 is a proxy which delays responding to requests
+ NSURL *authURL = [NSURL URLWithString:@"http://127.0.0.1:9082"];
+
+ // Login attempt should time out
+ RLMSyncCredentials *credentials = [RLMObjectServerTests basicCredentialsWithName:userName register:NO];
+ XCTestExpectation *ex = [self expectationWithDescription:@"Login should time out"];
+ [RLMSyncUser logInWithCredentials:credentials authServerURL:authURL
+ timeout:1.0 callbackQueue:dispatch_get_main_queue()
+ onCompletion:^(RLMSyncUser *user, NSError *error) {
+ XCTAssertNil(user);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, NSURLErrorDomain);
+ XCTAssertEqual(error.code, NSURLErrorTimedOut);
+ [ex fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
+
+ // Login attempt should succeeed
+ ex = [self expectationWithDescription:@"Login should succeed"];
+ [RLMSyncUser logInWithCredentials:credentials authServerURL:authURL
+ timeout:3.0 callbackQueue:dispatch_get_main_queue()
+ onCompletion:^(RLMSyncUser *user, NSError *error) {
+ [user logOut];
+ XCTAssertNotNil(user);
+ XCTAssertNil(error);
+ [ex fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:3.0 handler:nil];
}
#pragma mark - Users
@@ -1662,6 +1747,34 @@ static const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
[self waitForExpectationsWithTimeout:2.0 handler:nil];
}
+- (void)testAsyncOpenConnectionTimeout {
+ NSString *userName = NSStringFromSelector(_cmd);
+ // 9083 is a proxy which delays responding to requests
+ NSURL *authURL = [NSURL URLWithString:@"http://127.0.0.1:9083"];
+ RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:userName register:YES]
+ server:authURL];
+ RLMRealmConfiguration *c = [user configuration];
+ RLMSyncConfiguration *syncConfig = c.syncConfiguration;
+ syncConfig.cancelAsyncOpenOnNonFatalErrors = true;
+ c.syncConfiguration = syncConfig;
+
+ RLMSyncTimeoutOptions *timeoutOptions = [RLMSyncTimeoutOptions new];
+ timeoutOptions.connectTimeout = 1000.0;
+ RLMSyncManager.sharedManager.timeoutOptions = timeoutOptions;
+
+ XCTestExpectation *ex = [self expectationWithDescription:@"async open"];
+ [RLMRealm asyncOpenWithConfiguration:c
+ callbackQueue:dispatch_get_main_queue()
+ callback:^(RLMRealm *realm, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqual(error.code, ETIMEDOUT);
+ XCTAssertEqual(error.domain, NSPOSIXErrorDomain);
+ XCTAssertNil(realm);
+ [ex fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:10.0 handler:nil];
+}
+
#pragma mark - Compact on Launch
- (void)testCompactOnLaunch {
@@ -2150,8 +2263,6 @@ static NSURL *certificateURL(NSString *filename) {
}
- (void)verifyOpenFails:(RLMRealmConfiguration *)config {
- [self openRealmWithConfiguration:config];
-
XCTestExpectation *expectation = [self expectationWithDescription:@"wait for error"];
RLMSyncManager.sharedManager.errorHandler = ^(NSError *error, __unused RLMSyncSession *session) {
XCTAssertTrue([error.domain isEqualToString:RLMSyncErrorDomain]);
@@ -2159,6 +2270,7 @@ static NSURL *certificateURL(NSString *filename) {
[expectation fulfill];
};
+ [self openRealmWithConfiguration:config];
[self waitForExpectationsWithTimeout:20.0 handler:nil];
}
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.h b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.h
deleted file mode 100644
index cf914be0a..000000000
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.h
+++ /dev/null
@@ -1,25 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2016 Realm Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////
-
-#import "RLMSyncManager.h"
-
-@interface RLMSyncManager (ObjectServerTests)
-
-- (void)prepareForDestruction;
-
-@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.m b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.m
deleted file mode 100644
index 46746c8df..000000000
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncManager+ObjectServerTests.m
+++ /dev/null
@@ -1,44 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2016 Realm Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////
-
-#import "RLMSyncManager_Private.h"
-#import "RLMSyncManager+ObjectServerTests.h"
-#import "RLMSyncTestCase.h"
-#import "RLMTestUtils.h"
-
-@interface RLMSyncManager ()
-- (NSArray<RLMSyncUser *> *)_allUsers;
-@end
-
-@implementation RLMSyncManager (ObjectServerTests)
-
-+ (void)load {
- RLMSwapOutClassMethod(self, @selector(sharedManager), @selector(ost_sharedManager));
-}
-
-+ (instancetype)ost_sharedManager {
- return [RLMSyncTestCase managerForCurrentTest];
-}
-
-- (void)prepareForDestruction {
- // Log out all the logged-in users.
- [[self _allUsers] makeObjectsPerformSelector:@selector(logOut)];
- [RLMSyncManager resetForTesting];
-}
-
-@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.h b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.h
index 1723c51c9..42a23fbdc 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.h
@@ -24,7 +24,7 @@ typedef void(^RLMSyncBasicErrorReportingBlock)(NSError * _Nullable);
NS_ASSUME_NONNULL_BEGIN
@interface RLMSyncManager ()
-- (void)setSessionCompletionNotifier:(RLMSyncBasicErrorReportingBlock)sessionCompletionNotifier;
+- (void)setSessionCompletionNotifier:(nullable RLMSyncBasicErrorReportingBlock)sessionCompletionNotifier;
@end
@interface SyncObject : RLMObject
@@ -38,8 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface RLMSyncTestCase : RLMMultiProcessTestCase
-+ (RLMSyncManager *)managerForCurrentTest;
-
+ (NSURL *)authServerURL;
+ (NSURL *)secureAuthServerURL;
@@ -125,6 +123,9 @@ NS_ASSUME_NONNULL_BEGIN
/// Manually set the refresh token for a user. Used for testing invalid token conditions.
- (void)manuallySetRefreshTokenForUser:(RLMSyncUser *)user value:(NSString *)tokenValue;
+- (void)setupSyncManager;
+- (void)resetSyncManager;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.mm b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.mm
index f78648425..d114d0597 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncTestCase.mm
@@ -24,7 +24,7 @@
#import "RLMRealm_Dynamic.h"
#import "RLMRealm_Private.hpp"
#import "RLMRealmConfiguration_Private.h"
-#import "RLMSyncManager+ObjectServerTests.h"
+#import "RLMSyncManager_Private.h"
#import "RLMSyncSessionRefreshHandle+ObjectServerTests.h"
#import "RLMSyncConfiguration_Private.h"
#import "RLMUtil.hpp"
@@ -53,7 +53,8 @@ static NSString *nodePath() {
@interface RLMSyncManager ()
+ (void)_setCustomBundleID:(NSString *)customBundleID;
-- (instancetype)initWithCustomRootDirectory:(NSURL *)rootDirectory;
+- (void)configureWithRootDirectory:(NSURL *)rootDirectory;
+- (NSArray<RLMSyncUser *> *)_allUsers;
@end
@interface RLMSyncTestCase ()
@@ -90,7 +91,6 @@ static NSString *nodePath() {
@end
static NSTask *s_task;
-static RLMSyncManager *s_managerForTest;
static NSURL *syncDirectoryForChildProcess() {
NSString *path = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
@@ -240,10 +240,6 @@ static NSURL *syncDirectoryForChildProcess() {
@implementation RLMSyncTestCase
-+ (RLMSyncManager *)managerForCurrentTest {
- return s_managerForTest;
-}
-
#pragma mark - Helper methods
- (BOOL)isPartial {
@@ -323,6 +319,7 @@ static NSURL *syncDirectoryForChildProcess() {
// Wait for login to succeed or fail.
XCTAssert(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC))) == 0,
@"Timed out while trying to asynchronously open Realm for URL: %@", url);
+ RLMSyncManager.sharedManager.sessionCompletionNotifier = nil;
return realm;
}
@@ -512,6 +509,19 @@ static NSURL *syncDirectoryForChildProcess() {
- (void)setUp {
[super setUp];
self.continueAfterFailure = NO;
+
+ REALM_ASSERT(RLMSyncManager.sharedManager._allUsers.count == 0);
+ [RLMSyncManager resetForTesting];
+
+ [self setupSyncManager];
+}
+
+- (void)tearDown {
+ [self resetSyncManager];
+ [super tearDown];
+}
+
+- (void)setupSyncManager {
NSURL *clientDataRoot;
if (self.isParent) {
[RealmObjectServer.sharedServer launch];
@@ -520,21 +530,21 @@ static NSURL *syncDirectoryForChildProcess() {
else {
clientDataRoot = syncDirectoryForChildProcess();
}
+
NSError *error;
[NSFileManager.defaultManager removeItemAtURL:clientDataRoot error:&error];
[NSFileManager.defaultManager createDirectoryAtURL:clientDataRoot
withIntermediateDirectories:YES attributes:nil error:&error];
- s_managerForTest = [[RLMSyncManager alloc] initWithCustomRootDirectory:clientDataRoot];
- [RLMSyncManager sharedManager].logLevel = RLMSyncLogLevelOff;
- [RLMSyncManager sharedManager].userAgent = self.name;
+ RLMSyncManager *syncManager = RLMSyncManager.sharedManager;
+ [syncManager configureWithRootDirectory:clientDataRoot];
+ syncManager.logLevel = RLMSyncLogLevelOff;
+ syncManager.userAgent = self.name;
}
-- (void)tearDown {
- [s_managerForTest prepareForDestruction];
- s_managerForTest = nil;
+- (void)resetSyncManager {
+ [RLMSyncManager.sharedManager._allUsers makeObjectsPerformSelector:@selector(logOut)];
+ [RLMSyncManager resetForTesting];
[RLMSyncSessionRefreshHandle calculateFireDateUsingTestLogic:NO blockOnRefreshCompletion:nil];
-
- [super tearDown];
}
@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift
index 1730850ce..24ae51d26 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift
@@ -354,6 +354,48 @@ class SwiftObjectServerTests: SwiftSyncTestCase {
waitForExpectations(timeout: 10.0, handler: nil)
}
+ func testAsyncOpenTimeout() {
+ let syncTimeoutOptions = SyncTimeoutOptions()
+ syncTimeoutOptions.connectTimeout = 3000
+ SyncManager.shared.timeoutOptions = syncTimeoutOptions
+
+ // The server proxy adds a 2 second delay, so a 3 second timeout should succeed
+ autoreleasepool {
+ let user = try! synchronouslyLogInUser(for: basicCredentials(register: true), server: slowConnectAuthURL)
+ let config = user.configuration(cancelAsyncOpenOnNonFatalErrors: true)
+ let ex = expectation(description: "async open")
+ Realm.asyncOpen(configuration: config) { _, error in
+ XCTAssertNil(error)
+ ex.fulfill()
+ }
+ waitForExpectations(timeout: 10.0, handler: nil)
+ user.logOut()
+ }
+
+ self.resetSyncManager()
+ self.setupSyncManager()
+
+ // and a 1 second timeout should fail
+ autoreleasepool {
+ let user = try! synchronouslyLogInUser(for: basicCredentials(register: true), server: slowConnectAuthURL)
+ let config = user.configuration(cancelAsyncOpenOnNonFatalErrors: true)
+
+ syncTimeoutOptions.connectTimeout = 1000
+ SyncManager.shared.timeoutOptions = syncTimeoutOptions
+
+ let ex = expectation(description: "async open")
+ Realm.asyncOpen(configuration: config) { _, error in
+ XCTAssertNotNil(error)
+ if let error = error as NSError? {
+ XCTAssertEqual(error.code, Int(ETIMEDOUT))
+ XCTAssertEqual(error.domain, NSPOSIXErrorDomain)
+ }
+ ex.fulfill()
+ }
+ waitForExpectations(timeout: 4.0, handler: nil)
+ }
+ }
+
// MARK: - Administration
func testRetrieveUserInfo() {
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftSyncTestCase.swift b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftSyncTestCase.swift
index a258dd71c..6c5208d0f 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftSyncTestCase.swift
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftSyncTestCase.swift
@@ -73,6 +73,7 @@ class SwiftSyncTestCase: RLMSyncTestCase {
var task: Process?
let authURL: URL = URL(string: "http://127.0.0.1:9080")!
+ let slowConnectAuthURL: URL = URL(string: "http://127.0.0.1:9083")!
let realmURL: URL = URL(string: "realm://127.0.0.1:9080/~/testBasicSync")!
/// For testing, make a unique Realm URL of the form "realm://127.0.0.1:9080/~/X",
@@ -110,6 +111,7 @@ class SwiftSyncTestCase: RLMSyncTestCase {
SyncManager.shared.setSessionCompletionNotifier(basicBlock)
let realm = try Realm(configuration: configuration)
let result = semaphore.wait(timeout: .now() + DispatchTimeInterval.seconds(20))
+ SyncManager.shared.setSessionCompletionNotifier(nil)
XCTAssertEqual(result, .success)
return realm
}
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/test-ros-server.js b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/test-ros-server.js
index 84e55958b..639357c50 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/test-ros-server.js
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/test-ros-server.js
@@ -48,29 +48,17 @@ class PasswordEmailHandler {
}
}
-// A simple proxy server that runs in front of ROS and validates custom headers
-class HeaderValidationProxy {
+class Proxy {
constructor(listenPort, targetPort) {
this.proxy = httpProxy.createProxyServer({target: `http://127.0.0.1:${targetPort}`, ws: true});
this.proxy.on('error', e => {
console.log('proxy error', e);
});
this.server = http.createServer((req, res) => {
- if (this.validate(req)) {
- this.proxy.web(req, res);
- }
- else {
- res.writeHead(400);
- res.end('Missing X-Allow-Connection header');
- }
+ this.web(req, res);
});
this.server.on('upgrade', (req, socket, head) => {
- if (this.validate(req)) {
- this.proxy.ws(req, socket, head);
- }
- else {
- socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
- }
+ this.ws(req, socket, head);
});
this.server.listen(listenPort);
}
@@ -80,11 +68,50 @@ class HeaderValidationProxy {
this.proxy.close();
}
+ web(req, res) {
+ this.proxy.web(req, res);
+ }
+
+ ws(req, socket, head) {
+ this.proxy.ws(req, socket, head);
+ }
+}
+
+// A simple proxy server that runs in front of ROS and validates custom headers
+class HeaderValidationProxy extends Proxy {
+ web(req, res) {
+ if (this.validate(req)) {
+ this.proxy.web(req, res);
+ }
+ else {
+ res.writeHead(400);
+ res.end('Missing X-Allow-Connection header');
+ }
+ }
+ ws(req, socket, head) {
+ if (this.validate(req)) {
+ this.proxy.ws(req, socket, head);
+ }
+ else {
+ socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
+ }
+ }
validate(req) {
return !!req.headers['x-allow-connection'];
}
}
+// A proxy which sits in front of ROS and takes a long time to establish connections
+class SlowConnectingWebProxy extends Proxy {
+ web(req, res) {
+ setTimeout(() => this.proxy.web(req, res), 2000);
+ }
+}
+class SlowConnectingWsProxy extends Proxy {
+ ws(req, socket, head) {
+ setTimeout(() => this.proxy.ws(req, socket, head), 2000);
+ }
+}
const server = new ROS.BasicServer();
server.start({
@@ -125,3 +152,5 @@ server.start({
console.error(`Error starting Realm Object Server: ${err.message}`)
});
new HeaderValidationProxy(9081, 9080);
+new SlowConnectingWebProxy(9082, 9080);
+new SlowConnectingWsProxy(9083, 9080);
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
index 46ec3efd7..bc76f1f92 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
@@ -1,4 +1,4 @@
-REALM_CORE_VERSION=5.23.5
-REALM_SYNC_VERSION=4.7.8
+REALM_CORE_VERSION=5.23.6
+REALM_SYNC_VERSION=4.9.0
ANDROID_OPENSSL_VERSION=1.0.2k
REALM_CORE_PACKAGING=2
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/CMakeLists.txt b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/CMakeLists.txt
index 95110e9c5..d16398a70 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/CMakeLists.txt
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/CMakeLists.txt
@@ -52,6 +52,12 @@ endif()
add_executable(tests ${SOURCES} ${HEADERS})
target_compile_definitions(tests PRIVATE ${PLATFORM_DEFINES})
+if(VSCODE_TEST_RUNNER)
+ # Increase the Catch2 virtual console width so that the Visual Studio Code
+ # Test Explorer extension can parse long test names
+ target_compile_definitions(tests PRIVATE -DCATCH_CONFIG_CONSOLE_WIDTH=300)
+endif()
+
if(REALM_ENABLE_SYNC)
# It's necessary to explicitly link to realm-sync here to control the order in which libraries are
# linked to avoid link errors when using GNU ld.
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp
index 12c5126fa..244ad13e8 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp
@@ -461,8 +461,7 @@ TEST_CASE("Get Realm using Async Open", "[asyncOpen]") {
if (!util::EventLoop::has_implementation())
return;
- auto cleanup = util::make_scope_exit([=]() noexcept { SyncManager::shared().reset_for_testing(); });
- SyncManager::shared().configure(tmp_dir(), SyncManager::MetadataMode::NoEncryption);
+ TestSyncManager init_sync_manager;
SyncServer server;
SyncTestFile config(server, "default");
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.cpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.cpp
index 29d0d3ee3..7eb7d72a1 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.cpp
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.cpp
@@ -18,6 +18,8 @@
#include "util/test_file.hpp"
+#include "test_utils.hpp"
+
#include "impl/realm_coordinator.hpp"
#if REALM_ENABLE_SYNC
@@ -219,6 +221,28 @@ void wait_for_download(Realm& realm)
wait_for_session(realm, &SyncSession::wait_for_download_completion);
}
+TestSyncManager::TestSyncManager(std::string const& base_path, SyncManager::MetadataMode mode)
+{
+ configure(base_path, mode);
+}
+
+TestSyncManager::~TestSyncManager()
+{
+ SyncManager::shared().reset_for_testing();
+}
+
+void TestSyncManager::configure(std::string const& base_path, SyncManager::MetadataMode mode)
+{
+ SyncClientConfig config;
+ config.base_file_path = base_path.empty() ? tmp_dir() : base_path;
+ config.metadata_mode = mode;
+#if TEST_ENABLE_SYNC_LOGGING
+ config.log_level = util::Logger::Level::all;
+#else
+ config.log_level = util::Logger::Level::off;
+#endif
+ SyncManager::shared().configure(config);
+}
#endif // REALM_ENABLE_SYNC
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.hpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.hpp
index 463e199f4..d435b0b83 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.hpp
+++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/util/test_file.hpp
@@ -133,6 +133,12 @@ struct SyncTestFile : TestFile {
std::string user_name="test");
};
+struct TestSyncManager {
+ TestSyncManager(std::string const& base_path="", realm::SyncManager::MetadataMode = realm::SyncManager::MetadataMode::NoEncryption);
+ ~TestSyncManager();
+ static void configure(std::string const& base_path, realm::SyncManager::MetadataMode);
+};
+
void wait_for_upload(realm::Realm& realm);
void wait_for_download(realm::Realm& realm);
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMConstants.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMConstants.h
index b96dacbfa..c4c109317 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMConstants.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMConstants.h
@@ -161,6 +161,10 @@ typedef RLM_ERROR_ENUM(NSInteger, RLMError, RLMErrorDomain) {
If you wish to migrate any data from the backup Realm, you can open it using the provided Realm configuration.
*/
RLMErrorIncompatibleSyncedFile = 11,
+ /**
+ Denotates an error where an operation was requested which cannot be performed on an open file.
+ */
+ RLMErrorAlreadyOpen = 12,
};
#pragma mark - Constants
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMNetworkClient.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMNetworkClient.mm
index 5cb313547..009795ecf 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMNetworkClient.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMNetworkClient.mm
@@ -42,8 +42,6 @@ static NSRange rangeForErrorType(RLMServerHTTPErrorCodeType type) {
return NSMakeRange(type*100, kHTTPCodeRange);
}
-static std::atomic<NSTimeInterval> g_defaultTimeout{60.0};
-
#pragma mark Network client
@interface RLMSessionDelegate <NSURLSessionDelegate> : NSObject
@@ -71,7 +69,7 @@ static std::atomic<NSTimeInterval> g_defaultTimeout{60.0};
+ (void)sendRequestToServer:(NSURL *)serverURL
JSON:(NSDictionary *)jsonDictionary
completion:(void (^)(NSError *))completionBlock {
- [self sendRequestToServer:serverURL JSON:jsonDictionary timeout:g_defaultTimeout.load()
+ [self sendRequestToServer:serverURL JSON:jsonDictionary timeout:0
completion:^(NSError *error, NSDictionary *) {
completionBlock(error);
}];
@@ -80,6 +78,14 @@ static std::atomic<NSTimeInterval> g_defaultTimeout{60.0};
JSON:(NSDictionary *)jsonDictionary
timeout:(NSTimeInterval)timeout
completion:(void (^)(NSError *, NSDictionary *))completionBlock {
+ // If the timeout isn't set then use the timeout set on the sync manager,
+ // or 60 seconds if it isn't set there either.
+ RLMSyncManager *syncManager = RLMSyncManager.sharedManager;
+ if (timeout < 1)
+ timeout = syncManager.timeoutOptions.connectTimeout / 1000.0;
+ if (timeout < 1)
+ timeout = 60.0;
+
// Create the request
NSError *localError = nil;
NSURL *requestURL = [self urlForAuthServer:serverURL payload:jsonDictionary];
@@ -92,8 +98,8 @@ static std::atomic<NSTimeInterval> g_defaultTimeout{60.0};
return;
}
}
- request.timeoutInterval = MAX(timeout, 10);
- RLMNetworkRequestOptions *options = RLMSyncManager.sharedManager.networkRequestOptions;
+ request.timeoutInterval = timeout;
+ RLMNetworkRequestOptions *options = syncManager.networkRequestOptions;
NSDictionary<NSString *, NSString *> *headers = [self httpHeadersForPayload:jsonDictionary options:options];
for (NSString *key in headers) {
[request addValue:headers[key] forHTTPHeaderField:key];
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMObjectBase.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMObjectBase.mm
index 4a49201a5..3b264c8d9 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMObjectBase.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMObjectBase.mm
@@ -180,7 +180,11 @@ id RLMCreateManagedAccessor(Class cls, RLMClassInfo *info) {
// Generic Swift properties can't be dynamic, so KVO doesn't work for them by default
- (id)valueForUndefinedKey:(NSString *)key {
- if (Ivar ivar = _objectSchema[key].swiftIvar) {
+ RLMProperty *prop = _objectSchema[key];
+ if (Class accessor = prop.swiftAccessor) {
+ return [accessor get:(char *)(__bridge void *)self + ivar_getOffset(prop.swiftIvar)];
+ }
+ if (Ivar ivar = prop.swiftIvar) {
return RLMCoerceToNil(object_getIvar(self, ivar));
}
return [super valueForUndefinedKey:key];
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMPlatform.h.in b/Carthage/Checkouts/realm-cocoa/Realm/RLMPlatform.h.in
index 249173393..2a0607e7e 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMPlatform.h.in
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMPlatform.h.in
@@ -16,7 +16,7 @@
//
////////////////////////////////////////////////////////////////////////////
-#ifdef REALM_BUILDING_FOR_MACOSX
+#ifdef REALM_BUILDING_FOR_MACOS
#if !__is_target_os(macosx)
#error Attempting to use Realm''s macOS framework in a non-macOS target.
#endif
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h
index 53212c030..cbc99cea7 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h
@@ -149,6 +149,61 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, readonly) BOOL isEmpty;
+#pragma mark - File Management
+
+/**
+ Writes a compacted and optionally encrypted copy of the Realm to the given local URL.
+
+ The destination file cannot already exist.
+
+ Note that if this method is called from within a write transaction, the
+ *current* data is written, not the data from the point when the previous write
+ transaction was committed.
+
+ @param fileURL Local URL to save the Realm to.
+ @param key Optional 64-byte encryption key to encrypt the new file with.
+ @param error If an error occurs, upon return contains an `NSError` object
+ that describes the problem. If you are not interested in
+ possible errors, pass in `NULL`.
+
+ @return `YES` if the Realm was successfully written to disk, `NO` if an error occurred.
+ */
+- (BOOL)writeCopyToURL:(NSURL *)fileURL encryptionKey:(nullable NSData *)key error:(NSError **)error;
+
+/**
+ Checks if the Realm file for the given configuration exists locally on disk.
+
+ For non-synchronized, non-in-memory Realms, this is equivalent to
+ `-[NSFileManager.defaultManager fileExistsAtPath:config.path]`. For
+ synchronized Realms, it takes care of computing the actual path on disk based
+ on the server, virtual path, and user as is done when opening the Realm.
+
+ @param config A Realm configuration to check the existence of.
+ @return YES if the Realm file for the given configuration exists on disk, NO otherwise.
+ */
++ (BOOL)fileExistsForConfiguration:(RLMRealmConfiguration *)config;
+
+/**
+ Deletes the local Realm file and associated temporary files for the given configuration.
+
+ This deletes the ".realm", ".note" and ".management" files which would be
+ created by opening the Realm with the given configuration. It does not delete
+ the ".lock" file (which contains no persisted data and is recreated from
+ scratch every time the Realm file is opened).
+
+ The Realm must not be currently open on any thread or in another process. If
+ it is, this will return NO and report the error RLMErrorAlreadyOpen. Attempting to open
+ the Realm on another thread while the deletion is happening will block (and
+ then create a new Realm and open that afterwards).
+
+ If the Realm already does not exist this will return `NO` and report the error NSFileNoSuchFileError;
+
+ @param config A Realm configuration identifying the Realm to be deleted.
+ @return YES if any files were deleted, NO otherwise.
+ */
++ (BOOL)deleteFilesForConfiguration:(RLMRealmConfiguration *)config error:(NSError **)error
+ __attribute__((swift_error(nonnull_error)));
+
#pragma mark - Notifications
/**
@@ -189,9 +244,6 @@ typedef void (^RLMNotificationBlock)(RLMNotification notification, RLMRealm *rea
*/
- (RLMNotificationToken *)addNotificationBlock:(RLMNotificationBlock)block __attribute__((warn_unused_result));
-#pragma mark - Transactions
-
-
#pragma mark - Writing to a Realm
/**
@@ -426,25 +478,6 @@ typedef void (^RLMNotificationBlock)(RLMNotification notification, RLMRealm *rea
@property (nonatomic) BOOL autorefresh;
/**
- Writes a compacted and optionally encrypted copy of the Realm to the given local URL.
-
- The destination file cannot already exist.
-
- Note that if this method is called from within a write transaction, the
- *current* data is written, not the data from the point when the previous write
- transaction was committed.
-
- @param fileURL Local URL to save the Realm to.
- @param key Optional 64-byte encryption key to encrypt the new file with.
- @param error If an error occurs, upon return contains an `NSError` object
- that describes the problem. If you are not interested in
- possible errors, pass in `NULL`.
-
- @return `YES` if the Realm was successfully written to disk, `NO` if an error occurred.
-*/
-- (BOOL)writeCopyToURL:(NSURL *)fileURL encryptionKey:(nullable NSData *)key error:(NSError **)error;
-
-/**
Invalidates all `RLMObject`s, `RLMResults`, `RLMLinkingObjects`, and `RLMArray`s managed by the Realm.
A Realm holds a read lock on the version of the data accessed by it, so
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm
index 50bde2f0d..2ec9b2b58 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm
@@ -928,6 +928,44 @@ REALM_NOINLINE static void translateSharedGroupOpenException(RLMRealmConfigurati
return NO;
}
++ (BOOL)fileExistsForConfiguration:(RLMRealmConfiguration *)config {
+ return [NSFileManager.defaultManager fileExistsAtPath:config.pathOnDisk];
+}
+
++ (BOOL)deleteFilesForConfiguration:(RLMRealmConfiguration *)config error:(NSError **)error {
+ auto& path = config.config.path;
+ bool anyDeleted = false;
+ NSError *localError;
+ bool didCall = SharedGroup::call_with_lock(path, [&](auto const& path) {
+ NSURL *url = [NSURL fileURLWithPath:@(path.c_str())];
+ NSFileManager *fm = NSFileManager.defaultManager;
+
+ anyDeleted = [fm removeItemAtURL:url error:&localError];
+ if (localError && localError.code != NSFileNoSuchFileError) {
+ return;
+ }
+
+ [fm removeItemAtURL:[url URLByAppendingPathExtension:@"management"] error:&localError];
+ if (localError && localError.code != NSFileNoSuchFileError) {
+ return;
+ }
+
+ [fm removeItemAtURL:[url URLByAppendingPathExtension:@"note"] error:&localError];
+ });
+ if (error && localError && localError.code != NSFileNoSuchFileError) {
+ *error = localError;
+ }
+ else if (!didCall) {
+ if (error) {
+ NSString *msg = [NSString stringWithFormat:@"Realm file at path %s cannot be deleted because it is currently opened.", path.c_str()];
+ *error = [NSError errorWithDomain:RLMErrorDomain
+ code:RLMErrorAlreadyOpen
+ userInfo:@{NSLocalizedDescriptionKey: msg}];
+ }
+ }
+ return anyDeleted;
+}
+
#if REALM_ENABLE_SYNC
using Privilege = realm::ComputedPrivileges;
static bool hasPrivilege(realm::ComputedPrivileges actual, realm::ComputedPrivileges expected) {
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.h
index e31018c2d..5a74db21a 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.h
@@ -85,6 +85,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, nullable, copy) NSString *urlPrefix;
+/**
+ Whether nonfatal connection errors should cancel async opens.
+
+ By default, if a nonfatal connection error such as a connection timing out occurs, any currently pending asyncOpen operations will ignore the error and continue to retry until it succeeds. If this is set to true, the open will instead fail and report the error.
+
+ FIXME: This should probably be true by default in the next major version.
+ */
+@property (nonatomic) bool cancelAsyncOpenOnNonFatalErrors;
+
/// :nodoc:
- (instancetype)initWithUser:(RLMSyncUser *)user realmURL:(NSURL *)url __attribute__((unavailable("Use [RLMSyncUser configurationWithURL:] instead")));
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.mm
index aaa75b30f..b082477c4 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration.mm
@@ -68,8 +68,7 @@ BOOL isValidRealmURL(NSURL *url) {
realmURL:(NSURL *)url
customFileURL:(nullable NSURL *)customFileURL
isPartial:(BOOL)isPartial
- stopPolicy:(RLMSyncStopPolicy)stopPolicy
- errorHandler:(std::function<realm::SyncSessionErrorHandler>)errorHandler;
+ stopPolicy:(RLMSyncStopPolicy)stopPolicy;
@end
@implementation RLMSyncConfiguration
@@ -106,6 +105,10 @@ BOOL isValidRealmURL(NSURL *url) {
_config->is_partial = (bool)isPartial;
}
+- (BOOL)isPartial {
+ return (BOOL)_config->is_partial;
+}
+
- (NSURL *)pinnedCertificateURL {
if (auto& path = _config->ssl_trust_certificate_path) {
return [NSURL fileURLWithPath:RLMStringDataToNSString(*path)];
@@ -127,11 +130,6 @@ BOOL isValidRealmURL(NSURL *url) {
}
}
-
-- (BOOL)isPartial {
- return (BOOL)_config->is_partial;
-}
-
- (void)setFullSynchronization:(BOOL)fullSynchronization {
_config->is_partial = !(bool)fullSynchronization;
}
@@ -140,7 +138,7 @@ BOOL isValidRealmURL(NSURL *url) {
return !(BOOL)_config->is_partial;
}
-- (realm::SyncConfig)rawConfiguration {
+- (realm::SyncConfig&)rawConfiguration {
return *_config;
}
@@ -171,6 +169,14 @@ BOOL isValidRealmURL(NSURL *url) {
}
}
+- (bool)cancelAsyncOpenOnNonFatalErrors {
+ return _config->cancel_waits_on_nonfatal_error;
+}
+
+- (void)setCancelAsyncOpenOnNonFatalErrors:(bool)cancelAsyncOpenOnNonFatalErrors {
+ _config->cancel_waits_on_nonfatal_error = cancelAsyncOpenOnNonFatalErrors;
+}
+
- (NSURL *)realmURL {
NSString *rawStringURL = @(_config->reference_realm_url.c_str());
return [NSURL URLWithString:rawStringURL];
@@ -181,8 +187,7 @@ BOOL isValidRealmURL(NSURL *url) {
realmURL:url
customFileURL:nil
isPartial:NO
- stopPolicy:RLMSyncStopPolicyAfterChangesUploaded
- errorHandler:nullptr];
+ stopPolicy:RLMSyncStopPolicyAfterChangesUploaded];
}
- (instancetype)initWithUser:(RLMSyncUser *)user
@@ -196,62 +201,89 @@ BOOL isValidRealmURL(NSURL *url) {
realmURL:url
customFileURL:nil
isPartial:isPartial
- stopPolicy:stopPolicy
- errorHandler:nullptr];
+ stopPolicy:stopPolicy];
config.urlPrefix = urlPrefix;
config.enableSSLValidation = enableSSLValidation;
config.pinnedCertificateURL = certificatePath;
return config;
}
+static void bindHandler(std::string const&, SyncConfig const& config, std::shared_ptr<SyncSession> session) {
+ const std::shared_ptr<SyncUser>& user = config.user;
+ NSURL *realmURL = [NSURL URLWithString:@(config.realm_url().c_str())];
+ NSString *path = [realmURL path];
+ REALM_ASSERT(realmURL && path);
+ auto handle = [[RLMSyncSessionRefreshHandle alloc] initWithRealmURL:realmURL
+ user:user
+ session:std::move(session)
+ completionBlock:RLMSyncManager.sharedManager.sessionCompletionNotifier];
+ context_for(user).register_refresh_handle([path UTF8String], handle);
+}
+
+static void errorHandler(std::shared_ptr<SyncSession> errored_session, SyncError error) {
+ NSString *recoveryPath;
+ RLMSyncErrorActionToken *token;
+ for (auto& pair : error.user_info) {
+ if (pair.first == realm::SyncError::c_original_file_path_key) {
+ token = [[RLMSyncErrorActionToken alloc] initWithOriginalPath:pair.second];
+ }
+ else if (pair.first == realm::SyncError::c_recovery_file_path_key) {
+ recoveryPath = @(pair.second.c_str());
+ }
+ }
+
+ BOOL shouldMakeError = YES;
+ NSDictionary *custom = nil;
+ // Note that certain types of errors are 'interactive'; users have several options
+ // as to how to proceed after the error is reported.
+ auto errorClass = errorKindForSyncError(error);
+ switch (errorClass) {
+ case RLMSyncSystemErrorKindClientReset: {
+ custom = @{kRLMSyncPathOfRealmBackupCopyKey: recoveryPath, kRLMSyncErrorActionTokenKey: token};
+ break;
+ }
+ case RLMSyncSystemErrorKindPermissionDenied: {
+ custom = @{kRLMSyncErrorActionTokenKey: token};
+ break;
+ }
+ case RLMSyncSystemErrorKindUser:
+ case RLMSyncSystemErrorKindSession:
+ break;
+ case RLMSyncSystemErrorKindConnection:
+ case RLMSyncSystemErrorKindClient:
+ case RLMSyncSystemErrorKindUnknown:
+ // Report the error. There's nothing the user can do about it, though.
+ shouldMakeError = error.is_fatal;
+ break;
+ }
+ auto errorHandler = RLMSyncManager.sharedManager.errorHandler;
+ if (!shouldMakeError || !errorHandler) {
+ return;
+ }
+ NSError *nsError = make_sync_error(errorClass, @(error.message.c_str()), error.error_code.value(), custom);
+ RLMSyncSession *session = [[RLMSyncSession alloc] initWithSyncSession:errored_session];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ errorHandler(nsError, session);
+ });
+};
+
- (instancetype)initWithUser:(RLMSyncUser *)user
realmURL:(NSURL *)url
customFileURL:(nullable NSURL *)customFileURL
isPartial:(BOOL)isPartial
- stopPolicy:(RLMSyncStopPolicy)stopPolicy
- errorHandler:(std::function<realm::SyncSessionErrorHandler>)errorHandler {
+ stopPolicy:(RLMSyncStopPolicy)stopPolicy {
if (self = [super init]) {
if (!isValidRealmURL(url)) {
@throw RLMException(@"The provided URL (%@) was not a valid Realm URL.", [url absoluteString]);
}
- auto bindHandler = [=](auto&,
- const SyncConfig& config,
- const std::shared_ptr<SyncSession>& session) {
- const std::shared_ptr<SyncUser>& user = config.user;
- NSURL *realmURL = [NSURL URLWithString:@(config.realm_url().c_str())];
- NSString *path = [realmURL path];
- REALM_ASSERT(realmURL && path);
- RLMSyncSessionRefreshHandle *handle = [[RLMSyncSessionRefreshHandle alloc] initWithRealmURL:realmURL
- user:user
- session:std::move(session)
- completionBlock:[RLMSyncManager sharedManager].sessionCompletionNotifier];
- context_for(user).register_refresh_handle([path UTF8String], handle);
- };
- if (!errorHandler) {
- errorHandler = [=](std::shared_ptr<SyncSession> errored_session,
- SyncError error) {
- RLMSyncSession *session = [[RLMSyncSession alloc] initWithSyncSession:errored_session];
- NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:error.user_info.size()];
- for (auto& pair : error.user_info) {
- userInfo[@(pair.first.c_str())] = @(pair.second.c_str());
- }
- // FIXME: how should the binding respond if the `is_fatal` bool is true?
- [[RLMSyncManager sharedManager] _fireErrorWithCode:error.error_code.value()
- message:@(error.message.c_str())
- isFatal:error.is_fatal
- session:session
- userInfo:userInfo
- errorClass:errorKindForSyncError(error)];
- };
- }
_config = std::make_unique<SyncConfig>(SyncConfig{
[user _syncUser],
[[url absoluteString] UTF8String]
});
_config->stop_policy = translateStopPolicy(stopPolicy);
- _config->bind_session_handler = std::move(bindHandler);
- _config->error_handler = std::move(errorHandler);
+ _config->bind_session_handler = bindHandler;
+ _config->error_handler = errorHandler;
_config->is_partial = isPartial;
_config->client_resync_mode = realm::ClientResyncMode::Manual;
@@ -282,8 +314,7 @@ BOOL isValidRealmURL(NSURL *url) {
realmURL:user.defaultRealmURL
customFileURL:nil
isPartial:YES
- stopPolicy:RLMSyncStopPolicyAfterChangesUploaded
- errorHandler:nullptr];
+ stopPolicy:RLMSyncStopPolicyAfterChangesUploaded];
RLMRealmConfiguration *config = [[RLMRealmConfiguration alloc] init];
config.syncConfiguration = syncConfig;
return config;
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration_Private.hpp b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration_Private.hpp
index e80095ef4..6314e4cb7 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration_Private.hpp
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncConfiguration_Private.hpp
@@ -36,12 +36,11 @@ NS_ASSUME_NONNULL_BEGIN
realmURL:(NSURL *)url
customFileURL:(nullable NSURL *)customFileURL
isPartial:(BOOL)isPartial
- stopPolicy:(RLMSyncStopPolicy)stopPolicy
- errorHandler:(std::function<realm::SyncSessionErrorHandler>)errorHandler;
+ stopPolicy:(RLMSyncStopPolicy)stopPolicy;
- (instancetype)initWithRawConfig:(realm::SyncConfig)config;
-- (realm::SyncConfig)rawConfiguration;
+- (realm::SyncConfig&)rawConfiguration;
@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.h
index b0228e50e..debb5d4a4 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.h
@@ -20,7 +20,9 @@
#import "RLMSyncUtil.h"
-@class RLMSyncSession;
+@class RLMSyncSession, RLMSyncTimeoutOptions;
+
+NS_ASSUME_NONNULL_BEGIN
/// An enum representing different levels of sync-related logging that can be configured.
typedef RLM_CLOSED_ENUM(NSUInteger, RLMSyncLogLevel) {
@@ -50,7 +52,11 @@ typedef RLM_CLOSED_ENUM(NSUInteger, RLMSyncLogLevel) {
RLMSyncLogLevelAll
};
-NS_ASSUME_NONNULL_BEGIN
+/// A log callback function which can be set on RLMSyncManager.
+///
+/// The log function may be called from multiple threads simultaneously, and is
+/// responsible for performing its own synchronization if any is required.
+typedef void (*RLMSyncLogFunction)(RLMSyncLogLevel level, NSString *message);
/// A block type representing a block which can be used to report a sync-related error to the application. If the error
/// pertains to a specific session, that session will also be passed into the block.
@@ -95,7 +101,8 @@ typedef void(^RLMSyncErrorReportingBlock)(NSError *, RLMSyncSession * _Nullable)
The logging threshold which newly opened synced Realms will use. Defaults to
`RLMSyncLogLevelInfo`.
- Logging strings are output to Apple System Logger.
+ By default logging strings are output to Apple System Logger. Set `logger` to
+ perform custom logging logic instead.
@warning This property must be set before any synced Realms are opened. Setting it after
opening any synced Realm will do nothing.
@@ -103,6 +110,16 @@ typedef void(^RLMSyncErrorReportingBlock)(NSError *, RLMSyncSession * _Nullable)
@property (nonatomic) RLMSyncLogLevel logLevel;
/**
+ The function which will be invoked whenever the sync client has a log message.
+
+ If nil, log strings are output to Apple System Logger instead.
+
+ @warning This property must be set before any synced Realms are opened. Setting
+ it after opening any synced Realm will do nothing.
+ */
+@property (nonatomic, nullable) RLMSyncLogFunction logger;
+
+/**
The name of the HTTP header to send authorization data in when making requests to a Realm Object Server which has
been configured to expect a custom authorization header.
*/
@@ -141,6 +158,16 @@ typedef void(^RLMSyncErrorReportingBlock)(NSError *, RLMSyncSession * _Nullable)
*/
@property (nullable, nonatomic, copy) NSDictionary<NSString *, NSURL *> *pinnedCertificatePaths;
+/**
+ Options for the assorted types of connection timeouts for sync connections.
+
+ If nil default values for all timeouts are used instead.
+
+ @warning This property must be set before any synced Realms are opened. Setting
+ it after opening any synced Realm will do nothing.
+ */
+@property (nullable, nonatomic, copy) RLMSyncTimeoutOptions *timeoutOptions;
+
/// The sole instance of the singleton.
+ (instancetype)sharedManager NS_REFINED_FOR_SWIFT;
@@ -150,6 +177,69 @@ typedef void(^RLMSyncErrorReportingBlock)(NSError *, RLMSyncSession * _Nullable)
/// :nodoc:
+ (instancetype)new __attribute__((unavailable("RLMSyncManager cannot be created directly")));
-NS_ASSUME_NONNULL_END
+@end
+/**
+ Options for configuring timeouts and intervals in the sync client.
+ */
+@interface RLMSyncTimeoutOptions : NSObject
+/// The maximum number of milliseconds to allow for a connection to
+/// become fully established. This includes the time to resolve the
+/// network address, the TCP connect operation, the SSL handshake, and
+/// the WebSocket handshake.
+///
+/// Defaults to 2 minutes.
+@property (nonatomic) NSUInteger connectTimeout;
+
+/// The number of milliseconds to keep a connection open after all
+/// sessions have been abandoned.
+///
+/// After all synchronized Realms have been closed for a given server, the
+/// connection is kept open until the linger time has expire to avoid the
+/// overhead of reestablishing the connection when Realms are being closed and
+/// reopened.
+///
+/// Defaults to 30 seconds.
+@property (nonatomic) NSUInteger connectionLingerTime;
+
+/// The number of milliseconds between each heartbeat ping message.
+///
+/// The client periodically sends ping messages to the server to check if the
+/// connection is still alive. Shorter periods make connection state change
+/// notifications more responsive at the cost of battery life (as the antenna
+/// will have to wake up more often).
+///
+/// Defaults to 1 minute.
+@property (nonatomic) NSUInteger pingKeepalivePeriod;
+
+/// How long in milliseconds to wait for a reponse to a heartbeat ping before
+/// concluding that the connection has dropped.
+///
+/// Shorter values will make connection state change notifications more
+/// responsive as it will only change to `disconnected` after this much time has
+/// elapsed, but overly short values may result in spurious disconnection
+/// notifications when the server is simply taking a long time to respond.
+///
+/// Defaults to 2 minutes.
+@property (nonatomic) NSUInteger pongKeepaliveTimeout;
+
+/// The maximum amount of time, in milliseconds, since the loss of a
+/// prior connection, for a new connection to be considered a "fast
+/// reconnect".
+///
+/// When a client first connects to the server, it defers uploading any local
+/// changes until it has downloaded all changesets from the server. This
+/// typically reduces the total amount of merging that has to be done, and is
+/// particularly beneficial the first time that a specific client ever connects
+/// to the server.
+///
+/// When an existing client disconnects and then reconnects within the "fact
+/// reconnect" time this is skipped and any local changes are uploaded
+/// immediately without waiting for downloads, just as if the client was online
+/// the whole time.
+///
+/// Defaults to 1 minute.
+@property (nonatomic) NSUInteger fastReconnectLimit;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.mm
index f5d2c854a..cb2e1d372 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager.mm
@@ -68,6 +68,8 @@ RLMSyncLogLevel logLevelForLevel(Level logLevel) {
REALM_UNREACHABLE(); // Unrecognized log level.
}
+#pragma mark - Loggers
+
struct CocoaSyncLogger : public realm::util::RootLogger {
void do_log(Level, std::string message) override {
NSLog(@"Sync: %@", RLMStringDataToNSString(message));
@@ -82,21 +84,53 @@ struct CocoaSyncLoggerFactory : public realm::SyncLoggerFactory {
}
} s_syncLoggerFactory;
+struct CallbackLogger : public realm::util::RootLogger {
+ RLMSyncLogFunction logFn;
+ void do_log(Level level, std::string message) override {
+ @autoreleasepool {
+ logFn(logLevelForLevel(level), RLMStringDataToNSString(message));
+ }
+ }
+};
+struct CallbackLoggerFactory : public realm::SyncLoggerFactory {
+ RLMSyncLogFunction logFn;
+ std::unique_ptr<realm::util::Logger> make_logger(realm::util::Logger::Level level) override {
+ auto logger = std::make_unique<CallbackLogger>();
+ logger->logFn = logFn;
+ logger->set_level_threshold(level);
+ return std::move(logger); // not a redundant move because it's a different type
+ }
+
+ CallbackLoggerFactory(RLMSyncLogFunction logFn) : logFn(logFn) { }
+};
+
} // anonymous namespace
-@interface RLMSyncManager ()
-- (instancetype)initWithCustomRootDirectory:(nullable NSURL *)rootDirectory NS_DESIGNATED_INITIALIZER;
+#pragma mark - RLMSyncManager
+
+@interface RLMSyncTimeoutOptions () {
+ @public
+ realm::SyncClientTimeouts _options;
+}
@end
-@implementation RLMSyncManager
+@implementation RLMSyncManager {
+ std::unique_ptr<CallbackLoggerFactory> _loggerFactory;
+}
static RLMSyncManager *s_sharedManager = nil;
+- (instancetype)initPrivate {
+ return self = [super init];
+}
+
+ (instancetype)sharedManager {
static std::once_flag flag;
std::call_once(flag, [] {
try {
- s_sharedManager = [[RLMSyncManager alloc] initWithCustomRootDirectory:nil];
+ [RLMSyncUser _setUpBindingContextFactory];
+ s_sharedManager = [[RLMSyncManager alloc] initPrivate];
+ [s_sharedManager configureWithRootDirectory:nil];
}
catch (std::exception const& e) {
@throw RLMException(e);
@@ -105,25 +139,23 @@ static RLMSyncManager *s_sharedManager = nil;
return s_sharedManager;
}
-- (instancetype)initWithCustomRootDirectory:(NSURL *)rootDirectory {
- if (self = [super init]) {
- [RLMSyncUser _setUpBindingContextFactory];
-
- // Initialize the sync engine.
- SyncManager::shared().set_logger_factory(s_syncLoggerFactory);
- bool should_encrypt = !getenv("REALM_DISABLE_METADATA_ENCRYPTION") && !RLMIsRunningInPlayground();
- auto mode = should_encrypt ? SyncManager::MetadataMode::Encryption : SyncManager::MetadataMode::NoEncryption;
+- (void)configureWithRootDirectory:(NSURL *)rootDirectory {
+ SyncClientConfig config;
+ bool should_encrypt = !getenv("REALM_DISABLE_METADATA_ENCRYPTION") && !RLMIsRunningInPlayground();
+ config.logger_factory = &s_syncLoggerFactory;
+ config.metadata_mode = should_encrypt ? SyncManager::MetadataMode::Encryption
+ : SyncManager::MetadataMode::NoEncryption;
+ @autoreleasepool {
rootDirectory = rootDirectory ?: [NSURL fileURLWithPath:RLMDefaultDirectoryForBundleIdentifier(nil)];
- @autoreleasepool {
- bool isSwift = !!NSClassFromString(@"RealmSwiftObjectUtil");
- auto userAgent = [[NSMutableString alloc] initWithFormat:@"Realm%@/%@",
- isSwift ? @"Swift" : @"ObjectiveC", REALM_COCOA_VERSION];
- SyncManager::shared().configure(rootDirectory.path.UTF8String, mode, RLMStringDataWithNSString(userAgent), none, true);
- SyncManager::shared().set_user_agent(RLMStringDataWithNSString(self.appID));
- }
- return self;
+ config.base_file_path = rootDirectory.path.UTF8String;
+
+ bool isSwift = !!NSClassFromString(@"RealmSwiftObjectUtil");
+ config.user_agent_binding_info =
+ util::format("Realm%1/%2", isSwift ? "Swift" : "ObjectiveC",
+ RLMStringDataWithNSString(REALM_COCOA_VERSION));
+ config.user_agent_application_info = RLMStringDataWithNSString(self.appID);
}
- return nil;
+ SyncManager::shared().configure(config);
}
- (NSString *)appID {
@@ -153,6 +185,23 @@ static RLMSyncManager *s_sharedManager = nil;
}
}
+- (void)setLogger:(RLMSyncLogFunction)logFn {
+ _logger = logFn;
+ if (_logger) {
+ _loggerFactory = std::make_unique<CallbackLoggerFactory>(logFn);
+ SyncManager::shared().set_logger_factory(*_loggerFactory);
+ }
+ else {
+ _loggerFactory = nullptr;
+ SyncManager::shared().set_logger_factory(s_syncLoggerFactory);
+ }
+}
+
+- (void)setTimeoutOptions:(RLMSyncTimeoutOptions *)timeoutOptions {
+ _timeoutOptions = timeoutOptions;
+ SyncManager::shared().set_timeouts(timeoutOptions->_options);
+}
+
#pragma mark - Passthrough properties
- (RLMSyncLogLevel)logLevel {
@@ -173,53 +222,6 @@ static RLMSyncManager *s_sharedManager = nil;
});
}
-- (void)_fireErrorWithCode:(int)errorCode
- message:(NSString *)message
- isFatal:(BOOL)fatal
- session:(RLMSyncSession *)session
- userInfo:(NSDictionary *)userInfo
- errorClass:(RLMSyncSystemErrorKind)errorClass {
- NSError *error = nil;
- BOOL shouldMakeError = YES;
- NSDictionary *custom = nil;
- // Note that certain types of errors are 'interactive'; users have several options
- // as to how to proceed after the error is reported.
- switch (errorClass) {
- case RLMSyncSystemErrorKindClientReset: {
- std::string path = [userInfo[@(realm::SyncError::c_original_file_path_key)] UTF8String];
- custom = @{kRLMSyncPathOfRealmBackupCopyKey:
- userInfo[@(realm::SyncError::c_recovery_file_path_key)],
- kRLMSyncErrorActionTokenKey:
- [[RLMSyncErrorActionToken alloc] initWithOriginalPath:std::move(path)]
- };;
- break;
- }
- case RLMSyncSystemErrorKindPermissionDenied: {
- std::string path = [userInfo[@(realm::SyncError::c_original_file_path_key)] UTF8String];
- custom = @{kRLMSyncErrorActionTokenKey:
- [[RLMSyncErrorActionToken alloc] initWithOriginalPath:std::move(path)]
- };
- break;
- }
- case RLMSyncSystemErrorKindUser:
- case RLMSyncSystemErrorKindSession:
- break;
- case RLMSyncSystemErrorKindConnection:
- case RLMSyncSystemErrorKindClient:
- case RLMSyncSystemErrorKindUnknown:
- // Report the error. There's nothing the user can do about it, though.
- shouldMakeError = fatal;
- break;
- }
- error = shouldMakeError ? make_sync_error(errorClass, message, errorCode, custom) : nil;
- dispatch_async(dispatch_get_main_queue(), ^{
- if (!self.errorHandler || !error) {
- return;
- }
- self.errorHandler(error, session);
- });
-}
-
- (NSArray<RLMSyncUser *> *)_allUsers {
NSMutableArray<RLMSyncUser *> *buffer = [NSMutableArray array];
for (auto user : SyncManager::shared().all_logged_in_users()) {
@@ -229,6 +231,16 @@ static RLMSyncManager *s_sharedManager = nil;
}
+ (void)resetForTesting {
+ RLMSyncManager *manager = self.sharedManager;
+ manager->_errorHandler = nil;
+ manager->_appID = nil;
+ manager->_userAgent = nil;
+ manager->_logger = nil;
+ manager->_authorizationHeaderName = nil;
+ manager->_customRequestHeaders = nil;
+ manager->_pinnedCertificatePaths = nil;
+ manager->_timeoutOptions = nil;
+
SyncManager::shared().reset_for_testing();
}
@@ -241,3 +253,43 @@ static RLMSyncManager *s_sharedManager = nil;
}
@end
+
+#pragma mark - RLMSyncTimeoutOptions
+
+@implementation RLMSyncTimeoutOptions
+- (NSUInteger)connectTimeout {
+ return _options.connect_timeout;
+}
+- (void)setConnectTimeout:(NSUInteger)connectTimeout {
+ _options.connect_timeout = connectTimeout;
+}
+
+- (NSUInteger)connectLingerTime {
+ return _options.connection_linger_time;
+}
+- (void)setConnectionLingerTime:(NSUInteger)connectionLingerTime {
+ _options.connection_linger_time = connectionLingerTime;
+}
+
+- (NSUInteger)pingKeepalivePeriod {
+ return _options.ping_keepalive_period;
+}
+- (void)setPingKeepalivePeriod:(NSUInteger)pingKeepalivePeriod {
+ _options.ping_keepalive_period = pingKeepalivePeriod;
+}
+
+- (NSUInteger)pongKeepaliveTimeout {
+ return _options.pong_keepalive_timeout;
+}
+- (void)setPongKeepaliveTimeout:(NSUInteger)pongKeepaliveTimeout {
+ _options.pong_keepalive_timeout = pongKeepaliveTimeout;
+}
+
+- (NSUInteger)fastReconnectLimit {
+ return _options.fast_reconnect_limit;
+}
+- (void)setFastReconnectLimit:(NSUInteger)fastReconnectLimit {
+ _options.fast_reconnect_limit = fastReconnectLimit;
+}
+
+@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager_Private.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager_Private.h
index 7cb660b06..0284aee4f 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager_Private.h
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncManager_Private.h
@@ -34,13 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)_fireError:(NSError *)error;
-- (void)_fireErrorWithCode:(int)errorCode
- message:(NSString *)message
- isFatal:(BOOL)fatal
- session:(RLMSyncSession *)session
- userInfo:(NSDictionary *)userInfo
- errorClass:(RLMSyncSystemErrorKind)errorClass;
-
- (NSArray<RLMSyncUser *> *)_allUsers;
+ (void)resetForTesting;
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSessionRefreshHandle.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSessionRefreshHandle.mm
index 416b7e1b5..b2de98d3b 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSessionRefreshHandle.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSessionRefreshHandle.mm
@@ -58,7 +58,7 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
std::shared_ptr<SyncSession> _strongSession;
}
-@property (nonatomic) NSTimer *timer;
+@property (nonatomic) dispatch_source_t timer;
@property (nonatomic) NSURL *realmURL;
@property (nonatomic) NSURL *authServerURL;
@@ -86,19 +86,26 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
_session = _strongSession;
_user = user;
// Immediately fire off the network request.
- [self _timerFired:nil];
+ [self _timerFired];
return self;
}
return nil;
}
- (void)dealloc {
- [self.timer invalidate];
+ [self cancelTimer];
}
- (void)invalidate {
_strongSession = nullptr;
- [self.timer invalidate];
+ [self cancelTimer];
+}
+
+- (void)cancelTimer {
+ if (self.timer) {
+ dispatch_source_cancel(self.timer);
+ self.timer = nil;
+ }
}
+ (NSDate *)fireDateForTokenExpirationDate:(NSDate *)date nowDate:(NSDate *)nowDate {
@@ -108,43 +115,30 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
}
- (void)scheduleRefreshTimer:(NSDate *)dateWhenTokenExpires {
- // Schedule the timer on the main queue.
- // It's very likely that this method will be run on a side thread, for example
- // on the thread that runs `NSURLSession`'s completion blocks. We can't be
- // guaranteed that there's an existing runloop on those threads, and we don't want
- // to create and start a new one if one doesn't already exist.
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.timer invalidate];
- NSDate *fireDate = [RLMSyncSessionRefreshHandle fireDateForTokenExpirationDate:dateWhenTokenExpires
- nowDate:[NSDate date]];
- if (!fireDate) {
- unregisterRefreshHandle(_user, _path);
- return;
- }
- self.timer = [[NSTimer alloc] initWithFireDate:fireDate
- interval:0
- target:self
- selector:@selector(_timerFired:)
- userInfo:nil
- repeats:NO];
- [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
- });
-}
+ [self cancelTimer];
-/// Handler for network requests whose responses successfully parse into an auth response model.
-- (BOOL)_handleSuccessfulRequest:(RLMAuthResponseModel *)model {
- std::shared_ptr<SyncSession> session = _session.lock();
- if (!session) {
- // The session is dead or in a fatal error state.
+ NSDate *fireDate = [RLMSyncSessionRefreshHandle fireDateForTokenExpirationDate:dateWhenTokenExpires
+ nowDate:[NSDate date]];
+ if (!fireDate) {
unregisterRefreshHandle(_user, _path);
- [self invalidate];
- return NO;
+ return;
}
+ NSTimeInterval timeToExpiration = [fireDate timeIntervalSinceNow];
+ self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
+ dispatch_source_set_timer(self.timer, dispatch_time(DISPATCH_TIME_NOW, timeToExpiration * NSEC_PER_SEC),
+ /* interval */ DISPATCH_TIME_FOREVER,
+ /* leeway */ NSEC_PER_SEC * (timeToExpiration / 10));
+ dispatch_source_set_event_handler(self.timer, ^{ [self _timerFired]; });
+ dispatch_resume(self.timer);
+}
+
+/// Handler for network requests whose responses successfully parse into an auth response model.
+- (BOOL)_handleSuccessfulRequest:(RLMAuthResponseModel *)model session:(SyncSession&)session {
// Realm Cloud will give us a url prefix in the auth response that we need
// to pass onto objectstore to have it connect to the proper sync worker
if (model.urlPrefix) {
- session->set_url_prefix(model.urlPrefix.UTF8String);
+ session.set_url_prefix(model.urlPrefix.UTF8String);
}
// Calculate the resolved path.
@@ -159,7 +153,7 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
@throw RLMException(@"Resolved path returned from the server was invalid (%@).", resolvedPath);
}
// Pass the token and resolved path to the underlying sync subsystem.
- session->refresh_access_token([model.accessToken.token UTF8String], {resolvedURLString.UTF8String});
+ session.refresh_access_token([model.accessToken.token UTF8String], {resolvedURLString.UTF8String});
// Schedule a refresh. If we're successful we must already have `bind()`ed the session
// initially, so we can null out the strong pointer.
@@ -225,16 +219,23 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
/// Callback handler for network requests.
- (BOOL)_onRefreshCompletionWithError:(NSError *)error json:(NSDictionary *)json {
+ std::shared_ptr<SyncSession> session = _session.lock();
+ if (!session) {
+ // The session is dead or in a fatal error state.
+ unregisterRefreshHandle(_user, _path);
+ [self invalidate];
+ return NO;
+ }
+
if (json && !error) {
RLMAuthResponseModel *model = [[RLMAuthResponseModel alloc] initWithDictionary:json
requireAccessToken:YES
requireRefreshToken:NO];
if (model) {
- return [self _handleSuccessfulRequest:model];
+ return [self _handleSuccessfulRequest:model session:*session];
}
// Otherwise, malformed JSON
unregisterRefreshHandle(_user, _path);
- [self.timer invalidate];
NSError *error = make_sync_error(make_auth_error_bad_response(json));
if (self.completionBlock) {
self.completionBlock(error);
@@ -247,14 +248,13 @@ static const NSTimeInterval RLMRefreshBuffer = 10;
return NO;
}
-- (void)_timerFired:(__unused NSTimer *)timer {
+- (void)_timerFired {
RLMServerToken refreshToken = nil;
if (auto user = _user.lock()) {
refreshToken = @(user->refresh_token().c_str());
}
if (!refreshToken) {
unregisterRefreshHandle(_user, _path);
- [self.timer invalidate];
return;
}
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncUser.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncUser.mm
index 6740b8d5e..1c60cd2fa 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncUser.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncUser.mm
@@ -131,7 +131,7 @@ void CocoaSyncUserContext::set_error_handler(RLMUserErrorReportingBlock block)
onCompletion:(RLMUserCompletionBlock)completion {
[self logInWithCredentials:credential
authServerURL:authServerURL
- timeout:30
+ timeout:0 // use timeout from RLMSyncManager
callbackQueue:dispatch_get_main_queue()
onCompletion:completion];
}
@@ -231,8 +231,7 @@ void CocoaSyncUserContext::set_error_handler(RLMUserErrorReportingBlock block)
realmURL:url ?: self.defaultRealmURL
customFileURL:nil
isPartial:!fullSynchronization
- stopPolicy:RLMSyncStopPolicyAfterChangesUploaded
- errorHandler:nullptr];
+ stopPolicy:RLMSyncStopPolicyAfterChangesUploaded];
syncConfig.urlPrefix = urlPrefix;
syncConfig.enableSSLValidation = enableSSLValidation;
syncConfig.pinnedCertificateURL = RLMSyncManager.sharedManager.pinnedCertificatePaths[syncConfig.realmURL.host];
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMUtil.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMUtil.mm
index bde372eb6..59b9829c2 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/RLMUtil.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMUtil.mm
@@ -29,6 +29,10 @@
#import "shared_realm.hpp"
+#if REALM_ENABLE_SYNC
+#import "RLMSyncUtil.h"
+#endif
+
#import <realm/mixed.hpp>
#import <realm/table_view.hpp>
@@ -328,12 +332,23 @@ NSError *RLMMakeError(RLMError code, const realm::RealmFileException& exception)
}
NSError *RLMMakeError(std::system_error const& exception) {
+ int code = exception.code().value();
BOOL isGenericCategoryError = (exception.code().category() == std::generic_category());
NSString *category = @(exception.code().category().name());
NSString *errorDomain = isGenericCategoryError ? NSPOSIXErrorDomain : RLMUnknownSystemErrorDomain;
+#if REALM_ENABLE_SYNC
+ if (exception.code().category() == realm::sync::client_error_category()) {
+ if (exception.code().value() == static_cast<int>(realm::sync::Client::Error::connect_timeout)) {
+ errorDomain = NSPOSIXErrorDomain;
+ code = ETIMEDOUT;
+ }
+ else {
+ errorDomain = RLMSyncErrorDomain;
+ }
+ }
+#endif
- return [NSError errorWithDomain:errorDomain
- code:exception.code().value()
+ return [NSError errorWithDomain:errorDomain code:code
userInfo:@{NSLocalizedDescriptionKey: @(exception.what()),
@"Error Code": @(exception.code().value()),
@"Category": category}];
@@ -403,7 +418,7 @@ NSString *RLMDefaultDirectoryForBundleIdentifier(NSString *bundleIdentifier) {
(void)bundleIdentifier;
// tvOS prohibits writing to the Documents directory, so we use the Library/Caches directory instead.
return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
-#elif TARGET_OS_IPHONE
+#elif TARGET_OS_IPHONE && !TARGET_OS_MACCATALYST
(void)bundleIdentifier;
// On iOS the Documents directory isn't user-visible, so put files there
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
index 239a10c1f..3e3045b88 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>4.1.1</string>
+ <string>4.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>4.1.1</string>
+ <string>4.3.1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2014 Realm. All rights reserved.</string>
<key>NSPrincipalClass</key>
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m b/Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m
index f5392de87..85d84e25a 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m
@@ -20,6 +20,8 @@
#import "RLMConstants.h"
+#if !TARGET_OS_MACCATALYST
+
@interface InterprocessTest : RLMMultiProcessTestCase
@end
@@ -412,3 +414,5 @@
}
@end
+
+#endif
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm
index 6b6a4d556..3223528ca 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm
@@ -1925,15 +1925,82 @@
@autoreleasepool { [RLMRealm defaultRealm]; }
}];
-// NSURL *fileURL = RLMRealmConfiguration.defaultConfiguration.fileURL;
-// for (NSString *pathExtension in @[@"management", @"lock", @"note"]) {
-// NSNumber *attribute = nil;
-// NSError *error = nil;
-// BOOL success = [[fileURL URLByAppendingPathExtension:pathExtension] getResourceValue:&attribute forKey:NSURLIsExcludedFromBackupKey error:&error];
-// XCTAssertTrue(success);
-// XCTAssertNil(error);
-// XCTAssertTrue(attribute.boolValue);
-// }
+ NSURL *fileURL = RLMRealmConfiguration.defaultConfiguration.fileURL;
+#if !TARGET_OS_TV
+ for (NSString *pathExtension in @[@"management", @"lock", @"note"]) {
+#else
+ for (NSString *pathExtension in @[@"management", @"lock"]) {
+#endif
+ NSNumber *attribute = nil;
+ NSError *error = nil;
+ BOOL success = [[fileURL URLByAppendingPathExtension:pathExtension] getResourceValue:&attribute forKey:NSURLIsExcludedFromBackupKey error:&error];
+ XCTAssertTrue(success);
+ XCTAssertNil(error);
+ XCTAssertTrue(attribute.boolValue);
+ }
+}
+
+- (void)testRealmExists {
+ RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
+ XCTAssertFalse([RLMRealm fileExistsForConfiguration:config]);
+ @autoreleasepool { [RLMRealm realmWithConfiguration:config error:nil]; }
+ XCTAssertTrue([RLMRealm fileExistsForConfiguration:config]);
+ [RLMRealm deleteFilesForConfiguration:config error:nil];
+ XCTAssertFalse([RLMRealm fileExistsForConfiguration:config]);
+}
+
+- (void)testDeleteNonexistentRealmFile {
+ NSError *error;
+ XCTAssertFalse([RLMRealm deleteFilesForConfiguration:RLMRealmConfiguration.defaultConfiguration error:&error]);
+ XCTAssertNil(error);
+}
+
+- (void)testDeleteClosedRealmFile {
+ RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
+ @autoreleasepool { [RLMRealm realmWithConfiguration:config error:nil]; }
+
+ NSError *error;
+ XCTAssertTrue([RLMRealm deleteFilesForConfiguration:config error:&error]);
+ XCTAssertNil(error);
+
+ NSFileManager *fm = NSFileManager.defaultManager;
+ XCTAssertTrue([fm fileExistsAtPath:[config.fileURL.path stringByAppendingPathExtension:@"lock"]]);
+ XCTAssertFalse([fm fileExistsAtPath:[config.fileURL.path stringByAppendingPathExtension:@"management"]]);
+#if !TARGET_OS_TV
+ XCTAssertFalse([fm fileExistsAtPath:[config.fileURL.path stringByAppendingPathExtension:@"note"]]);
+#endif
+}
+
+- (void)testDeleteRealmFileWithMissingManagementFiles {
+ RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
+ [NSFileManager.defaultManager createFileAtPath:config.fileURL.path contents:nil attributes:nil];
+
+ NSError *error;
+ XCTAssertTrue([RLMRealm deleteFilesForConfiguration:config error:&error]);
+ XCTAssertNil(error);
+}
+
+- (void)testDeleteRealmFileWithReadOnlyManagementFiles {
+ RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
+ NSFileManager *fm = NSFileManager.defaultManager;
+ [fm createFileAtPath:config.fileURL.path contents:nil attributes:nil];
+ NSString *notificationPipe = [config.fileURL.path stringByAppendingPathExtension:@"note"];
+ [fm createFileAtPath:notificationPipe contents:nil attributes:@{NSFileImmutable: @YES}];
+
+ NSError *error;
+ XCTAssertTrue([RLMRealm deleteFilesForConfiguration:config error:&error]);
+ XCTAssertEqual(error.code, NSFileWriteNoPermissionError);
+ [fm setAttributes:@{NSFileImmutable: @NO} ofItemAtPath:notificationPipe error:nil];
+}
+
+- (void)testDeleteOpenRealmFile {
+ RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
+ __attribute__((objc_precise_lifetime)) RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
+
+ NSError *error;
+ XCTAssertFalse([RLMRealm deleteFilesForConfiguration:config error:&error]);
+ XCTAssertEqual(error.code, RLMErrorAlreadyOpen);
+ XCTAssertTrue([NSFileManager.defaultManager fileExistsAtPath:config.fileURL.path]);
}
@end
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/SchemaTests.mm b/Carthage/Checkouts/realm-cocoa/Realm/Tests/SchemaTests.mm
index 361d428a2..8bee02b47 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/SchemaTests.mm
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Tests/SchemaTests.mm
@@ -742,7 +742,7 @@ RLM_ARRAY_TYPE(NotARealClass)
}
// Can't spawn child processes on iOS
-#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR && !TARGET_OS_MACCATALYST
- (void)testPartialSharedSchemaInit {
if (self.isParent) {
RLMRunChildAndWait();
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift b/Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift
index 54588cb53..9fb3128f6 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift
@@ -21,6 +21,8 @@ import Realm
import Realm.Private
import RealmTestSupport
+#if os(macOS)
+
class InitLinkedToClass: RLMObject {
@objc dynamic var value: SwiftRLMIntObject! = SwiftRLMIntObject(value: [0])
}
@@ -212,3 +214,5 @@ class SwiftRLMSchemaTests: RLMMultiProcessTestCase {
"RLMArray\\<invalid class\\>")
}
}
+
+#endif
diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestHost/main.m b/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestHost/main.m
index 58fb99fe9..bba2d436f 100644
--- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestHost/main.m
+++ b/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestHost/main.m
@@ -14,20 +14,20 @@
int main(int argc, const char *argv[]) {
}
-#elif TARGET_OS_IPHONE || TARGET_OS_TV
+#elif TARGET_OS_IPHONE || TARGET_OS_TV || TARGET_OS_MACCATALYST
#import <UIKit/UIKit.h>
-@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@interface RLMAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
-@implementation AppDelegate
+@implementation RLMAppDelegate
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ return UIApplicationMain(argc, argv, NSStringFromClass([UIApplication class]), NSStringFromClass([RLMAppDelegate class]));
}
}
diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift b/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift
index 9b346a7e6..4ef7ea736 100644
--- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift
+++ b/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift
@@ -764,7 +764,7 @@ public struct Realm {
rlmRealm.invalidate()
}
- // MARK: Writing a Copy
+ // MARK: File Management
/**
Writes a compacted and optionally encrypted copy of the Realm to the given local URL.
@@ -783,6 +783,43 @@ public struct Realm {
try rlmRealm.writeCopy(to: fileURL, encryptionKey: encryptionKey)
}
+ /**
+ Checks if the Realm file for the given configuration exists locally on disk.
+
+ For non-synchronized, non-in-memory Realms, this is equivalent to
+ `FileManager.default.fileExists(atPath:)`. For synchronized Realms, it
+ takes care of computing the actual path on disk based on the server,
+ virtual path, and user as is done when opening the Realm.
+
+ @param config A Realm configuration to check the existence of.
+ @return true if the Realm file for the given configuration exists on disk, false otherwise.
+ */
+ public static func fileExists(for config: Configuration) -> Bool {
+ return RLMRealm.fileExists(for: config.rlmConfiguration)
+ }
+
+ /**
+ Deletes the local Realm file and associated temporary files for the given configuration.
+
+ This deletes the ".realm", ".note" and ".management" files which would be
+ created by opening the Realm with the given configuration. It does not
+ delete the ".lock" file (which contains no persisted data and is recreated
+ from scratch every time the Realm file is opened).
+
+ The Realm must not be currently open on any thread or in another process.
+ If it is, this will throw the error .alreadyOpen. Attempting to open the
+ Realm on another thread while the deletion is happening will block, and
+ then create a new Realm and open that afterwards.
+
+ If the Realm already does not exist this will return `false`.
+
+ @param config A Realm configuration identifying the Realm to be deleted.
+ @return true if any files were deleted, false otherwise.
+ */
+ public static func deleteFiles(for config: Configuration) throws -> Bool {
+ return try RLMRealm.deleteFiles(for: config.rlmConfiguration)
+ }
+
// MARK: Internal
internal var rlmRealm: RLMRealm
diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift
index 5320c830a..60f9b3b84 100644
--- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift
+++ b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift
@@ -248,7 +248,7 @@ class ObjectTests: TestCase {
let expected = object.value(forKey: "binaryCol") as! Data
let actual = "a".data(using: String.Encoding.utf8)!
- XCTAssertTrue(expected == actual)
+ XCTAssertEqual(expected, actual)
XCTAssertEqual(object.value(forKey: "dateCol") as! Date?, Date(timeIntervalSince1970: 1))
XCTAssertEqual((object.value(forKey: "objectCol")! as! SwiftBoolObject).boolCol, false)
@@ -256,9 +256,95 @@ class ObjectTests: TestCase {
}
test(SwiftObject())
- try! Realm().write {
- let persistedObject = try! Realm().create(SwiftObject.self, value: [:])
- test(persistedObject)
+ let realm = try! Realm()
+ try! realm.write {
+ test(realm.create(SwiftObject.self, value: [:]))
+ let addedObj = SwiftObject()
+ realm.add(addedObj)
+ test(addedObj)
+ }
+ }
+
+ func testValueForKeyOptionals() {
+ let test: (SwiftOptionalObject) -> Void = { object in
+ XCTAssertNil(object.value(forKey: "optNSStringCol"))
+ XCTAssertNil(object.value(forKey: "optStringCol"))
+ XCTAssertNil(object.value(forKey: "optBinaryCol"))
+ XCTAssertNil(object.value(forKey: "optDateCol"))
+ XCTAssertNil(object.value(forKey: "optIntCol"))
+ XCTAssertNil(object.value(forKey: "optInt8Col"))
+ XCTAssertNil(object.value(forKey: "optInt16Col"))
+ XCTAssertNil(object.value(forKey: "optInt32Col"))
+ XCTAssertNil(object.value(forKey: "optInt64Col"))
+ XCTAssertNil(object.value(forKey: "optFloatCol"))
+ XCTAssertNil(object.value(forKey: "optDoubleCol"))
+ XCTAssertNil(object.value(forKey: "optBoolCol"))
+ XCTAssertNil(object.value(forKey: "optEnumCol"))
+ }
+
+ test(SwiftOptionalObject())
+ let realm = try! Realm()
+ try! realm.write {
+ test(realm.create(SwiftOptionalObject.self, value: [:]))
+ let addedObj = SwiftOptionalObject()
+ realm.add(addedObj)
+ test(addedObj)
+ }
+ }
+
+ func testValueForKeyList() {
+ let test: (SwiftListObject) -> Void = { object in
+ XCTAssertNil((object.value(forKey: "int") as! List<Int>).first)
+ XCTAssertNil((object.value(forKey: "int8") as! List<Int8>).first)
+ XCTAssertNil((object.value(forKey: "int16") as! List<Int16>).first)
+ XCTAssertNil((object.value(forKey: "int32") as! List<Int32>).first)
+ XCTAssertNil((object.value(forKey: "int64") as! List<Int64>).first)
+ XCTAssertNil((object.value(forKey: "float") as! List<Float>).first)
+ XCTAssertNil((object.value(forKey: "double") as! List<Double>).first)
+ XCTAssertNil((object.value(forKey: "string") as! List<String>).first)
+ XCTAssertNil((object.value(forKey: "data") as! List<Data>).first)
+ XCTAssertNil((object.value(forKey: "date") as! List<Date>).first)
+
+ // The `as Any?` casts below are only to silence the warning about it
+ // happening implicitly and are not functionally required
+ XCTAssertNil((object.value(forKey: "intOpt") as! List<Int?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "int8Opt") as! List<Int8?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "int16Opt") as! List<Int16?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "int32Opt") as! List<Int32?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "int64Opt") as! List<Int64?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "floatOpt") as! List<Float?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "doubleOpt") as! List<Double?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "stringOpt") as! List<String?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "dataOpt") as! List<Data?>).first as Any?)
+ XCTAssertNil((object.value(forKey: "dateOpt") as! List<Date?>).first as Any?)
+ }
+
+ test(SwiftListObject())
+ let realm = try! Realm()
+ try! realm.write {
+ test(realm.create(SwiftListObject.self, value: [:]))
+ let addedObj = SwiftListObject()
+ realm.add(addedObj)
+ test(addedObj)
+ }
+ }
+
+ func testValueForKeyLinkingObjects() {
+ let test: (SwiftDogObject) -> Void = { object in
+ let owners = object.value(forKey: "owners") as! LinkingObjects<SwiftOwnerObject>
+ if object.realm != nil {
+ XCTAssertEqual(owners.first!.name, "owner name")
+ }
+ }
+
+ let dog = SwiftDogObject()
+ let owner = SwiftOwnerObject(value: ["owner name", dog])
+ test(dog)
+ let realm = try! Realm()
+ try! realm.write {
+ test(realm.create(SwiftOwnerObject.self, value: owner).dog!)
+ realm.add(owner)
+ test(dog)
}
}
diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/PerformanceTests.swift b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/PerformanceTests.swift
index 1391a37cb..c9f07323f 100644
--- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/PerformanceTests.swift
+++ b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/PerformanceTests.swift
@@ -48,7 +48,7 @@ class SwiftPerformanceTests: TestCase {
}
#else
override class func defaultTestSuite() -> XCTestSuite {
-#if !DEBUG && os(iOS)
+#if !DEBUG && os(iOS) && !TARGET_OS_MACCATALYST
if isRunningOnDevice {
return super.defaultTestSuite()
}
diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift
index 197afc8f1..79e7675e3 100644
--- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift
+++ b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift
@@ -845,4 +845,13 @@ class RealmTests: TestCase {
XCTFail("Failed to brigde RLMError to Realm.Error")
}
}
+
+ func testExists() {
+ let config = Realm.Configuration()
+ XCTAssertFalse(Realm.fileExists(for: config))
+ autoreleasepool { _ = try! Realm(configuration: config) }
+ XCTAssertTrue(Realm.fileExists(for: config))
+ XCTAssertTrue(try! Realm.deleteFiles(for: config))
+ XCTAssertFalse(Realm.fileExists(for: config))
+ }
}
diff --git a/Carthage/Checkouts/realm-cocoa/build.sh b/Carthage/Checkouts/realm-cocoa/build.sh
index 0ca34965a..c3bb27a78 100755
--- a/Carthage/Checkouts/realm-cocoa/build.sh
+++ b/Carthage/Checkouts/realm-cocoa/build.sh
@@ -70,6 +70,8 @@ command:
test-tvos-devices: tests ObjC & Swift tvOS frameworks on all attached tvOS devices
test-osx: tests macOS framework
test-osx-swift: tests RealmSwift macOS framework
+ test-catalyst: tests Mac Catalyst framework
+ test-catalyst-swift: tests RealmSwift Mac Catalyst framework
test-swiftpm: tests ObjC and Swift macOS frameworks via SwiftPM
verify: verifies docs, osx, osx-swift, ios-static, ios-dynamic, ios-swift, ios-device in both Debug and Release configurations, swiftlint
verify-osx-object-server: downloads the Realm Object Server and runs the Objective-C and Swift integration tests
@@ -569,7 +571,10 @@ case "$COMMAND" in
exit 1
fi
- xc "-scheme Realm -configuration $CONFIGURATION REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' REALM_PLATFORM_SUFFIX='maccatalyst'"
+ xc "-scheme Realm -configuration $CONFIGURATION \
+ REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' \
+ REALM_PLATFORM_SUFFIX='maccatalyst' \
+ IS_MACCATALYST=YES"
clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/catalyst" "Realm.framework"
;;
@@ -585,7 +590,8 @@ case "$COMMAND" in
REALM_CATALYST_FLAGS='-target x86_64-apple-ios13.0-macabi' \
REALM_PLATFORM_SUFFIX='maccatalyst' \
SWIFT_DEPLOYMENT_TARGET='13.0-macabi' \
- SWIFT_PLATFORM_TARGET_PREFIX='ios'"
+ SWIFT_PLATFORM_TARGET_PREFIX='ios' \
+ IS_MACCATALYST=YES"
destination="build/catalyst/swift-$REALM_XCODE_VERSION"
clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework"
rm -rf "$destination/Realm.framework"
@@ -755,6 +761,10 @@ case "$COMMAND" in
sh build.sh test-tvos-devices || failed=1
sh build.sh test-osx || failed=1
sh build.sh test-osx-swift || failed=1
+ if (( $(xcode_version_major) >= 11 )); then
+ sh build.sh test-catalyst || failed=1
+ sh build.sh test-catalyst-swift || failed=1
+ fi
exit $failed
;;
@@ -846,6 +856,20 @@ case "$COMMAND" in
exit 0
;;
+ "test-catalyst")
+ export REALM_SDKROOT=iphoneos
+ xc "-scheme Realm -configuration $CONFIGURATION -destination 'platform=macOS,variant=Mac Catalyst' CODE_SIGN_IDENTITY='' build-for-testing"
+ xc "-scheme Realm -configuration $CONFIGURATION -destination 'platform=macOS,variant=Mac Catalyst' CODE_SIGN_IDENTITY='' test"
+ exit 0
+ ;;
+
+ "test-catalyst-swift")
+ export REALM_SDKROOT=iphoneos
+ xc "-scheme RealmSwift -configuration $CONFIGURATION -destination 'platform=macOS,variant=Mac Catalyst' CODE_SIGN_IDENTITY='' build-for-testing"
+ xc "-scheme RealmSwift -configuration $CONFIGURATION -destination 'platform=macOS,variant=Mac Catalyst' CODE_SIGN_IDENTITY='' test"
+ exit 0
+ ;;
+
######################################
# Full verification
######################################
@@ -871,6 +895,10 @@ case "$COMMAND" in
sh build.sh verify-swiftlint
sh build.sh verify-swiftpm
sh build.sh verify-osx-object-server
+ if (( $(xcode_version_major) >= 11 )); then
+ sh build.sh verify-catalyst
+ sh build.sh verify-catalyst-swift
+ fi
;;
"verify-cocoapods")
@@ -1017,6 +1045,16 @@ case "$COMMAND" in
exit 0
;;
+ "verify-catalyst")
+ sh build.sh test-catalyst
+ exit 0
+ ;;
+
+ "verify-catalyst-swift")
+ sh build.sh test-catalyst-swift
+ exit 0
+ ;;
+
######################################
# Docs
######################################
@@ -1256,7 +1294,7 @@ EOM
sh build.sh prelaunch-simulator
fi
- source $(brew --prefix nvm)/nvm.sh
+ source $(brew --prefix nvm)/nvm.sh --no-use
export REALM_NODE_PATH="$(nvm which 8)"
# Reset CoreSimulator.log
@@ -1512,7 +1550,7 @@ x.y.z Release notes (yyyy-MM-dd)
* File format: Generates Realms with format v9 (Reads and upgrades all previous formats)
* Realm Object Server: 3.21.0 or later.
* APIs are backwards compatible with all previous releases in the 4.x.y series.
-* Carthage release for Swift is built with Xcode 11.2.
+* Carthage release for Swift is built with Xcode 11.3.
### Internal
Upgraded realm-core from ? to ?
diff --git a/Carthage/Checkouts/realm-cocoa/dependencies.list b/Carthage/Checkouts/realm-cocoa/dependencies.list
index dc1972fcb..087212f13 100644
--- a/Carthage/Checkouts/realm-cocoa/dependencies.list
+++ b/Carthage/Checkouts/realm-cocoa/dependencies.list
@@ -1,4 +1,4 @@
-VERSION=4.1.1
-REALM_CORE_VERSION=5.23.6
-REALM_SYNC_VERSION=4.8.2
+VERSION=4.3.1
+REALM_CORE_VERSION=5.23.8
+REALM_SYNC_VERSION=4.9.4
REALM_OBJECT_SERVER_VERSION=3.23.1
diff --git a/Carthage/Checkouts/realm-cocoa/scripts/generate-rlmplatform.sh b/Carthage/Checkouts/realm-cocoa/scripts/generate-rlmplatform.sh
index 9949212c5..c8e01b959 100755
--- a/Carthage/Checkouts/realm-cocoa/scripts/generate-rlmplatform.sh
+++ b/Carthage/Checkouts/realm-cocoa/scripts/generate-rlmplatform.sh
@@ -6,11 +6,12 @@ SOURCE_FILE="${SRCROOT}/Realm/RLMPlatform.h.in"
DESTINATION_FILE="${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/RLMPlatform.h"
TEMPORARY_FILE="${TARGET_TEMP_DIR}/RLMPlatform.h"
-if [ -n "${REALM_PLATFORM_SUFFIX}" ]; then
- PLATFORM_NAME="${REALM_PLATFORM_SUFFIX}"
+PLATFORM_SUFFIX="$SWIFT_PLATFORM_TARGET_PREFIX"
+if [ "$IS_MACCATALYST" = "YES" ]; then
+ PLATFORM_SUFFIX=maccatalyst
fi
-unifdef -B -DREALM_BUILDING_FOR_$(echo ${PLATFORM_NAME} | tr "[:lower:]" "[:upper:]") < "${SOURCE_FILE}" | sed -e "s/''/'/" > "${TEMPORARY_FILE}"
+unifdef -B -DREALM_BUILDING_FOR_$(echo ${PLATFORM_SUFFIX} | tr "[:lower:]" "[:upper:]") < "${SOURCE_FILE}" | sed -e "s/''/'/" > "${TEMPORARY_FILE}"
if ! cmp -s "${TEMPORARY_FILE}" "${DESTINATION_FILE}"; then
echo "Updating ${DESTINATION_FILE}"
diff --git a/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb b/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb
index bf8f01949..32a1ee4b7 100755
--- a/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb
+++ b/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb
@@ -41,7 +41,7 @@ base_examples = [
"examples/tvos/swift",
]
-xcode_versions = %w(10.0 10.1 10.2.1 10.3 11.0)
+xcode_versions = %w(10.0 10.1 10.3 11.1 11.2.1 11.3)
# Remove reference to Realm.xcodeproj from all example workspaces.
base_examples.each do |example|