Browse Source

Merge branch 'develop'

marinofaggiana 5 years ago
parent
commit
85c0869dd6
100 changed files with 2509 additions and 2708 deletions
  1. 12 6
      Cartfile
  2. 8 5
      Cartfile.resolved
  3. 1 1
      Carthage/Checkouts/CocoaLumberjack/Demos/WebServerIPhone/Vendor/CocoaHTTPServer/Categories/DDData.h
  4. 1 1
      Carthage/Checkouts/KTVHTTPCache/Framework/module.modulemap
  5. 4 5
      Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache/Classes/KTVHCHTTPServer/KTVHCHTTPServer.m
  6. 12 4
      Carthage/Checkouts/KTVHTTPCache/Vendors/KTVCocoaHTTPServer/Framework/module.modulemap
  7. 2 2
      Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/CustomCameraCell.swift
  8. 13 0
      Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift
  9. 2 2
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker.podspec
  10. 4 4
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/.gitkeep
  11. 11 2
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLBundle.swift
  12. 6 5
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.swift
  13. 34 12
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.xib
  14. 3 2
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib
  15. 7 1
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/TLPhotoPicker/TLPhotoPicker.h
  16. 38 20
      Carthage/Checkouts/realm-cocoa/.jenkins.yml
  17. 126 0
      Carthage/Checkouts/realm-cocoa/CHANGELOG.md
  18. 2 1
      Carthage/Checkouts/realm-cocoa/Configuration/Realm/Tests iOS static.xcconfig
  19. 1 0
      Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig
  20. 150 110
      Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm
  21. 0 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncUser+ObjectServerTests.h
  22. 0 4
      Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncUser+ObjectServerTests.mm
  23. 123 77
      Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift
  24. 30 3
      Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftPermissionsTests.swift
  25. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
  26. 2 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/CMakeLists.txt
  27. 3 3
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp
  28. 58 48
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/realm_coordinator.cpp
  29. 20 5
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/realm_coordinator.hpp
  30. 11 4
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp
  31. 3 1
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/weak_realm_notifier.hpp
  32. 1 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/list.hpp
  33. 32 43
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp
  34. 19 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/shared_realm.cpp
  35. 13 8
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/shared_realm.hpp
  36. 19 1
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.hpp
  37. 95 75
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/object.cpp
  38. 139 22
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp
  39. 11 7
      Carthage/Checkouts/realm-cocoa/Realm/RLMAccessor.mm
  40. 4 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMAnalytics.mm
  41. 97 2
      Carthage/Checkouts/realm-cocoa/Realm/RLMObject.h
  42. 13 9
      Carthage/Checkouts/realm-cocoa/Realm/RLMObject.mm
  43. 6 1
      Carthage/Checkouts/realm-cocoa/Realm/RLMObjectSchema.mm
  44. 10 3
      Carthage/Checkouts/realm-cocoa/Realm/RLMObjectStore.h
  45. 18 5
      Carthage/Checkouts/realm-cocoa/Realm/RLMObjectStore.mm
  46. 37 10
      Carthage/Checkouts/realm-cocoa/Realm/RLMProperty.mm
  47. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h
  48. 124 55
      Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm
  49. 15 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMRealmConfiguration.mm
  50. 3 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMRealm_Private.h
  51. 3 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMResults.mm
  52. 42 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.h
  53. 59 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.mm
  54. 5 0
      Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession_Private.hpp
  55. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
  56. 2 6
      Carthage/Checkouts/realm-cocoa/Realm/Swift/RLMSupport.swift
  57. 16 12
      Carthage/Checkouts/realm-cocoa/Realm/Tests/DynamicTests.m
  58. 1 1
      Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m
  59. 1 1
      Carthage/Checkouts/realm-cocoa/Realm/Tests/KVOTests.mm
  60. 3 0
      Carthage/Checkouts/realm-cocoa/Realm/Tests/LinkingObjectsTests.mm
  61. 55 50
      Carthage/Checkouts/realm-cocoa/Realm/Tests/MigrationTests.mm
  62. 64 1
      Carthage/Checkouts/realm-cocoa/Realm/Tests/NotificationTests.m
  63. 1 1
      Carthage/Checkouts/realm-cocoa/Realm/Tests/QueryTests.m
  64. 0 108
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMAssertions.h
  65. 0 35
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.h
  66. 0 163
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.m
  67. 0 56
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.h
  68. 0 223
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.m
  69. 0 463
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.h
  70. 0 409
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.m
  71. 5 0
      Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm
  72. 2 13
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/RLMTestCaseUtils.swift
  73. 24 23
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftArrayPropertyTests.swift
  74. 33 32
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftArrayTests.swift
  75. 18 17
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftDynamicTests.swift
  76. 27 26
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftLinkTests.swift
  77. 50 41
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftObjectInterfaceTests.swift
  78. 17 16
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftPropertyTypeTest.swift
  79. 29 28
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftRealmTests.swift
  80. 33 28
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift
  81. 46 39
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftTestObjects.swift
  82. 8 7
      Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftUnicodeTests.swift
  83. 0 27
      Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.h
  84. 0 48
      Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.mm
  85. 3 0
      Carthage/Checkouts/realm-cocoa/Realm/Tests/UtilTests.mm
  86. 1 0
      Carthage/Checkouts/realm-cocoa/RealmSwift.podspec
  87. 21 11
      Carthage/Checkouts/realm-cocoa/RealmSwift/List.swift
  88. 24 0
      Carthage/Checkouts/realm-cocoa/RealmSwift/Object.swift
  89. 0 25
      Carthage/Checkouts/realm-cocoa/RealmSwift/ObjectiveCSupport.swift
  90. 16 0
      Carthage/Checkouts/realm-cocoa/RealmSwift/Optional.swift
  91. 231 23
      Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift
  92. 19 123
      Carthage/Checkouts/realm-cocoa/RealmSwift/RealmCollection.swift
  93. 14 1
      Carthage/Checkouts/realm-cocoa/RealmSwift/Results.swift
  94. 18 25
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/KVOTests.swift
  95. 10 10
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectAccessorTests.swift
  96. 234 12
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectCreationTests.swift
  97. 11 11
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift
  98. 2 2
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectiveCSupportTests.swift
  99. 2 0
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmSwiftTests-BridgingHeader.h
  100. 10 10
      Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift

+ 12 - 6
Cartfile

@@ -1,17 +1,23 @@
-github "tilltue/TLPhotoPicker" == 1.8.5
+github "tilltue/TLPhotoPicker" == 1.9.3
 github "kishikawakatsumi/UICKeyChainStore" == 2.1.2
 github "danielsaidi/Sheeeeeeeeet" == 1.2.2
 github "MortimerGoro/MGSwipeTableCell" == 1.6.8
 github "dzenbot/DZNEmptyDataSet" == 1.8.1
 github "ealeksandrov/EAIntroView" == 2.12.0
 github "calimarkus/JDStatusBarNotification" == 1.6.0
-github "ChangbaDevs/KTVHTTPCache" == 2.0.0
+github "ChangbaDevs/KTVHTTPCache" == 2.0.1
 github "jdg/MBProgressHUD" == 1.1.0
-github "realm/realm-cocoa" == 3.15.0
+github "realm/realm-cocoa" == 3.17.1
 github "SVGKit/SVGKit" == 2.1.0
 github "WeTransfer/WeScan" == 1.1.0
 github "malcommac/SwiftRichString" == 3.0.0
+github "yannickl/QRCodeReader.swift" >= 10.1.0
+github "weichsel/ZIPFoundation" == 0.9.9
+github "rechsteiner/Parchment" == 1.6.0
+github "WenchaoD/FSCalendar"
+github "AssistoLab/DropDown"
+github "krzyzanowskim/OpenSSL"
+
 github "https://github.com/marinofaggiana/FastScroll" "master"
-github "yannickl/QRCodeReader.swift" >= 10.0.0
-github "AFNetworking/AFNetworking" == 3.2.1
-github "weichsel/ZIPFoundation" == 0.9.9
+github "https://github.com/marinofaggiana/AFNetworking" "master"
+

+ 8 - 5
Cartfile.resolved

@@ -1,9 +1,10 @@
-github "AFNetworking/AFNetworking" "3.2.1"
-github "ChangbaDevs/KTVHTTPCache" "2.0.0"
+github "AssistoLab/DropDown" "v2.3.13"
+github "ChangbaDevs/KTVHTTPCache" "2.0.1"
 github "CocoaLumberjack/CocoaLumberjack" "3.5.3"
 github "MortimerGoro/MGSwipeTableCell" "1.6.8"
 github "SVGKit/SVGKit" "2.1.0"
 github "WeTransfer/WeScan" "v1.1.0"
+github "WenchaoD/FSCalendar" "2.8.0"
 github "calimarkus/JDStatusBarNotification" "1.6.0"
 github "danielsaidi/Sheeeeeeeeet" "1.2.2"
 github "dzenbot/DZNEmptyDataSet" "v1.8.1"
@@ -11,10 +12,12 @@ github "ealeksandrov/EAIntroView" "2.12.0"
 github "ealeksandrov/EARestrictedScrollView" "1.1.0"
 github "jdg/MBProgressHUD" "1.1.0"
 github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
+github "krzyzanowskim/OpenSSL" "1.0.218"
 github "malcommac/SwiftRichString" "3.0.0"
+github "marinofaggiana/AFNetworking" "2967678c3e0e98c9b8d7e06222ad12d1f49c26f2"
 github "marinofaggiana/FastScroll" "81967c2309d29bc2c330d422da612160a30bade8"
-github "realm/realm-cocoa" "v3.15.0"
-github "sgr-ksmt/PDFGenerator" "2.1"
-github "tilltue/TLPhotoPicker" "1.8.5"
+github "realm/realm-cocoa" "v3.17.1"
+github "rechsteiner/Parchment" "v1.6.0"
+github "tilltue/TLPhotoPicker" "1.9.3"
 github "weichsel/ZIPFoundation" "0.9.9"
 github "yannickl/QRCodeReader.swift" "10.1.0"

+ 1 - 1
Carthage/Checkouts/CocoaLumberjack/Demos/WebServerIPhone/Vendor/CocoaHTTPServer/Categories/DDData.h

@@ -15,7 +15,7 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.0.0</string>
+	<string>2.0.1</string>
 	<key>CFBundleVersion</key>
 	<string>$(CURRENT_PROJECT_VERSION)</string>
 	<key>LSApplicationCategoryType</key>

+ 1 - 1
Carthage/Checkouts/KTVHTTPCache/Framework/module.modulemap

@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name                = "KTVHTTPCache"
-  s.version             = "2.0.0"
+  s.version             = "2.0.1"
   s.summary             = "A powerful media cache framework."
   s.homepage            = "https://github.com/ChangbaDevs/KTVHTTPCache"
   s.license             = { :type => "MIT", :file => "LICENSE" }

+ 4 - 5
Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache/Classes/KTVHCHTTPServer/KTVHCHTTPServer.m

@@ -36,6 +36,10 @@
 {
     if (self = [super init]) {
         KTVHCLogAlloc(self);
+        self.server = [[HTTPServer alloc] init];
+        [self.server setConnectionClass:[KTVHCHTTPConnection class]];
+        [self.server setType:@"_http._tcp."];
+        [self.server setPort:80];
         self.backgroundTask = UIBackgroundTaskInvalid;
         [[NSNotificationCenter defaultCenter] addObserver:self
                                                  selector:@selector(applicationDidEnterBackground)
@@ -97,10 +101,6 @@
 
 - (BOOL)startInternal:(NSError **)error
 {
-    self.server = [[HTTPServer alloc] init];
-    [self.server setConnectionClass:[KTVHCHTTPConnection class]];
-    [self.server setType:@"_http._tcp."];
-    [self.server setPort:80];
     BOOL ret = [self.server start:error];
     if (ret) {
         KTVHCLogHTTPServer(@"%p, Start server success", self);
@@ -113,7 +113,6 @@
 - (void)stopInternal
 {
     [self.server stop];
-    self.server = nil;
 }
 
 #pragma mark - Background Task

+ 12 - 4
Carthage/Checkouts/KTVHTTPCache/Vendors/KTVCocoaHTTPServer/Framework/module.modulemap

@@ -19,7 +19,7 @@
                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                         <subviews>
                             <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="3bJ-bG-tue">
-                                <rect key="frame" x="73" y="143.5" width="229" height="380"/>
+                                <rect key="frame" x="73" y="144" width="229" height="380"/>
                                 <subviews>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zpy-9h-CPz">
                                         <rect key="frame" x="0.0" y="0.0" width="229" height="36"/>
@@ -37,9 +37,17 @@
                                             <action selector="pickerWithCustomCameraCell" destination="vXZ-lx-hvc" eventType="touchUpInside" id="fXi-av-gMq"/>
                                         </connections>
                                     </button>
-                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="icR-mj-SY4">
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9kt-E5-QsD">
                                         <rect key="frame" x="0.0" y="172" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
+                                        <state key="normal" title="Custom BlackStyle"/>
+                                        <connections>
+                                            <action selector="pickerWithCustomBlackStyle" destination="vXZ-lx-hvc" eventType="touchUpInside" id="gzY-jn-80S"/>
+                                        </connections>
+                                    </button>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="icR-mj-SY4">
+                                        <rect key="frame" x="0.0" y="258" width="229" height="36"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="with NavigationController">
                                             <color key="titleColor" red="0.1019607843" green="0.73725490199999999" blue="0.61176470589999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                         </state>
@@ -48,7 +56,7 @@
                                         </connections>
                                     </button>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VP9-SK-f4B">
-                                        <rect key="frame" x="0.0" y="258" width="229" height="36"/>
+                                        <rect key="frame" x="0.0" y="344" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="with custom rules">
                                             <color key="titleColor" red="0.27450980390000002" green="0.31372549020000001" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -68,7 +76,7 @@
                                 </subviews>
                             </stackView>
                             <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="u8O-io-kHd">
-                                <rect key="frame" x="137.5" y="533.5" width="100" height="112"/>
+                                <rect key="frame" x="137.5" y="534" width="100" height="112"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="get image message" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9CM-MS-96X">
                                         <rect key="frame" x="3" y="0.0" width="94" height="12"/>

+ 2 - 2
Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/CustomCameraCell.swift

@@ -27,7 +27,6 @@ class CustomCameraCell: TLPhotoCollectionViewCell, AVCaptureFileOutputRecordingD
     var videoDeviceInput: AVCaptureDeviceInput!
     
     @IBOutlet private weak var previewView: PreviewView!
-    
     override func awakeFromNib() {
         super.awakeFromNib()
         if Platform.isSimulator {
@@ -103,7 +102,8 @@ class CustomCameraCell: TLPhotoCollectionViewCell, AVCaptureFileOutputRecordingD
         if Platform.isSimulator {
             return
         }
-        sessionQueue.async {
+        sessionQueue.async { [weak self] in
+            guard let `self` = self else { return }
             if self.setupResult == .success {
                 self.session.stopRunning()
                 self.isSessionRunning = self.session.isRunning

+ 13 - 0
Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift

@@ -46,6 +46,19 @@ class ViewController: UIViewController,TLPhotosPickerViewControllerDelegate {
         viewController.selectedAssets = self.selectedAssets
         self.present(viewController.wrapNavigationControllerWithoutBar(), animated: true, completion: nil)
     }
+    
+    @IBAction func pickerWithCustomBlackStyle() {
+        let viewController = CustomBlackStylePickerViewController()
+        viewController.delegate = self
+        viewController.didExceedMaximumNumberOfSelection = { [weak self] (picker) in
+            self?.showExceededMaximumAlert(vc: picker)
+        }
+        var configure = TLPhotosPickerConfigure()
+        configure.numberOfColumn = 3
+        viewController.configure = configure
+        viewController.selectedAssets = self.selectedAssets
+        self.present(viewController, animated: true, completion: nil)
+    }
 
     @IBAction func pickerWithNavigation() {
         let viewController = PhotoPickerWithNavigationViewController()

+ 2 - 2
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker.podspec

@@ -8,7 +8,7 @@
 
 Pod::Spec.new do |s|
   s.name             = 'TLPhotoPicker'
-  s.version          = '1.8.5'
+  s.version          = '1.9.3'
   s.summary          = 'multiple phassets picker for iOS lib. like facebook'
 
 # This description is used to generate tags and improve search results.
@@ -32,7 +32,7 @@ TODO: Add long description of the pod here.
   s.swift_version = '5.0'
   s.pod_target_xcconfig = { 'SWIFT_VERSION' => '5.0' }
 
-  s.source_files = 'TLPhotoPicker/Classes/**/*'
+  s.source_files = 'TLPhotoPicker/Classes/**/*.swift'
   
   s.resource_bundles = { 'TLPhotoPicker' => ['TLPhotoPicker/Classes/*.xib'] }
   s.resources = 'TLPhotoPicker/TLPhotoPickerController.bundle'

+ 4 - 4
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/.gitkeep

@@ -53,10 +53,10 @@ extension PopupViewProtocol where Self: UIView {
 }
 
 open class TLAlbumPopView: UIView,PopupViewProtocol {
-    @IBOutlet var bgView: UIView!
-    @IBOutlet var popupView: UIView!
+    @IBOutlet open var bgView: UIView!
+    @IBOutlet open var popupView: UIView!
     @IBOutlet var popupViewHeight: NSLayoutConstraint!
-    @IBOutlet var tableView: UITableView!
+    @IBOutlet open var tableView: UITableView!
     @objc var originalFrame = CGRect.zero
     @objc var show = false
     
@@ -69,7 +69,7 @@ open class TLAlbumPopView: UIView,PopupViewProtocol {
         self.popupView.layer.cornerRadius = 5.0
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapBgView))
         self.bgView.addGestureRecognizer(tapGesture)
-        self.tableView.register(UINib(nibName: "TLCollectionTableViewCell", bundle: Bundle(for: TLCollectionTableViewCell.self)), forCellReuseIdentifier: "TLCollectionTableViewCell")
+        self.tableView.register(UINib(nibName: "TLCollectionTableViewCell", bundle: TLBundle.bundle()), forCellReuseIdentifier: "TLCollectionTableViewCell")
     }
     
     @objc func tapBgView() {

+ 11 - 2
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLBundle.swift

@@ -8,8 +8,8 @@
 
 import Foundation
 
-class TLBundle {
-    class func podBundleImage(named: String) -> UIImage? {
+open class TLBundle {
+    open class func podBundleImage(named: String) -> UIImage? {
         let podBundle = Bundle(for: TLBundle.self)
         if let url = podBundle.url(forResource: "TLPhotoPickerController", withExtension: "bundle") {
             let bundle = Bundle(url: url)
@@ -17,4 +17,13 @@ class TLBundle {
         }
         return nil
     }
+    
+    class func bundle() -> Bundle {
+        let podBundle = Bundle(for: TLBundle.self)
+        if let url = podBundle.url(forResource: "TLPhotoPicker", withExtension: "bundle") {
+            let bundle = Bundle(url: url)
+            return bundle ?? podBundle
+        }
+        return podBundle
+    }
 }

+ 6 - 5
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.swift

@@ -8,11 +8,12 @@
 
 import UIKit
 
-class TLCollectionTableViewCell: UITableViewCell {
-    @IBOutlet var thumbImageView: UIImageView!
-    @IBOutlet var titleLabel: UILabel!
-    @IBOutlet var subTitleLabel: UILabel!
-    override func awakeFromNib() {
+open class TLCollectionTableViewCell: UITableViewCell {
+    @IBOutlet open var thumbImageView: UIImageView!
+    @IBOutlet open var titleLabel: UILabel!
+    @IBOutlet open var subTitleLabel: UILabel!
+    
+    override open func awakeFromNib() {
         super.awakeFromNib()   
         if #available(iOS 11.0, *) {
             self.thumbImageView.accessibilityIgnoresInvertColors = true

+ 34 - 12
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.xib

@@ -81,6 +81,7 @@ public struct TLPhotosPickerConfigure {
     public var cameraCellNibSet: (nibName: String, bundle:Bundle)? = nil
     public var fetchCollectionTypes: [(PHAssetCollectionType,PHAssetCollectionSubtype)]? = nil
     public var groupByFetch: PHFetchedResultGroupedBy? = nil
+    public var supportedInterfaceOrientations: UIInterfaceOrientationMask = .portrait
     public init() {
         
     }
@@ -97,6 +98,7 @@ public struct Platform {
 
 
 open class TLPhotosPickerViewController: UIViewController {
+    @IBOutlet open var navigationBar: UINavigationBar!
     @IBOutlet open var titleView: UIView!
     @IBOutlet open var titleLabel: UILabel!
     @IBOutlet open var subTitleStackView: UIStackView!
@@ -176,7 +178,7 @@ open class TLPhotosPickerViewController: UIViewController {
     }
     
     public init() {
-        super.init(nibName: "TLPhotosPickerViewController", bundle: Bundle(for: TLPhotosPickerViewController.self))
+        super.init(nibName: "TLPhotosPickerViewController", bundle: TLBundle.bundle())
     }
     
     @objc convenience public init(withPHAssets: (([PHAsset]) -> Void)? = nil, didCancel: (() -> Void)? = nil) {
@@ -192,7 +194,7 @@ open class TLPhotosPickerViewController: UIViewController {
     }
     
     override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
-        return UIInterfaceOrientationMask.portrait
+        return self.configure.supportedInterfaceOrientations
     }
     
     override open func didReceiveMemoryWarning() {
@@ -245,11 +247,28 @@ open class TLPhotosPickerViewController: UIViewController {
         }
     }
     
-    open func maxCheck() -> Bool {
-        if self.configure.singleSelectedMode {
+    private func findIndexAndReloadCells(phAsset: PHAsset) {
+        if
+            var index = self.focusedCollection?.fetchResult?.index(of: phAsset),
+            index != NSNotFound
+        {
+            index += (getfocusedIndex() == 0 && self.configure.usedCameraButton) ? 1 : 0
+            self.collectionView.reloadItems(at: [IndexPath(row: index, section: 0)])
+        }
+    }
+    
+    open func deselectWhenUsingSingleSelectedMode() {
+        if
+            self.configure.singleSelectedMode == true,
+            let selectedPHAsset = self.selectedAssets.first?.phAsset
+        {
             self.selectedAssets.removeAll()
-            self.orderUpdateCells()
+            findIndexAndReloadCells(phAsset: selectedPHAsset)
         }
+    }
+    
+    open func maxCheck() -> Bool {
+        deselectWhenUsingSingleSelectedMode()
         if let max = self.configure.maxSelectedAssets, max <= self.selectedAssets.count {
             self.delegate?.didExceedMaximumNumberOfSelection(picker: self)
             self.didExceedMaximumNumberOfSelection?(self)
@@ -291,7 +310,7 @@ extension TLPhotosPickerViewController {
     }
     
     @objc open func makeUI() {
-        registerNib(nibName: "TLPhotoCollectionViewCell", bundle: Bundle(for: TLPhotoCollectionViewCell.self))
+        registerNib(nibName: "TLPhotoCollectionViewCell", bundle: TLBundle.bundle())
         if let nibSet = self.configure.nibSet {
             registerNib(nibName: nibSet.nibName, bundle: nibSet.bundle)
         }
@@ -637,7 +656,7 @@ extension TLPhotosPickerViewController: PHLivePhotoViewDelegate {
         if asset.type == .video {
             guard let cell = self.collectionView.cellForItem(at: indexPath) as? TLPhotoCollectionViewCell else { return }
             let requestID = self.photoLibrary.videoAsset(asset: phAsset, completionBlock: { (playerItem, info) in
-                DispatchQueue.main.sync { [weak self, weak cell] in
+                DispatchQueue.main.async { [weak self, weak cell] in
                     guard let `self` = self, let cell = cell, cell.player == nil else { return }
                     let player = AVPlayer(playerItem: playerItem)
                     cell.player = player
@@ -678,7 +697,7 @@ extension TLPhotosPickerViewController: PHPhotoLibraryChangeObserver {
             return
         }
         let addIndex = self.usedCameraButton ? 1 : 0
-        DispatchQueue.main.sync {
+        DispatchQueue.main.async {
             guard let changeFetchResult = self.focusedCollection?.fetchResult else { return }
             guard let changes = changeInstance.changeDetails(for: changeFetchResult) else { return }
             if changes.hasIncrementalChanges, self.configure.groupByFetch == nil {
@@ -738,8 +757,8 @@ extension TLPhotosPickerViewController: PHPhotoLibraryChangeObserver {
                 self.reloadCollectionView()
             }
             if let collection = self.focusedCollection {
-                self.collections[getfocusedIndex()] = collection
-                self.albumPopView.tableView.reloadRows(at: [IndexPath(row: getfocusedIndex(), section: 0)], with: .none)
+                self.collections[self.getfocusedIndex()] = collection
+                self.albumPopView.tableView.reloadRows(at: [IndexPath(row: self.getfocusedIndex(), section: 0)], with: .none)
             }
         }
     }
@@ -858,7 +877,6 @@ extension TLPhotosPickerViewController: UICollectionViewDelegate,UICollectionVie
             }else{
                 cell.imageView?.image = self.cameraImage
             }
-            cell.willDisplayCell()
             return cell
         }
         guard let asset = collection.getTLAsset(at: indexPath) else { return cell }
@@ -985,7 +1003,11 @@ extension TLPhotosPickerViewController: UICollectionViewDelegate,UICollectionVie
     }
     
     public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
-        if self.usedPrefetch, let cell = cell as? TLPhotoCollectionViewCell, let collection = self.focusedCollection, let asset = collection.getTLAsset(at: indexPath) {
+        guard let cell = cell as? TLPhotoCollectionViewCell else {
+            return
+        }
+        cell.willDisplayCell()
+        if self.usedPrefetch, let collection = self.focusedCollection, let asset = collection.getTLAsset(at: indexPath) {
             if let selectedAsset = getSelectedAssets(asset) {
                 cell.selectedAsset = true
                 cell.orderLabel?.text = "\(selectedAsset.selectedOrder)"

+ 3 - 2
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -21,6 +21,7 @@
                 <outlet property="emptyMessageLabel" destination="7qj-q4-rHC" id="Bcp-Hu-lEY"/>
                 <outlet property="emptyView" destination="HPm-Vc-F86" id="4FT-XL-9ql"/>
                 <outlet property="indicator" destination="AEv-G6-dRI" id="coA-3n-07e"/>
+                <outlet property="navigationBar" destination="X8O-Gg-slz" id="Sp9-g1-r4y"/>
                 <outlet property="navigationBarTopConstraint" destination="IKp-hS-tTy" id="MFH-eP-0tb"/>
                 <outlet property="popArrowImageView" destination="5zn-je-qLx" id="6k9-cH-vcU"/>
                 <outlet property="subTitleArrowImageView" destination="b7w-7R-rco" id="IjY-7S-Zz1"/>

+ 7 - 1
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/TLPhotoPicker/TLPhotoPicker.h

@@ -19,7 +19,7 @@ core
 core-*
 
 # sync
-sync*
+/sync-*
 
 # sh build.sh config
 /Realm/config.mk
@@ -52,6 +52,7 @@ xcuserdata/
 project.xcworkspace
 *.xccheckout
 DerivedData
+/.build
 
 # AppCode
 .idea/
@@ -111,3 +112,8 @@ examples/ios/objc/Draw/Constants.h
 ## Sync testing
 test-ros-instance
 Realm/ObjectServerTests/node_modules
+
+## Swiftpm
+.swiftpm
+.build
+Package.resolved

+ 38 - 20
Carthage/Checkouts/realm-cocoa/.jenkins.yml

@@ -23,6 +23,7 @@ target:
   - tvos
   - osx-encryption
   - osx-object-server
+  - swiftpm
 
   # These are disabled because the machinen with the devices attached is currently offline
   # - ios-device-objc-ios8
@@ -38,26 +39,26 @@ configuration:
 # Combinations have to be excluded in a way that's hard to read.
 # This table shows which jobs will run:
 
-# +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-# | Configuration Matrix | osx | docs | ios-static | ios-dynamic | ios-swift | osx-swift | watchos | cocoapods-ios | cocoapods-osx | cocoapods-watchos | swiftlint | tvos | osx-encryption | osx-object-server | ios-device-objc-ios8 | ios-device-swift-ios8 | ios-device-objc-ios10 | ios-device-swift-ios10 | tvos-device |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 9.2   | Debug        | X   |      | X          |             |           |           |         |               |               |                   |           |      |                |                   |                      |                       |                       |                        |             |
-# | 9.2   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           | X    | X              | X                 | X                    |                       | X                     |                        |             |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 9.3   | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |      |                |                   |                      |                       |                       |                        |             |
-# | 9.3   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           | X    |                |                   |                      |                       |                       |                        |             |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 9.4   | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |      |                |                   |                      |                       |                       |                        |             |
-# | 9.4   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           | X    |                |                   |                      |                       |                       |                        |             |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 10.0  | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |      |                |                   |                      |                       |                       |                        |             |
-# | 10.0  | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           | X    |                |                   |                      |                       |                       |                        |             |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 10.1  | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |      |                |                   |                      |                       |                       |                        |             |
-# | 10.1  | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           | X    |                |                   |                      |                       |                       |                        |             |
-# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
-# | 10.2.1| Debug        | X   |      |            | X           | X         | X         | X       |               |               |                   |           | X    |                |                   |                      |                       |                       |                        |             |
-# | 10.2.1| Release      | X   | X    | X          | X           | X         | X         | X       | X             | X             | X                 | X         | X    | X              | X                 |                      |                       | X                     |                        | X           |
+# +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+# | Configuration Matrix | osx | docs | ios-static | ios-dynamic | ios-swift | osx-swift | watchos | cocoapods-ios | cocoapods-osx | cocoapods-watchos | swiftlint | swiftpm | tvos | osx-encryption | osx-object-server | ios-device-objc-ios8 | ios-device-swift-ios8 | ios-device-objc-ios10 | ios-device-swift-ios10 | tvos-device |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 9.2   | Debug        | X   |      | X          |             |           |           |         |               |               |                   |           |         |      |                |                   |                      |                       |                       |                        |             |
+# | 9.2   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           |         | X    | X              | X                 | X                    |                       | X                     |                        |             |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 9.3   | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |         |      |                |                   |                      |                       |                       |                        |             |
+# | 9.3   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           |         | X    |                |                   |                      |                       |                       |                        |             |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 9.4   | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |         |      |                |                   |                      |                       |                       |                        |             |
+# | 9.4   | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           |         | X    |                |                   |                      |                       |                       |                        |             |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 10.0  | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |         |      |                |                   |                      |                       |                       |                        |             |
+# | 10.0  | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           |         | X    |                |                   |                      |                       |                       |                        |             |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 10.1  | Debug        | X   |      |            |             |           |           |         |               |               |                   |           |         |      |                |                   |                      |                       |                       |                        |             |
+# | 10.1  | Release      | X   |      | X          | X           | X         | X         | X       | X             | X             | X                 |           |         | X    |                |                   |                      |                       |                       |                        |             |
+# | -------------------- | --- | ---- | ---------- | ----------- | --------- | --------- | ------- | ------------- | ------------- | ----------------- | --------- | ------- | ---- | -------------- | ----------------- | -------------------- | --------------------- | --------------------- | ---------------------- | ----------- |
+# | 10.2.1| Debug        | X   |      |            | X           | X         | X         | X       |               |               |                   |           |         | X    |                |                   |                      |                       |                       |                        |             |
+# | 10.2.1| Release      | X   | X    | X          | X           | X         | X         | X       | X             | X             | X                 | X         | X       | X    | X              | X                 |                      |                       | X                     |                        | X           |
 # +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 exclude:
@@ -206,6 +207,23 @@ exclude:
   - target: swiftlint
     configuration: Debug
 
+  ################
+  # swiftpm
+  ################
+  # Just run on 10.2 Release
+  - xcode_version: 9.2
+    target: swiftpm
+  - xcode_version: 9.3
+    target: swiftpm
+  - xcode_version: 9.4
+    target: swiftpm
+  - xcode_version: 10.0
+    target: swiftpm
+  - xcode_version: 10.1
+    target: swiftpm
+  - target: swiftpm
+    configuration: Debug
+
   ################
   # tvos
   ################

+ 126 - 0
Carthage/Checkouts/realm-cocoa/CHANGELOG.md

@@ -1,3 +1,129 @@
+3.17.1 Release notes (2019-07-10)
+=============================================================
+
+### Enhancements
+
+* Add support for canceling asynchronous opens using a new AsyncOpenTask
+  returned from the asyncOpen() call. ([PR #6913](https://github.com/realm/realm-cocoa/pull/6187)).
+* Importing the Realm SPM package can now be done by pinning to a version
+  rather than a branch.
+
+### Fixed
+
+* Queries on a List/RLMArray which checked an indexed int property would
+  sometimes give incorrect results.
+  ([#6154](https://github.com/realm/realm-cocoa/issues/6154)), since v3.15.0)
+* Queries involving an indexed int property had a memory leak if run multiple
+  times. ([#6186](https://github.com/realm/realm-cocoa/issues/6186)), since v3.15.0)
+* Creating a subscription with `includeLinkingObjects:` performed unneccesary
+  comparisons, making it extremely slow when large numbers of objects were
+  involved. ([Core #3311](https://github.com/realm/realm-core/issues/3311), since v3.15.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 10.2.1.
+
+3.17.0 Release notes (2019-06-28)
+=============================================================
+
+### Enhancements
+
+* Add support for including Realm via Swift Package Manager. This currently
+  requires depending on the branch "master" rather than pinning to a version
+  (i.e. `.package(url: "https://github.com/realm/realm-cocoa", .branch("master"))`).
+  ([#6187](https://github.com/realm/realm-cocoa/pull/6187)).
+* Add Codable conformance to RealmOptional and List, and Encodable conformance to Results.
+  ([PR #6172](https://github.com/realm/realm-cocoa/pull/6172)).
+
+### Fixed
+
+* Attempting to observe an unmanaged LinkingObjects object crashed rather than
+  throwing an approriate exception (since v0.100.0).
+* Opening an encrypted Realm could potentially report that a valid file was
+  corrupted if the system was low on free memory.
+  (since 3.14.0, [Core #3267](https://github.com/realm/realm-core/issues/3267))
+* Calling `Realm.asyncOpen()` on multiple Realms at once would sometimes crash
+  due to a `FileNotFound` exception being thrown on a background worker thread.
+  (since 3.16.0, [ObjectStore #806](https://github.com/realm/realm-object-store/pull/806)).
+
+### 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 10.2.1.
+
+3.16.2 Release notes (2019-06-14)
+=============================================================
+
+### Enhancements
+
+* Add support for Xcode 11 Beta 1. Xcode betas are only supported when building
+  from source, and not when using a prebuilt framework.
+  ([PR #6164](https://github.com/realm/realm-cocoa/pull/6164)).
+
+### Fixed
+
+* Using asyncOpen on query-based Realms which didn't already exist on the local
+  device would fail with error 214.
+  ([#6178](https://github.com/realm/realm-cocoa/issues/6178), since 3.16.0).
+* asyncOpen on query-based Realms did not wait for the server-created
+  permission objects to be downloaded, resulting in crashes if modifications to
+  the permissions were made before creating a subscription for the first time (since 3.0.0).
+* EINTR was not handled correctly in the notification worker, which may have
+  resulted in inconsistent and rare assertion failures in
+  `ExternalCommitHelper::listen()` when building with assertions enabled.
+  (PR: [#804](https://github.com/realm/realm-object-store/pull/804), since 0.91.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 10.2.1.
+
+3.16.1 Release notes (2019-05-31)
+=============================================================
+
+### Fixed
+
+* The static type passed at compile time to `realm.create()` was checked for a
+  primary key rather than the actual type passed at runtime, resulting in
+  exceptions like "''RealmSwiftObject' does not have a primary key and can not
+  be updated'" being thrown even if the object type being created has a primary
+  key. (since 3.16.0, [#6159](https://github.com/realm/realm-cocoa/issues/6159)).
+
+### 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 10.2.1.
+
+3.16.0 Release notes (2019-05-29)
+=============================================================
+
+### Enhancements
+
+* Add an option to only set the properties which have values different from the
+  existing ones when updating an existing object with
+  `Realm.create()`/`-[RLMObject createOrUpdateInRealm:withValue:]`. This makes
+  notifications report only the properties which have actually changed, and
+  improves Object Server performance by reducing the number of operations to
+  merge. (Issue: [#5970](https://github.com/realm/realm-cocoa/issues/5970),
+  PR: [#6149](https://github.com/realm/realm-cocoa/pull/6149)).
+* Using `-[RLMRealm asyncOpenWithConfiguration:callbackQueue:]`/`Realm.asyncOpen()` to open a
+  synchronized Realm which does not exist on the local device now uses an
+  optimized transfer method to download the initial data for the Realm, greatly
+  speeding up the first start time for applications which use full
+  synchronization. This is currently not applicable to query-based
+  synchronization. (PR: [#6106](https://github.com/realm/realm-cocoa/pull/6106)).
+
+### 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 10.2.1.
+
 3.15.0 Release notes (2019-05-06)
 =============================================================
 

+ 2 - 1
Carthage/Checkouts/realm-cocoa/Configuration/Realm/Tests iOS static.xcconfig

@@ -1,6 +1,7 @@
 #include "Tests.xcconfig"
 
 CONFIGURATION_BUILD_DIR = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)-static;
+CONFIGURATION_TEMP_DIR = $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)-static;
 IPHONEOS_DEPLOYMENT_TARGET = 8.0;
 
-TEST_HOST[sdk=iphone*] = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/TestHost.app/TestHost;
+TEST_HOST[sdk=iphone*] = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)-static/TestHost static.app/TestHost static;

+ 1 - 0
Carthage/Checkouts/realm-cocoa/Configuration/TestHost.xcconfig

@@ -1,5 +1,6 @@
 SUPPORTED_PLATFORMS = macosx iphonesimulator iphoneos appletvos appletvsimulator;
 
+CODE_SIGN_IDENTITY = "-";
 COPY_PHASE_STRIP = NO;
 LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks;
 INFOPLIST_FILE = Realm/Tests/TestHost/Info.plist;

+ 150 - 110
Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm

@@ -63,12 +63,6 @@
 }
 @end
 
-@implementation PersonObject
-+ (NSDictionary *)linkingObjectsProperties {
-    return @{@"parents": [RLMPropertyDescriptor descriptorWithClass:PersonObject.class propertyName:@"children"]};
-}
-@end
-
 @interface RLMObjectServerTests : RLMSyncTestCase
 @end
 
@@ -1385,66 +1379,66 @@
 
 #pragma mark - Progress Notifications
 
+static const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
+
+- (void)populateDataForUser:(RLMSyncUser *)user url:(NSURL *)url {
+    RLMRealm *realm = [self openRealmForURL:url user:user];
+    [realm beginWriteTransaction];
+    for (NSInteger i=0; i<NUMBER_OF_BIG_OBJECTS; i++) {
+        [realm addObject:[HugeSyncObject object]];
+    }
+    [realm commitWriteTransaction];
+    [self waitForUploadsForRealm:realm];
+    CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
+}
+
 - (void)testStreamingDownloadNotifier {
-    const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
     NSURL *url = REALM_URL();
-    // Log in the user.
-    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
-                                                                                            register:self.isParent]
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
                                                server:[RLMObjectServerTests authServerURL]];
+    if (!self.isParent) {
+        [self populateDataForUser:user url:url];
+        return;
+    }
+
     __block NSInteger callCount = 0;
     __block NSUInteger transferred = 0;
     __block NSUInteger transferrable = 0;
-    // Open the Realm
-    RLMRealm *realm = [self openRealmForURL:url user:user];
-    if (self.isParent) {
-        __block BOOL hasBeenFulfilled = NO;
-        // Register a notifier.
-        RLMSyncSession *session = [user sessionForURL:url];
-        XCTAssertNotNil(session);
-        XCTestExpectation *ex = [self expectationWithDescription:@"streaming-download-notifier"];
-        RLMProgressNotificationToken *token = [session addProgressNotificationForDirection:RLMSyncProgressDirectionDownload
-                                                                                      mode:RLMSyncProgressModeReportIndefinitely
-                                                                                     block:^(NSUInteger xfr, NSUInteger xfb) {
-            // Make sure the values are increasing, and update our stored copies.
-            XCTAssert(xfr >= transferred);
-            XCTAssert(xfb >= transferrable);
-            transferred = xfr;
-            transferrable = xfb;
-            callCount++;
-            if (transferrable > 0 && transferred >= transferrable && !hasBeenFulfilled) {
-                [ex fulfill];
-                hasBeenFulfilled = YES;
-            }
-        }];
-        // Wait for the child process to upload everything.
-        RLMRunChildAndWait();
-        [self waitForExpectationsWithTimeout:10.0 handler:nil];
-        [token invalidate];
-        // The notifier should have been called at least twice: once at the beginning and at least once
-        // to report progress.
-        XCTAssert(callCount > 1);
-        XCTAssert(transferred >= transferrable,
-                  @"Transferred (%@) needs to be greater than or equal to transferrable (%@)",
-                  @(transferred), @(transferrable));
-    } else {
-        // Write lots of data to the Realm, then wait for it to be uploaded.
-        [realm beginWriteTransaction];
-        for (NSInteger i=0; i<NUMBER_OF_BIG_OBJECTS; i++) {
-            [realm addObject:[HugeSyncObject object]];
-        }
-        [realm commitWriteTransaction];
-        [self waitForUploadsForRealm:realm];
-        CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
-    }
+    __block BOOL hasBeenFulfilled = NO;
+    // Register a notifier.
+    [self openRealmForURL:url user:user];
+    RLMSyncSession *session = [user sessionForURL:url];
+    XCTAssertNotNil(session);
+    XCTestExpectation *ex = [self expectationWithDescription:@"streaming-download-notifier"];
+    id token = [session addProgressNotificationForDirection:RLMSyncProgressDirectionDownload
+                                                       mode:RLMSyncProgressModeReportIndefinitely
+                                                      block:^(NSUInteger xfr, NSUInteger xfb) {
+                                                          // Make sure the values are increasing, and update our stored copies.
+                                                          XCTAssert(xfr >= transferred);
+                                                          XCTAssert(xfb >= transferrable);
+                                                          transferred = xfr;
+                                                          transferrable = xfb;
+                                                          callCount++;
+                                                          if (transferrable > 0 && transferred >= transferrable && !hasBeenFulfilled) {
+                                                              [ex fulfill];
+                                                              hasBeenFulfilled = YES;
+                                                          }
+                                                      }];
+    // Wait for the child process to upload everything.
+    RLMRunChildAndWait();
+    [self waitForExpectationsWithTimeout:10.0 handler:nil];
+    [token invalidate];
+    // The notifier should have been called at least twice: once at the beginning and at least once
+    // to report progress.
+    XCTAssert(callCount > 1);
+    XCTAssert(transferred >= transferrable,
+              @"Transferred (%@) needs to be greater than or equal to transferrable (%@)",
+              @(transferred), @(transferrable));
 }
 
 - (void)testStreamingUploadNotifier {
-    const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
     NSURL *url = REALM_URL();
-    // Log in the user.
-    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
-                                                                                            register:self.isParent]
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
                                                server:[RLMObjectServerTests authServerURL]];
     __block NSInteger callCount = 0;
     __block NSUInteger transferred = 0;
@@ -1493,64 +1487,47 @@
 - (void)testDownloadRealm {
     const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
     NSURL *url = REALM_URL();
-    // Log in the user.
-    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
-                                                                                            register:self.isParent]
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
                                                server:[RLMObjectServerTests authServerURL]];
-    if (self.isParent) {
-        // Wait for the child process to upload everything.
-        RLMRunChildAndWait();
-        XCTestExpectation *ex = [self expectationWithDescription:@"download-realm"];
-        RLMRealmConfiguration *c = [user configurationWithURL:url fullSynchronization:true];
-        XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:c.pathOnDisk isDirectory:nil]);
-        [RLMRealm asyncOpenWithConfiguration:c
-                               callbackQueue:dispatch_get_main_queue()
-                                    callback:^(RLMRealm * _Nullable realm, NSError * _Nullable error) {
-            XCTAssertNil(error);
-            CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
-            [ex fulfill];
-        }];
-        NSUInteger (^fileSize)(NSString *) = ^NSUInteger(NSString *path) {
-            NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
-            if (attributes)
-                return [(NSNumber *)attributes[NSFileSize] unsignedLongLongValue];
-
-            return 0;
-        };
-        XCTAssertNil(RLMGetAnyCachedRealmForPath(c.pathOnDisk.UTF8String));
-        [self waitForExpectationsWithTimeout:10.0 handler:nil];
-        XCTAssertGreaterThan(fileSize(c.pathOnDisk), 0U);
-        XCTAssertNil(RLMGetAnyCachedRealmForPath(c.pathOnDisk.UTF8String));
-    } else {
-        RLMRealm *realm = [self openRealmForURL:url user:user];
-        // Write lots of data to the Realm, then wait for it to be uploaded.
-        [realm beginWriteTransaction];
-        for (NSInteger i=0; i<NUMBER_OF_BIG_OBJECTS; i++) {
-            [realm addObject:[HugeSyncObject object]];
-        }
-        [realm commitWriteTransaction];
-        [self waitForUploadsForRealm:realm];
-        CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
+    if (!self.isParent) {
+        [self populateDataForUser:user url:url];
+        return;
     }
+
+    // Wait for the child process to upload everything.
+    RLMRunChildAndWait();
+
+    XCTestExpectation *ex = [self expectationWithDescription:@"download-realm"];
+    RLMRealmConfiguration *c = [user configurationWithURL:url fullSynchronization:true];
+    XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:c.pathOnDisk isDirectory:nil]);
+    [RLMRealm asyncOpenWithConfiguration:c
+                           callbackQueue:dispatch_get_main_queue()
+                                callback:^(RLMRealm * _Nullable realm, NSError * _Nullable error) {
+                                    XCTAssertNil(error);
+                                    CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
+                                    [ex fulfill];
+                                }];
+    NSUInteger (^fileSize)(NSString *) = ^NSUInteger(NSString *path) {
+        NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
+        if (attributes)
+            return [(NSNumber *)attributes[NSFileSize] unsignedLongLongValue];
+
+        return 0;
+    };
+    XCTAssertNil(RLMGetAnyCachedRealmForPath(c.pathOnDisk.UTF8String));
+    [self waitForExpectationsWithTimeout:10.0 handler:nil];
+    XCTAssertGreaterThan(fileSize(c.pathOnDisk), 0U);
+    XCTAssertNil(RLMGetAnyCachedRealmForPath(c.pathOnDisk.UTF8String));
 }
 
 - (void)testDownloadAlreadyOpenRealm {
     const NSInteger NUMBER_OF_BIG_OBJECTS = 2;
     NSURL *url = REALM_URL();
     // Log in the user.
-    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
-                                                                                            register:self.isParent]
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
                                                server:[RLMObjectServerTests authServerURL]];
     if (!self.isParent) {
-        RLMRealm *realm = [self openRealmForURL:url user:user];
-        // Write lots of data to the Realm, then wait for it to be uploaded.
-        [realm beginWriteTransaction];
-        for (NSInteger i = 0; i < NUMBER_OF_BIG_OBJECTS; i++) {
-            [realm addObject:[HugeSyncObject object]];
-        }
-        [realm commitWriteTransaction];
-        [self waitForUploadsForRealm:realm];
-        CHECK_COUNT(NUMBER_OF_BIG_OBJECTS, HugeSyncObject, realm);
+        [self populateDataForUser:user url:url];
         return;
     }
 
@@ -1590,8 +1567,7 @@
 }
 
 - (void)testDownloadCancelsOnAuthError {
-    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd)
-                                                                                            register:self.isParent]
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
                                                server:[RLMObjectServerTests authServerURL]];
     auto c = [user configurationWithURL:[NSURL URLWithString:@"realm://127.0.0.1:9080/invalid"] fullSynchronization:true];
     auto ex = [self expectationWithDescription:@"async open"];
@@ -1604,6 +1580,70 @@
     [self waitForExpectationsWithTimeout:2.0 handler:nil];
 }
 
+- (void)testCancelDownload {
+    NSURL *url = REALM_URL();
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
+                                               server:[RLMObjectServerTests authServerURL]];
+    if (!self.isParent) {
+        [self populateDataForUser:user url:url];
+        return;
+    }
+
+    // Wait for the child process to upload everything.
+    RLMRunChildAndWait();
+
+    // Use a serial queue for asyncOpen to ensure that the first one adds
+    // the completion block before the second one cancels it
+    RLMSetAsyncOpenQueue(dispatch_queue_create("io.realm.asyncOpen", 0));
+
+    XCTestExpectation *ex = [self expectationWithDescription:@"download-realm"];
+    RLMRealmConfiguration *c = [user configurationWithURL:url fullSynchronization:true];
+
+    [RLMRealm asyncOpenWithConfiguration:c
+                           callbackQueue:dispatch_get_main_queue()
+                                callback:^(RLMRealm *realm, NSError *error) {
+                                    XCTAssertNil(realm);
+                                    XCTAssertNotNil(error);
+                                    [ex fulfill];
+                                }];
+    [[RLMRealm asyncOpenWithConfiguration:c
+                            callbackQueue:dispatch_get_main_queue()
+                                 callback:^(RLMRealm *, NSError *) {
+                                     XCTFail(@"Cancelled callback got called");
+                                 }] cancel];
+    [self waitForExpectationsWithTimeout:2.0 handler:nil];
+}
+
+- (void)testAsyncOpenProgressNotifications {
+    NSURL *url = REALM_URL();
+    RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:NSStringFromSelector(_cmd) register:self.isParent]
+                                               server:[RLMObjectServerTests authServerURL]];
+    if (!self.isParent) {
+        [self populateDataForUser:user url:url];
+        return;
+    }
+
+    RLMRunChildAndWait();
+
+    XCTestExpectation *ex1 = [self expectationWithDescription:@"async open"];
+    XCTestExpectation *ex2 = [self expectationWithDescription:@"download progress complete"];
+    RLMRealmConfiguration *c = [user configurationWithURL:url fullSynchronization:true];
+
+    auto task = [RLMRealm asyncOpenWithConfiguration:c
+                                       callbackQueue:dispatch_get_main_queue()
+                                            callback:^(RLMRealm *realm, NSError *error) {
+                                                XCTAssertNil(error);
+                                                XCTAssertNotNil(realm);
+                                                [ex1 fulfill];
+                                            }];
+    [task addProgressNotificationBlock:^(NSUInteger transferredBytes, NSUInteger transferrableBytes) {
+        if (transferrableBytes > 0 && transferredBytes == transferrableBytes) {
+            [ex2 fulfill];
+        }
+    }];
+    [self waitForExpectationsWithTimeout:2.0 handler:nil];
+}
+
 #pragma mark - Compact on Launch
 
 - (void)testCompactOnLaunch {
@@ -1638,7 +1678,9 @@
     // actually compacted
     auto config = [user configurationWithURL:url fullSynchronization:true];
     __block bool blockCalled = false;
-    config.shouldCompactOnLaunch = ^(NSUInteger, NSUInteger){
+    __block NSUInteger usedSize = 0;
+    config.shouldCompactOnLaunch = ^(NSUInteger, NSUInteger used) {
+        usedSize = used;
         blockCalled = true;
         return YES;
     };
@@ -1650,9 +1692,7 @@
 
     auto finalSize = [[fileManager attributesOfItemAtPath:path error:nil][NSFileSize] unsignedLongLongValue];
     XCTAssertLessThan(finalSize, initialSize);
-    // Immediately after compaction the file is two pages (8192 bytes), but it
-    // grows to three pages shortly later due to sync performing a write
-    XCTAssertLessThanOrEqual(finalSize, 12288U);
+    XCTAssertLessThanOrEqual(finalSize, usedSize + 4096U);
 }
 
 #pragma mark - Offline Client Reset

+ 0 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncUser+ObjectServerTests.h

@@ -29,6 +29,4 @@ NS_ASSUME_NONNULL_BEGIN
 
 @end
 
-FOUNDATION_EXTERN bool RLMHasCachedRealmForPath(NSString *path);
-
 NS_ASSUME_NONNULL_END

+ 0 - 4
Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMSyncUser+ObjectServerTests.mm

@@ -70,7 +70,3 @@ using namespace realm;
 }
 
 @end
-
-bool RLMHasCachedRealmForPath(NSString *path) {
-    return RLMGetAnyCachedRealmForPath(path.UTF8String);
-}

+ 123 - 77
Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift

@@ -186,52 +186,57 @@ class SwiftObjectServerTests: SwiftSyncTestCase {
 
     // MARK: - Progress notifiers
 
+    let bigObjectCount = 2
+
+    func populateRealm(user: SyncUser, url: URL) {
+        let realm = try! synchronouslyOpenRealm(url: realmURL, user: user)
+        try! realm.write {
+            for _ in 0..<bigObjectCount {
+                realm.add(SwiftHugeSyncObject())
+            }
+        }
+        waitForUploads(for: realm)
+        checkCount(expected: bigObjectCount, realm, SwiftHugeSyncObject.self)
+    }
+
     func testStreamingDownloadNotifier() {
-        let bigObjectCount = 2
-        do {
-            var callCount = 0
-            var transferred = 0
-            var transferrable = 0
-            let user = try synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
-            let realm = try synchronouslyOpenRealm(url: realmURL, user: user)
-            if isParent {
-                let session = realm.syncSession
-                XCTAssertNotNil(session)
-                let ex = expectation(description: "streaming-downloads-expectation")
-                var hasBeenFulfilled = false
-                let token = session!.addProgressNotification(for: .download, mode: .reportIndefinitely) { p in
-                    callCount += 1
-                    XCTAssert(p.transferredBytes >= transferred)
-                    XCTAssert(p.transferrableBytes >= transferrable)
-                    transferred = p.transferredBytes
-                    transferrable = p.transferrableBytes
-                    if p.transferredBytes > 0 && p.isTransferComplete && !hasBeenFulfilled {
-                        ex.fulfill()
-                        hasBeenFulfilled = true
-                    }
-                }
-                // Wait for the child process to upload all the data.
-                executeChild()
-                waitForExpectations(timeout: 10.0, handler: nil)
-                token!.invalidate()
-                XCTAssert(callCount > 1)
-                XCTAssert(transferred >= transferrable)
-            } else {
-                try realm.write {
-                    for _ in 0..<bigObjectCount {
-                        realm.add(SwiftHugeSyncObject())
-                    }
-                }
-                waitForUploads(for: realm)
-                checkCount(expected: bigObjectCount, realm, SwiftHugeSyncObject.self)
+        let user = try! synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
+        if !isParent {
+            populateRealm(user: user, url: realmURL)
+            return
+        }
+
+        var callCount = 0
+        var transferred = 0
+        var transferrable = 0
+        let realm = try! synchronouslyOpenRealm(url: realmURL, user: user)
+
+        let session = realm.syncSession
+        XCTAssertNotNil(session)
+        let ex = expectation(description: "streaming-downloads-expectation")
+        var hasBeenFulfilled = false
+        let token = session!.addProgressNotification(for: .download, mode: .reportIndefinitely) { p in
+            callCount += 1
+            XCTAssert(p.transferredBytes >= transferred)
+            XCTAssert(p.transferrableBytes >= transferrable)
+            transferred = p.transferredBytes
+            transferrable = p.transferrableBytes
+            if p.transferredBytes > 0 && p.isTransferComplete && !hasBeenFulfilled {
+                ex.fulfill()
+                hasBeenFulfilled = true
             }
-        } catch {
-            XCTFail("Got an error: \(error) (process: \(isParent ? "parent" : "child"))")
         }
+
+        // Wait for the child process to upload all the data.
+        executeChild()
+
+        waitForExpectations(timeout: 10.0, handler: nil)
+        token!.invalidate()
+        XCTAssert(callCount > 1)
+        XCTAssert(transferred >= transferrable)
     }
 
     func testStreamingUploadNotifier() {
-        let bigObjectCount = 2
         do {
             var transferred = 0
             var transferrable = 0
@@ -267,45 +272,86 @@ class SwiftObjectServerTests: SwiftSyncTestCase {
     // MARK: - Download Realm
 
     func testDownloadRealm() {
-        let bigObjectCount = 2
-        do {
-            let user = try synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
-            if isParent {
-                // Wait for the child process to upload everything.
-                executeChild()
-                let ex = expectation(description: "download-realm")
-                let config = user.configuration(realmURL: realmURL, fullSynchronization: true)
-                let pathOnDisk = ObjectiveCSupport.convert(object: config).pathOnDisk
-                XCTAssertFalse(FileManager.default.fileExists(atPath: pathOnDisk))
-                Realm.asyncOpen(configuration: config) { realm, error in
-                    XCTAssertNil(error)
-                    self.checkCount(expected: bigObjectCount, realm!, SwiftHugeSyncObject.self)
-                    ex.fulfill()
-                }
-                func fileSize(path: String) -> Int {
-                    if let attr = try? FileManager.default.attributesOfItem(atPath: path) {
-                        return attr[.size] as! Int
-                    }
-                    return 0
-                }
-                XCTAssertFalse(RLMHasCachedRealmForPath(pathOnDisk))
-                waitForExpectations(timeout: 10.0, handler: nil)
-                XCTAssertGreaterThan(fileSize(path: pathOnDisk), 0)
-                XCTAssertFalse(RLMHasCachedRealmForPath(pathOnDisk))
-            } else {
-                let realm = try synchronouslyOpenRealm(url: realmURL, user: user)
-                // Write lots of data to the Realm, then wait for it to be uploaded.
-                try realm.write {
-                    for _ in 0..<bigObjectCount {
-                        realm.add(SwiftHugeSyncObject())
-                    }
-                }
-                waitForUploads(for: realm)
-                checkCount(expected: bigObjectCount, realm, SwiftHugeSyncObject.self)
+        let user = try! synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
+        if !isParent {
+            populateRealm(user: user, url: realmURL)
+            return
+        }
+
+        // Wait for the child process to upload everything.
+        executeChild()
+
+        let ex = expectation(description: "download-realm")
+        let config = user.configuration(realmURL: realmURL, fullSynchronization: true)
+        let pathOnDisk = ObjectiveCSupport.convert(object: config).pathOnDisk
+        XCTAssertFalse(FileManager.default.fileExists(atPath: pathOnDisk))
+        Realm.asyncOpen(configuration: config) { realm, error in
+            XCTAssertNil(error)
+            self.checkCount(expected: self.bigObjectCount, realm!, SwiftHugeSyncObject.self)
+            ex.fulfill()
+        }
+        func fileSize(path: String) -> Int {
+            if let attr = try? FileManager.default.attributesOfItem(atPath: path) {
+                return attr[.size] as! Int
             }
-        } catch {
-            XCTFail("Got an error: \(error) (process: \(isParent ? "parent" : "child"))")
+            return 0
         }
+        XCTAssertFalse(RLMHasCachedRealmForPath(pathOnDisk))
+        waitForExpectations(timeout: 10.0, handler: nil)
+        XCTAssertGreaterThan(fileSize(path: pathOnDisk), 0)
+        XCTAssertFalse(RLMHasCachedRealmForPath(pathOnDisk))
+    }
+
+    func testCancelDownloadRealm() {
+        let user = try! synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
+        if !isParent {
+            populateRealm(user: user, url: realmURL)
+            return
+        }
+
+        // Wait for the child process to upload everything.
+        executeChild()
+
+        // Use a serial queue for asyncOpen to ensure that the first one adds
+        // the completion block before the second one cancels it
+        RLMSetAsyncOpenQueue(DispatchQueue(label: "io.realm.asyncOpen"))
+
+        let ex = expectation(description: "async open")
+        let config = user.configuration(realmURL: realmURL, fullSynchronization: true)
+        Realm.asyncOpen(configuration: config) { _, error in
+            XCTAssertNotNil(error)
+            ex.fulfill()
+        }
+        let task = Realm.asyncOpen(configuration: config) { _, _ in
+            XCTFail("Cancelled completion handler was called")
+        }
+        task.cancel()
+        waitForExpectations(timeout: 10.0, handler: nil)
+    }
+
+    func testAsyncOpenProgress() {
+        let user = try! synchronouslyLogInUser(for: basicCredentials(register: isParent), server: authURL)
+        if !isParent {
+            populateRealm(user: user, url: realmURL)
+            return
+        }
+
+        // Wait for the child process to upload everything.
+        executeChild()
+
+        let ex1 = expectation(description: "async open")
+        let ex2 = expectation(description: "download progress")
+        let config = user.configuration(realmURL: realmURL, fullSynchronization: true)
+        let task = Realm.asyncOpen(configuration: config) { _, error in
+            XCTAssertNil(error)
+            ex1.fulfill()
+        }
+        task.addProgressNotification { progress in
+            if progress.isTransferComplete {
+                ex2.fulfill()
+            }
+        }
+        waitForExpectations(timeout: 10.0, handler: nil)
     }
 
     // MARK: - Administration

+ 30 - 3
Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftPermissionsTests.swift

@@ -77,7 +77,7 @@ class SwiftPermissionsAPITests: SwiftSyncTestCase {
         // Create a new Realm with an admin user
         let admin = createAdminUser(for: SwiftSyncTestCase.authServerURL(),
                                     username: UUID().uuidString + "-admin")
-        let url = URL(string: "realm://127.0.0.1:9080/\(name)")!
+        let url = URL(string: "realm://127.0.0.1:9080/\(name.replacingOccurrences(of: "()", with: ""))")!
         let adminRealm = openRealm(url, admin)
         // FIXME: we currently need to add a subscription to get the permissions types sent to us
         subscribe(realm: adminRealm, type: SwiftSyncObject.self)
@@ -134,13 +134,40 @@ class SwiftPermissionsAPITests: SwiftSyncTestCase {
     }
 
     func add(user: SyncUser, toRole roleName: String, inRealm realm: Realm) {
-        let user = realm.create(RealmSwift.PermissionUser.self, value: [user.identity!], update: true)
-        realm.create(PermissionRole.self, value: [roleName], update: true).users.append(user)
+        let user = realm.create(RealmSwift.PermissionUser.self, value: [user.identity!], update: .modified)
+        realm.create(PermissionRole.self, value: [roleName], update: .modified).users.append(user)
     }
 
 
     // MARK: Tests
 
+    func testAsyncOpenWaitsForPermissions() {
+        let url = createRealm(name: #function) { realm in
+            createDefaultPermisisons(realm.permissions)
+            add(user: userA, toRole: "reader", inRealm: realm)
+        }
+
+        let ex = expectation(description: "asyncOpen")
+        var subscription: SyncSubscription<SwiftSyncObject>!
+        var token: NotificationToken!
+        Realm.asyncOpen(configuration: userA.configuration(realmURL: url)) { realm, error in
+            XCTAssertNil(error)
+            // Will crash if the __Class object for swiftSyncObject wasn't downloaded
+            _ = realm!.permissions(forType: SwiftSyncObject.self)
+
+            // Make sure that the dummy subscription we created hasn't interfered
+            // with adding new subscriptions.
+            subscription = realm!.objects(SwiftSyncObject.self).subscribe()
+            token = subscription.observe(\.state, options: .initial) { state in
+                if state == .complete {
+                    ex.fulfill()
+                }
+            }
+        }
+        waitForExpectations(timeout: 10.0, handler: nil)
+        token.invalidate()
+    }
+
     func testRealmRead() {
         let url = createRealm(name: "testRealmRead") { realm in
             createDefaultPermisisons(realm.permissions)

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list

@@ -1,4 +1,4 @@
-REALM_CORE_VERSION=5.19.1
-REALM_SYNC_VERSION=4.4.2
+REALM_CORE_VERSION=5.22.0
+REALM_SYNC_VERSION=4.6.1
 ANDROID_OPENSSL_VERSION=1.0.2k
 REALM_CORE_PACKAGING=2

+ 2 - 0
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/CMakeLists.txt

@@ -92,6 +92,7 @@ set(INCLUDE_DIRS
 
 if(REALM_ENABLE_SYNC)
     list(APPEND HEADERS
+        sync/async_open_task.hpp
         sync/partial_sync.hpp
         sync/subscription_state.hpp
         sync/sync_config.hpp
@@ -104,6 +105,7 @@ if(REALM_ENABLE_SYNC)
         sync/impl/sync_metadata.hpp
         sync/impl/work_queue.hpp)
     list(APPEND SOURCES
+        sync/async_open_task.cpp
         sync/partial_sync.cpp
         sync/sync_config.cpp
         sync/sync_manager.cpp

+ 3 - 3
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp

@@ -196,7 +196,7 @@ ExternalCommitHelper::~ExternalCommitHelper()
 
 void ExternalCommitHelper::listen()
 {
-    pthread_setname_np("RLMRealm notification listener");
+    pthread_setname_np("Realm notification listener");
 
     // Set up the kqueue
     // EVFILT_READ indicates that we care about data being available to read
@@ -214,11 +214,11 @@ void ExternalCommitHelper::listen()
         // Wait for data to become on either fd
         // Return code is number of bytes available or -1 on error
         ret = kevent(m_kq, nullptr, 0, &event, 1, nullptr);
-        assert(ret >= 0);
-        if (ret == 0) {
+        if (ret == 0 || (ret < 0 && errno == EINTR)) {
             // Spurious wakeup; just wait again
             continue;
         }
+        assert(ret > 0);
 
         // Check which file descriptor had activity: if it's the shutdown
         // pipe, then someone called -stop; otherwise it's the named pipe

+ 58 - 48
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/realm_coordinator.cpp

@@ -26,9 +26,12 @@
 #include "object_schema.hpp"
 #include "object_store.hpp"
 #include "schema.hpp"
+#include "thread_safe_reference.hpp"
 
 #if REALM_ENABLE_SYNC
 #include "sync/impl/work_queue.hpp"
+#include "sync/async_open_task.hpp"
+#include "sync/partial_sync.hpp"
 #include "sync/sync_config.hpp"
 #include "sync/sync_manager.hpp"
 #include "sync/sync_session.hpp"
@@ -76,7 +79,7 @@ std::shared_ptr<RealmCoordinator> RealmCoordinator::get_existing_coordinator(Str
     return it == s_coordinators_per_path.end() ? nullptr : it->second.lock();
 }
 
-void RealmCoordinator::create_sync_session(bool force_client_reset)
+void RealmCoordinator::create_sync_session(bool force_client_reset, bool validate_sync_history)
 {
 #if REALM_ENABLE_SYNC
     if (m_sync_session)
@@ -93,7 +96,7 @@ void RealmCoordinator::create_sync_session(bool force_client_reset)
     }
 
     auto sync_config = *m_config.sync_config;
-    sync_config.validate_sync_history = false;
+    sync_config.validate_sync_history = validate_sync_history;
     m_sync_session = SyncManager::shared().get_session(m_config.path, sync_config, force_client_reset);
 
     std::weak_ptr<RealmCoordinator> weak_self = shared_from_this();
@@ -180,16 +183,17 @@ void RealmCoordinator::set_config(const Realm::Config& config)
             }
         }
 #endif
+        // Mixing cached and uncached Realms is allowed
+        m_config.cache = config.cache;
 
         // Realm::update_schema() handles complaining about schema mismatches
     }
 }
 
-std::shared_ptr<Realm> RealmCoordinator::get_cached_realm(Realm::Config const& config)
+std::shared_ptr<Realm> RealmCoordinator::get_cached_realm(Realm::Config const& config, AnyExecutionContextID execution_context)
 {
     if (!config.cache)
         return nullptr;
-    AnyExecutionContextID execution_context(config.execution_context);
     for (auto& cached_realm : m_weak_realm_notifiers) {
         if (!cached_realm.is_cached_for_execution_context(execution_context))
             continue;
@@ -220,17 +224,34 @@ std::shared_ptr<Realm> RealmCoordinator::get_realm(Realm::Config config)
     // to acquire the same lock
     std::shared_ptr<Realm> realm;
     std::unique_lock<std::mutex> lock(m_realm_mutex);
+    set_config(config);
+    if ((realm = get_cached_realm(config, config.execution_context)))
+        return realm;
     do_get_realm(std::move(config), realm, lock);
     return realm;
 }
 
-void RealmCoordinator::do_get_realm(Realm::Config config, std::shared_ptr<Realm>& realm,
-                                    std::unique_lock<std::mutex>& realm_lock)
+std::shared_ptr<Realm> RealmCoordinator::get_realm()
 {
-    set_config(config);
-    if ((realm = get_cached_realm(config)))
-        return;
+    std::shared_ptr<Realm> realm;
+    std::unique_lock<std::mutex> lock(m_realm_mutex);
+    if ((realm = get_cached_realm(m_config, m_config.execution_context)))
+        return realm;
+    do_get_realm(m_config, realm, lock);
+    return realm;
+}
 
+ThreadSafeReference<Realm> RealmCoordinator::get_unbound_realm()
+{
+    ThreadSafeReference<Realm> ref;
+    std::unique_lock<std::mutex> lock(m_realm_mutex);
+    do_get_realm(m_config, ref.m_realm, lock, false);
+    return ref;
+}
+
+void RealmCoordinator::do_get_realm(Realm::Config config, std::shared_ptr<Realm>& realm,
+                                    std::unique_lock<std::mutex>& realm_lock, bool bind_to_context)
+{
     auto schema = std::move(config.schema);
     auto migration_function = std::move(config.migration_function);
     auto initialization_function = std::move(config.initialization_function);
@@ -247,61 +268,50 @@ void RealmCoordinator::do_get_realm(Realm::Config config, std::shared_ptr<Realm>
             throw RealmFileException(RealmFileException::Kind::AccessError, get_path(), ex.code().message(), "");
         }
     }
-    m_weak_realm_notifiers.emplace_back(realm, realm->config().cache);
+    m_weak_realm_notifiers.emplace_back(realm, realm->config().cache, bind_to_context);
 
     if (realm->config().sync_config)
-        create_sync_session(false);
+        create_sync_session(false, false);
 
     if (!m_audit_context && audit_factory)
         m_audit_context = audit_factory();
 
+    realm_lock.unlock();
     if (schema) {
-        realm_lock.unlock();
         realm->update_schema(std::move(*schema), config.schema_version, std::move(migration_function),
                              std::move(initialization_function));
     }
+#if REALM_ENABLE_SYNC
+    else if (realm->is_partial())
+        _impl::ensure_partial_sync_schema_initialized(*realm);
+#endif
 }
 
-void RealmCoordinator::get_realm(Realm::Config config,
-                                 std::function<void(std::shared_ptr<Realm>, std::exception_ptr)> callback)
+void RealmCoordinator::bind_to_context(Realm& realm, AnyExecutionContextID execution_context)
 {
-#if REALM_ENABLE_SYNC
-    if (config.sync_config) {
-        std::unique_lock<std::mutex> lock(m_realm_mutex);
-        set_config(config);
-        create_sync_session(!File::exists(m_config.path));
-        m_sync_session->wait_for_download_completion([callback, self = shared_from_this()](std::error_code ec) {
-            if (ec)
-                callback(nullptr, std::make_exception_ptr(std::system_error(ec)));
-            else {
-                std::shared_ptr<Realm> realm;
-                try {
-                    realm = self->get_realm();
-                }
-                catch (...) {
-                    return callback(nullptr, std::current_exception());
-                }
-                callback(realm, nullptr);
-            }
-        });
+    std::unique_lock<std::mutex> lock(m_realm_mutex);
+    for (auto& cached_realm : m_weak_realm_notifiers) {
+        if (!cached_realm.is_for_realm(&realm))
+            continue;
+        cached_realm.bind_to_execution_context(execution_context);
         return;
     }
-#endif
-
-    std::shared_ptr<Realm> realm;
-    try {
-        realm = get_realm(std::move(config));
-    }
-    catch (...) {
-        return callback(nullptr, std::current_exception());
-    }
-    callback(realm, nullptr);
+    REALM_TERMINATE("Invalid Realm passed to bind_to_context()");
 }
 
-std::shared_ptr<Realm> RealmCoordinator::get_realm()
+#if REALM_ENABLE_SYNC
+std::shared_ptr<AsyncOpenTask> RealmCoordinator::get_synchronized_realm(Realm::Config config)
 {
-    return get_realm(m_config);
+    if (!config.sync_config)
+        throw std::logic_error("This method is only available for fully synchronized Realms.");
+
+    std::unique_lock<std::mutex> lock(m_realm_mutex);
+    set_config(config);
+    bool exists = File::exists(m_config.path);
+    create_sync_session(!config.sync_config->is_partial && !exists, exists);
+    return std::make_shared<AsyncOpenTask>(shared_from_this(), m_sync_session);
 }
+#endif
 
 bool RealmCoordinator::get_cached_schema(Schema& schema, uint64_t& schema_version,
                                          uint64_t& transaction) const noexcept
@@ -351,7 +361,7 @@ void RealmCoordinator::advance_schema_cache(uint64_t previous, uint64_t next)
 
 RealmCoordinator::RealmCoordinator()
 #if REALM_ENABLE_SYNC
-: m_partial_sync_work_queue(std::make_unique<partial_sync::WorkQueue>())
+: m_partial_sync_work_queue(std::make_unique<_impl::partial_sync::WorkQueue>())
 #endif
 {
 }
@@ -971,12 +981,12 @@ void RealmCoordinator::process_available_async(Realm& realm)
 
 void RealmCoordinator::set_transaction_callback(std::function<void(VersionID, VersionID)> fn)
 {
-    create_sync_session(false);
+    create_sync_session(false, false);
     m_transaction_callback = std::move(fn);
 }
 
 #if REALM_ENABLE_SYNC
-partial_sync::WorkQueue& RealmCoordinator::partial_sync_work_queue()
+_impl::partial_sync::WorkQueue& RealmCoordinator::partial_sync_work_queue()
 {
     return *m_partial_sync_work_queue;
 }

+ 20 - 5
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/realm_coordinator.hpp

@@ -58,7 +58,23 @@ public:
     // configuration is compatible with the existing one
     std::shared_ptr<Realm> get_realm(Realm::Config config);
     std::shared_ptr<Realm> get_realm();
-    void get_realm(Realm::Config config, std::function<void(std::shared_ptr<Realm>, std::exception_ptr)> callback);
+#if REALM_ENABLE_SYNC
+    // Get a thread-local shared Realm with the given configuration
+    // If the Realm is not already present, it will be fully downloaded before being returned.
+    // If the Realm is already on disk, it will be fully synchronized before being returned.
+    // Timeouts and interruptions are not handled by this method and must be handled by upper layers.
+    std::shared_ptr<AsyncOpenTask> get_synchronized_realm(Realm::Config config);
+#endif
+
+    // Get a Realm which is not bound to the current execution context
+    ThreadSafeReference<Realm> get_unbound_realm();
+
+    // Get the existing cached Realm for the given execution context if it exists
+    std::shared_ptr<Realm> get_cached_realm(Realm::Config const&, AnyExecutionContextID);
+
+    // Bind an unbound Realm to a specific execution context. The Realm must
+    // be managed by this coordinator.
+    void bind_to_context(Realm& realm, AnyExecutionContextID);
 
     Realm::Config get_config() const { return m_config; }
 
@@ -144,7 +160,7 @@ public:
 
 #if REALM_ENABLE_SYNC
     // A work queue that can be used to perform background work related to partial sync.
-    partial_sync::WorkQueue& partial_sync_work_queue();
+    _impl::partial_sync::WorkQueue& partial_sync_work_queue();
 #endif
 
     AuditInterface* audit_context() const noexcept { return m_audit_context.get(); }
@@ -193,10 +209,9 @@ private:
     void pin_version(VersionID version);
 
     void set_config(const Realm::Config&);
-    void create_sync_session(bool force_client_reset);
+    void create_sync_session(bool force_client_reset, bool validate_sync_history);
     void do_get_realm(Realm::Config config, std::shared_ptr<Realm>& realm,
-                      std::unique_lock<std::mutex>& realm_lock);
-    std::shared_ptr<Realm> get_cached_realm(Realm::Config const& config);
+                      std::unique_lock<std::mutex>& realm_lock, bool bind_to_context=true);
 
     void run_async_notifiers();
     void open_helper_shared_group();

+ 11 - 4
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp

@@ -24,13 +24,12 @@
 using namespace realm;
 using namespace realm::_impl;
 
-
-WeakRealmNotifier::WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache)
+WeakRealmNotifier::WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache, bool bind_to_context)
 : m_realm(realm)
 , m_execution_context(realm->config().execution_context)
 , m_realm_key(realm.get())
 , m_cache(cache)
-, m_signal(std::make_shared<util::EventLoopSignal<Callback>>(Callback{realm}))
+, m_signal(bind_to_context ? std::make_shared<util::EventLoopSignal<Callback>>(Callback{realm}) : nullptr)
 {
 }
 
@@ -45,5 +44,13 @@ void WeakRealmNotifier::Callback::operator()() const
 
 void WeakRealmNotifier::notify()
 {
-    m_signal->notify();
+    if (m_signal)
+        m_signal->notify();
+}
+
+void WeakRealmNotifier::bind_to_execution_context(AnyExecutionContextID context)
+{
+    REALM_ASSERT(!m_signal);
+    m_signal = std::make_shared<util::EventLoopSignal<Callback>>(Callback{m_realm});
+    m_execution_context = context;
 }

+ 3 - 1
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/impl/weak_realm_notifier.hpp

@@ -39,7 +39,7 @@ namespace _impl {
 // a Realm instance is released from within a function holding the cache lock.
 class WeakRealmNotifier {
 public:
-    WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache);
+    WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache, bool bind_to_context);
     ~WeakRealmNotifier();
 
     // Get a strong reference to the cached realm
@@ -59,6 +59,8 @@ public:
 
     void notify();
 
+    void bind_to_execution_context(AnyExecutionContextID context);
+
 private:
     std::weak_ptr<Realm> m_realm;
     AnyExecutionContextID m_execution_context;

+ 1 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/list.hpp

@@ -270,8 +270,7 @@ void List::assign(Context& ctx, T&& values, bool update, bool update_only_diff)
             index++;
         });
         while (index < sz) {
-            remove(index);
-            sz--;
+            remove(--sz);
         }
     }
     else {

+ 32 - 43
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp

@@ -69,14 +69,36 @@ ValueType Object::get_property_value(ContextType& ctx, StringData prop_name)
 }
 
 namespace {
-template <class T, typename ValueType, typename ContextType>
-inline void do_update_value(ContextType& ctx, Table& table, ValueType& value, size_t col, size_t row, bool update_only_diff, bool is_default)
-{
-    auto new_val = ctx.template unbox<T>(value);
-    if (!update_only_diff || table.get<T>(col, row) != new_val) {
-        table.set(col, row, new_val, is_default);
+template <typename ValueType, typename ContextType>
+struct ValueUpdater {
+    ContextType& ctx;
+    Property const& property;
+    ValueType& value;
+    RowExpr row;
+    size_t col;
+    bool try_update;
+    bool update_only_diff;
+    bool is_default;
+
+    void operator()(RowExpr*)
+    {
+        ContextType child_ctx(ctx, property);
+        auto curr_link = row.get_link(col);
+        auto link = child_ctx.template unbox<RowExpr>(value, true, try_update, update_only_diff, curr_link);
+        if (!update_only_diff || curr_link != link.get_index()) {
+            row.set_link(col, link.get_index());
+        }
     }
-}
+
+    template<typename T>
+    void operator()(T*)
+    {
+        auto new_val = ctx.template unbox<T>(value);
+        if (!update_only_diff || row.get<T>(col) != new_val) {
+            row.set(col, new_val, is_default);
+        }
+    }
+};
 }
 
 template <typename ValueType, typename ContextType>
@@ -114,42 +136,9 @@ void Object::set_property_value_impl(ContextType& ctx, const Property &property,
         return;
     }
 
-    switch (property.type & ~PropertyType::Nullable) {
-        case PropertyType::Object: {
-            ContextType child_ctx(ctx, property);
-            auto curr_link = table.get_link(col,row);
-            auto link = child_ctx.template unbox<RowExpr>(value, true, try_update, update_only_diff, curr_link);
-            if (!update_only_diff || curr_link != link.get_index()) {
-                table.set_link(col, row, link.get_index(), is_default);
-            }
-            break;
-        }
-        case PropertyType::Bool:
-            do_update_value<bool>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Int:
-            do_update_value<int64_t>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Float:
-            do_update_value<float>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Double:
-            do_update_value<double>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::String:
-            do_update_value<StringData>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Data:
-            do_update_value<BinaryData>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Date:
-            do_update_value<Timestamp>(ctx, table, value, col, row, update_only_diff, is_default);
-            break;
-        case PropertyType::Any:
-            throw std::logic_error("not supported");
-        default:
-            REALM_COMPILER_HINT_UNREACHABLE();
-    }
+    ValueUpdater<ValueType, ContextType> updater{ctx, property, value,
+        table.get(row),col, try_update, update_only_diff, is_default};
+    switch_on_type(property.type, updater);
     ctx.did_change();
 }
 

+ 19 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/shared_realm.cpp

@@ -272,12 +272,26 @@ SharedRealm Realm::get_shared_realm(Config config)
     return coordinator->get_realm(std::move(config));
 }
 
-void Realm::get_shared_realm(Config config, std::function<void(SharedRealm, std::exception_ptr)> callback)
+SharedRealm Realm::get_shared_realm(ThreadSafeReference<Realm> ref, util::Optional<AbstractExecutionContextID> execution_context)
 {
+    REALM_ASSERT(ref.m_realm);
+    auto& config = ref.m_realm->config();
     auto coordinator = RealmCoordinator::get_coordinator(config.path);
-    coordinator->get_realm(std::move(config), callback);
+    if (auto realm = coordinator->get_cached_realm(config, execution_context))
+        return realm;
+    coordinator->bind_to_context(*ref.m_realm, execution_context);
+    ref.m_realm->m_execution_context = execution_context;
+    return std::move(ref.m_realm);
 }
 
+#if REALM_ENABLE_SYNC
+std::shared_ptr<AsyncOpenTask> Realm::get_synchronized_realm(Config config)
+{
+    auto coordinator = RealmCoordinator::get_coordinator(config.path);
+    return coordinator->get_synchronized_realm(std::move(config));
+}
+#endif
+
 void Realm::set_schema(Schema const& reference, Schema schema)
 {
     m_dynamic_schema = false;
@@ -806,6 +820,9 @@ void Realm::notify()
 
     if (m_binding_context) {
         m_binding_context->before_notify();
+        if (is_closed() || is_in_transaction()) {
+            return;
+        }
     }
 
     auto cleanup = util::make_scope_exit([this]() noexcept { m_is_sending_notifications = false; });

+ 13 - 8
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/shared_realm.hpp

@@ -32,6 +32,7 @@
 #include <memory>
 
 namespace realm {
+class AsyncOpenTask;
 class AuditInterface;
 class BindingContext;
 class Group;
@@ -261,15 +262,19 @@ public:
     // encryption key will raise an exception.
     static SharedRealm get_shared_realm(Config config);
 
-    // Open a Realm and then pass it to the callback.
+    // Get a Realm for the given execution context (or current thread if `none`)
+    // from the thread safe reference. May return a cached Realm or create a new one.
+    static SharedRealm get_shared_realm(ThreadSafeReference<Realm>, util::Optional<AbstractExecutionContextID> = util::none);
+
+#if REALM_ENABLE_SYNC
+    // Open a synchronized Realm and make sure it is fully up to date before
+    // returning it.
     //
-    // If SyncConfig is set, the callback will not be invoked until the latest
-    // Realm state has been fully downloaded. This will result in the callback
-    // being invoked on a different thread. The calling code should normally
-    // dispatch back to the desired thread and obtain a new reference to the
-    // Realm, only using the reference passed to the callback to keep the file
-    // open while this is happening.
-    static void get_shared_realm(Config config, std::function<void(SharedRealm, std::exception_ptr)> callback);
+    // It is possible to both cancel the download and listen to download progress
+    // using the `AsyncOpenTask` returned. Note that the download doesn't actually
+    // start until you call `AsyncOpenTask::start(callback)`
+    static std::shared_ptr<AsyncOpenTask> get_synchronized_realm(Config config);
+#endif
 
     // Updates a Realm to a given schema, using the Realm's pre-set schema mode.
     void update_schema(Schema schema, uint64_t version=0,

+ 19 - 1
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.hpp

@@ -19,7 +19,6 @@
 #ifndef REALM_THREAD_SAFE_REFERENCE_HPP
 #define REALM_THREAD_SAFE_REFERENCE_HPP
 
-
 #include <realm/group_shared.hpp>
 
 namespace realm {
@@ -32,6 +31,7 @@ class Results;
 class TableView;
 template<typename T> class BasicRow;
 typedef BasicRow<Table> Row;
+namespace _impl { class RealmCoordinator; }
 
 // Opaque type representing an object for handover
 class ThreadSafeReferenceBase {
@@ -108,6 +108,24 @@ class ThreadSafeReference<Results>: public ThreadSafeReferenceBase {
     // Precondition: Realm and handover are on same version.
     Results import_into_realm(std::shared_ptr<Realm> realm) &&;
 };
+
+template<>
+class ThreadSafeReference<Realm> {
+    friend class Realm;
+    friend class _impl::RealmCoordinator;
+
+    std::shared_ptr<Realm> m_realm;
+
+    ThreadSafeReference(std::shared_ptr<Realm>);
+    std::shared_ptr<Realm> resolve() &&;
+public:
+
+    ThreadSafeReference() = default;
+    ThreadSafeReference(ThreadSafeReference const&) = delete;
+    ThreadSafeReference(ThreadSafeReference &&) = default;
+    ThreadSafeReference& operator=(ThreadSafeReference const&) = delete;
+    ThreadSafeReference& operator=(ThreadSafeReference&&) = default;
+};
 }
 
 #endif /* REALM_THREAD_SAFE_REFERENCE_HPP */

+ 95 - 75
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/object.cpp

@@ -715,81 +715,101 @@ TEST_CASE("object") {
         REQUIRE(callback_called);
     }
 
-    SECTION("set existing fields to null with update") {
-        AnyDict initial_values{
-            {"pk", INT64_C(1)},
-            {"bool", true},
-            {"int", INT64_C(5)},
-            {"float", 2.2f},
-            {"double", 3.3},
-            {"string", "hello"s},
-            {"data", "olleh"s},
-            {"date", Timestamp(10, 20)},
-
-            {"bool array", AnyVec{true, false}},
-            {"int array", AnyVec{INT64_C(5), INT64_C(6)}},
-            {"float array", AnyVec{1.1f, 2.2f}},
-            {"double array", AnyVec{3.3, 4.4}},
-            {"string array", AnyVec{"a"s, "b"s, "c"s}},
-            {"data array", AnyVec{"d"s, "e"s, "f"s}},
-            {"date array", AnyVec{}},
-            {"object array", AnyVec{AnyDict{{"value", INT64_C(20)}}}},
-        };
-        r->begin_transaction();
-        auto obj = Object::create(d, r, *r->schema().find("all optional types"), util::Any(initial_values));
-
-        // Missing fields in dictionary do not update anything
-        Object::create(d, r, *r->schema().find("all optional types"), util::Any(AnyDict{{"pk", INT64_C(1)}}), true);
-
-        REQUIRE(any_cast<bool>(obj.get_property_value<util::Any>(d, "bool")) == true);
-        REQUIRE(any_cast<int64_t>(obj.get_property_value<util::Any>(d, "int")) == 5);
-        REQUIRE(any_cast<float>(obj.get_property_value<util::Any>(d, "float")) == 2.2f);
-        REQUIRE(any_cast<double>(obj.get_property_value<util::Any>(d, "double")) == 3.3);
-        REQUIRE(any_cast<std::string>(obj.get_property_value<util::Any>(d, "string")) == "hello");
-        REQUIRE(any_cast<Timestamp>(obj.get_property_value<util::Any>(d, "date")) == Timestamp(10, 20));
-
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "bool array")).get<util::Optional<bool>>(0) == true);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "int array")).get<util::Optional<int64_t>>(0) == 5);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "float array")).get<util::Optional<float>>(0) == 1.1f);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "double array")).get<util::Optional<double>>(0) == 3.3);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "string array")).get<StringData>(0) == "a");
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "date array")).size() == 0);
-
-        AnyDict null_values{
-            {"pk", INT64_C(1)},
-            {"bool", util::Any()},
-            {"int", util::Any()},
-            {"float", util::Any()},
-            {"double", util::Any()},
-            {"string", util::Any()},
-            {"data", util::Any()},
-            {"date", util::Any()},
-
-            {"bool array", AnyVec{util::Any()}},
-            {"int array", AnyVec{util::Any()}},
-            {"float array", AnyVec{util::Any()}},
-            {"double array", AnyVec{util::Any()}},
-            {"string array", AnyVec{util::Any()}},
-            {"data array", AnyVec{util::Any()}},
-            {"date array", AnyVec{Timestamp()}},
-        };
-        Object::create(d, r, *r->schema().find("all optional types"), util::Any(null_values), true);
-
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "bool").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "int").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "float").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "double").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "string").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "data").has_value());
-        REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "date").has_value());
-
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "bool array")).get<util::Optional<bool>>(0) == util::none);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "int array")).get<util::Optional<int64_t>>(0) == util::none);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "float array")).get<util::Optional<float>>(0) == util::none);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "double array")).get<util::Optional<double>>(0) == util::none);
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "string array")).get<StringData>(0) == StringData());
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "data array")).get<BinaryData>(0) == BinaryData());
-        REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "date array")).get<Timestamp>(0) == Timestamp());
+    for (auto diffed_update : {false, true}) {
+        SECTION("set existing fields to null with update "s + (diffed_update ? "(diffed)" : "(all)")) {
+            AnyDict initial_values{
+                {"pk", INT64_C(1)},
+                {"bool", true},
+                {"int", INT64_C(5)},
+                {"float", 2.2f},
+                {"double", 3.3},
+                {"string", "hello"s},
+                {"data", "olleh"s},
+                {"date", Timestamp(10, 20)},
+
+                {"bool array", AnyVec{true, false}},
+                {"int array", AnyVec{INT64_C(5), INT64_C(6)}},
+                {"float array", AnyVec{1.1f, 2.2f}},
+                {"double array", AnyVec{3.3, 4.4}},
+                {"string array", AnyVec{"a"s, "b"s, "c"s}},
+                {"data array", AnyVec{"d"s, "e"s, "f"s}},
+                {"date array", AnyVec{}},
+                {"object array", AnyVec{AnyDict{{"value", INT64_C(20)}}}},
+            };
+            r->begin_transaction();
+            auto obj = Object::create(d, r, *r->schema().find("all optional types"), util::Any(initial_values));
+
+            // Missing fields in dictionary do not update anything
+            Object::create(d, r, *r->schema().find("all optional types"),
+                           util::Any(AnyDict{{"pk", INT64_C(1)}}), true, diffed_update);
+
+            REQUIRE(any_cast<bool>(obj.get_property_value<util::Any>(d, "bool")) == true);
+            REQUIRE(any_cast<int64_t>(obj.get_property_value<util::Any>(d, "int")) == 5);
+            REQUIRE(any_cast<float>(obj.get_property_value<util::Any>(d, "float")) == 2.2f);
+            REQUIRE(any_cast<double>(obj.get_property_value<util::Any>(d, "double")) == 3.3);
+            REQUIRE(any_cast<std::string>(obj.get_property_value<util::Any>(d, "string")) == "hello");
+            REQUIRE(any_cast<Timestamp>(obj.get_property_value<util::Any>(d, "date")) == Timestamp(10, 20));
+
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "bool array")).get<util::Optional<bool>>(0) == true);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "int array")).get<util::Optional<int64_t>>(0) == 5);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "float array")).get<util::Optional<float>>(0) == 1.1f);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "double array")).get<util::Optional<double>>(0) == 3.3);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "string array")).get<StringData>(0) == "a");
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "date array")).size() == 0);
+
+            // Set all properties to null
+            AnyDict null_values{
+                {"pk", INT64_C(1)},
+                {"bool", util::Any()},
+                {"int", util::Any()},
+                {"float", util::Any()},
+                {"double", util::Any()},
+                {"string", util::Any()},
+                {"data", util::Any()},
+                {"date", util::Any()},
+
+                {"bool array", AnyVec{util::Any()}},
+                {"int array", AnyVec{util::Any()}},
+                {"float array", AnyVec{util::Any()}},
+                {"double array", AnyVec{util::Any()}},
+                {"string array", AnyVec{util::Any()}},
+                {"data array", AnyVec{util::Any()}},
+                {"date array", AnyVec{Timestamp()}},
+            };
+            Object::create(d, r, *r->schema().find("all optional types"), util::Any(null_values), true, diffed_update);
+
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "bool").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "int").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "float").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "double").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "string").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "data").has_value());
+            REQUIRE_FALSE(obj.get_property_value<util::Any>(d, "date").has_value());
+
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "bool array")).get<util::Optional<bool>>(0) == util::none);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "int array")).get<util::Optional<int64_t>>(0) == util::none);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "float array")).get<util::Optional<float>>(0) == util::none);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "double array")).get<util::Optional<double>>(0) == util::none);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "string array")).get<StringData>(0) == StringData());
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "data array")).get<BinaryData>(0) == BinaryData());
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "date array")).get<Timestamp>(0) == Timestamp());
+
+            // Set all properties back to non-null
+            Object::create(d, r, *r->schema().find("all optional types"), util::Any(initial_values), true, diffed_update);
+            REQUIRE(any_cast<bool>(obj.get_property_value<util::Any>(d, "bool")) == true);
+            REQUIRE(any_cast<int64_t>(obj.get_property_value<util::Any>(d, "int")) == 5);
+            REQUIRE(any_cast<float>(obj.get_property_value<util::Any>(d, "float")) == 2.2f);
+            REQUIRE(any_cast<double>(obj.get_property_value<util::Any>(d, "double")) == 3.3);
+            REQUIRE(any_cast<std::string>(obj.get_property_value<util::Any>(d, "string")) == "hello");
+            REQUIRE(any_cast<Timestamp>(obj.get_property_value<util::Any>(d, "date")) == Timestamp(10, 20));
+
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "bool array")).get<util::Optional<bool>>(0) == true);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "int array")).get<util::Optional<int64_t>>(0) == 5);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "float array")).get<util::Optional<float>>(0) == 1.1f);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "double array")).get<util::Optional<double>>(0) == 3.3);
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "string array")).get<StringData>(0) == "a");
+            REQUIRE(any_cast<List&&>(obj.get_property_value<util::Any>(d, "date array")).size() == 0);
+        }
     }
 
     SECTION("create throws for duplicate pk if update is not specified") {

+ 139 - 22
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/realm.cpp

@@ -29,9 +29,14 @@
 #include "property.hpp"
 #include "results.hpp"
 #include "schema.hpp"
+#include "thread_safe_reference.hpp"
 
 #include "impl/realm_coordinator.hpp"
 
+#if REALM_ENABLE_SYNC
+#include "sync/async_open_task.hpp"
+#endif
+
 #include <realm/group.hpp>
 #include <realm/util/scope_exit.hpp>
 
@@ -444,7 +449,8 @@ TEST_CASE("SharedRealm: get_shared_realm()") {
     }
 }
 
-TEST_CASE("SharedRealm: get_shared_realm() with callback") {
+#if REALM_ENABLE_SYNC
+TEST_CASE("Get Realm using Async Open", "[asyncOpen]") {
     TestFile local_config;
     local_config.schema_version = 1;
     local_config.schema = Schema{
@@ -453,17 +459,6 @@ TEST_CASE("SharedRealm: get_shared_realm() with callback") {
         }},
     };
 
-    SECTION("immediately invokes callback for non-sync realms") {
-        bool called = false;
-        Realm::get_shared_realm(local_config, [&](auto realm, auto error) {
-            REQUIRE(realm);
-            REQUIRE(!error);
-            called = true;
-        });
-        REQUIRE(called);
-    }
-
-#if REALM_ENABLE_SYNC
     if (!util::EventLoop::has_implementation())
         return;
 
@@ -484,12 +479,12 @@ TEST_CASE("SharedRealm: get_shared_realm() with callback") {
 
     SECTION("can open synced Realms that don't already exist") {
         std::atomic<bool> called{false};
-        Realm::get_shared_realm(config, [&](auto realm, auto error) {
-            REQUIRE(realm);
+        auto task = Realm::get_synchronized_realm(config);
+        task->start([&](auto ref, auto error) {
             REQUIRE(!error);
             called = true;
 
-            REQUIRE(realm->read_group().get_table("class_object"));
+            REQUIRE(Realm::get_shared_realm(std::move(ref))->read_group().get_table("class_object"));
         });
         util::EventLoop::main().run_until([&]{ return called.load(); });
         REQUIRE(called);
@@ -505,12 +500,12 @@ TEST_CASE("SharedRealm: get_shared_realm() with callback") {
         }
 
         std::atomic<bool> called{false};
-        Realm::get_shared_realm(config, [&](auto realm, auto error) {
-            REQUIRE(realm);
+        auto task = Realm::get_synchronized_realm(config);
+        task->start([&](auto ref, auto error) {
             REQUIRE(!error);
             called = true;
 
-            REQUIRE(realm->read_group().get_table("class_object")->size() == 1);
+            REQUIRE(Realm::get_shared_realm(std::move(ref))->read_group().get_table("class_object"));
         });
         util::EventLoop::main().run_until([&]{ return called.load(); });
         REQUIRE(called);
@@ -528,18 +523,64 @@ TEST_CASE("SharedRealm: get_shared_realm() with callback") {
         }
 
         std::atomic<bool> called{false};
-        Realm::get_shared_realm(config, [&](auto realm, auto error) {
-            REQUIRE(realm);
+        auto task = Realm::get_synchronized_realm(config);
+        task->start([&](auto ref, auto error) {
             REQUIRE(!error);
             called = true;
 
-            REQUIRE(realm->read_group().get_table("class_object")->size() == 1);
+            REQUIRE(Realm::get_shared_realm(std::move(ref))->read_group().get_table("class_object")->size() == 1);
         });
         util::EventLoop::main().run_until([&]{ return called.load(); });
         REQUIRE(called);
     }
-#endif
+
+    SECTION("can download partial Realms") {
+        config.sync_config->is_partial = true;
+        config2.sync_config->is_partial = true;
+        {
+            auto realm = Realm::get_shared_realm(config2);
+            realm->begin_transaction();
+            sync::create_object(realm->read_group(), *realm->read_group().get_table("class_object"));
+            realm->commit_transaction();
+            wait_for_upload(*realm);
+        }
+
+        std::atomic<bool> called{false};
+        auto task = Realm::get_synchronized_realm(config);
+        task->start([&](auto, auto error) {
+            REQUIRE(!error);
+            called = true;
+        });
+        util::EventLoop::main().run_until([&]{ return called.load(); });
+        REQUIRE(called);
+
+        // No subscriptions, so no objects
+        REQUIRE(Realm::get_shared_realm(config)->read_group().get_table("class_object")->size() == 0);
+    }
+
+    SECTION("can download multiple Realms at a time") {
+        SyncTestFile config1(server, "realm1");
+        SyncTestFile config2(server, "realm2");
+        SyncTestFile config3(server, "realm3");
+        SyncTestFile config4(server, "realm4");
+
+        std::vector<std::shared_ptr<AsyncOpenTask>> tasks = {
+            Realm::get_synchronized_realm(config1),
+            Realm::get_synchronized_realm(config2),
+            Realm::get_synchronized_realm(config3),
+            Realm::get_synchronized_realm(config4),
+        };
+
+        std::atomic<int> completed{0};
+        for (auto& task : tasks) {
+            task->start([&](auto, auto) {
+                ++completed;
+            });
+        }
+        util::EventLoop::main().run_until([&]{ return completed == 4; });
+    }
 }
+#endif
 
 TEST_CASE("SharedRealm: notifications") {
     if (!util::EventLoop::has_implementation())
@@ -1802,3 +1843,79 @@ TEST_CASE("BindingContext is notified in case of notifier errors") {
     }
 }
 #endif
+
+TEST_CASE("RealmCoordinator: get_unbound_realm()") {
+    TestFile config;
+    config.schema = Schema{
+        {"object", {
+            {"value", PropertyType::Int}
+        }},
+    };
+
+    ThreadSafeReference<Realm> ref;
+    std::thread([&] { ref = _impl::RealmCoordinator::get_coordinator(config)->get_unbound_realm(); }).join();
+
+    SECTION("checks thread after being resolved") {
+        auto realm = Realm::get_shared_realm(std::move(ref));
+        REQUIRE_NOTHROW(realm->verify_thread());
+        std::thread([&] {
+            REQUIRE_THROWS(realm->verify_thread());
+        }).join();
+    }
+
+    SECTION("delivers notifications to the thread it is resolved on") {
+        if (!util::EventLoop::has_implementation())
+            return;
+        auto realm = Realm::get_shared_realm(std::move(ref));
+        Results results(realm, ObjectStore::table_for_object_type(realm->read_group(), "object")->where());
+        bool called = false;
+        auto token = results.add_notification_callback([&](CollectionChangeSet, std::exception_ptr) {
+            called = true;
+        });
+        util::EventLoop::main().run_until([&] { return called; });
+    }
+
+    SECTION("does not check thread if resolved using an execution context") {
+        auto realm = Realm::get_shared_realm(std::move(ref), AbstractExecutionContextID(1));
+        REQUIRE_NOTHROW(realm->verify_thread());
+        std::thread([&] {
+            REQUIRE_NOTHROW(realm->verify_thread());
+        }).join();
+    }
+
+    SECTION("resolves to existing cached Realm for the thread if caching is enabled") {
+        auto r1 = Realm::get_shared_realm(config);
+        auto r2 = Realm::get_shared_realm(std::move(ref));
+        REQUIRE(r1 == r2);
+    }
+
+    SECTION("resolves to existing cached Realm for the execution context if caching is enabled") {
+        config.execution_context = AbstractExecutionContextID(1);
+        auto r1 = Realm::get_shared_realm(config);
+        config.execution_context = AbstractExecutionContextID(2);
+        auto r2 = Realm::get_shared_realm(config);
+        auto r3 = Realm::get_shared_realm(std::move(ref), AbstractExecutionContextID(1));
+        REQUIRE(r1 == r3);
+        REQUIRE(r1 != r2);
+        REQUIRE(r2 != r3);
+    }
+
+    SECTION("resolves to a new Realm if caching is disabled") {
+        // Cache disabled for local realm, enabled for unbound
+        config.cache = false;
+        auto r1 = Realm::get_shared_realm(config);
+        auto r2 = Realm::get_shared_realm(std::move(ref));
+        REQUIRE(r1 != r2);
+
+        // New unbound with cache disabled
+        std::thread([&] { ref = _impl::RealmCoordinator::get_coordinator(config)->get_unbound_realm(); }).join();
+        auto r3 = Realm::get_shared_realm(std::move(ref));
+        REQUIRE(r1 != r3);
+        REQUIRE(r2 != r3);
+
+        // New local with cache enabled should grab the resolved unbound
+        config.cache = true;
+        auto r4 = Realm::get_shared_realm(config);
+        REQUIRE(r4 == r2);
+    }
+}

+ 11 - 7
Carthage/Checkouts/realm-cocoa/Realm/RLMAccessor.mm

@@ -114,7 +114,7 @@ void setValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex,
         return;
     }
 
-    RLMAddObjectToRealm(val, obj->_realm, false);
+    RLMAddObjectToRealm(val, obj->_realm, RLMUpdatePolicyError);
 
     // make sure it is the correct type
     if (val->_row.get_table() != obj->_row.get_table()->get_link_target(colIndex)) {
@@ -724,12 +724,16 @@ realm::util::Optional<int64_t> RLMAccessorContext::unbox(__unsafe_unretained id
 }
 
 template<>
-realm::RowExpr RLMAccessorContext::unbox(__unsafe_unretained id const v, bool create, bool update, bool, size_t) {
+realm::RowExpr RLMAccessorContext::unbox(__unsafe_unretained id const v, bool create, bool update, bool diff, size_t) {
+    RLMUpdatePolicy policy = !update ? RLMUpdatePolicyError
+                           : !diff   ? RLMUpdatePolicyUpdateAll
+                           :           RLMUpdatePolicyUpdateChanged;
+
     RLMObjectBase *link = RLMDynamicCast<RLMObjectBase>(v);
     if (!link) {
         if (!create)
             return realm::RowExpr();
-        return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, v, update)->_row;
+        return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, v, policy)->_row;
     }
 
     if (link.isInvalidated) {
@@ -743,7 +747,7 @@ realm::RowExpr RLMAccessorContext::unbox(__unsafe_unretained id const v, bool cr
 
     if (![link->_objectSchema.className isEqualToString:_info.rlmObjectSchema.className]) {
         if (create && !_promote_existing)
-            return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, link, update)->_row;
+            return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, link, policy)->_row;
         return link->_row;
     }
 
@@ -751,13 +755,13 @@ realm::RowExpr RLMAccessorContext::unbox(__unsafe_unretained id const v, bool cr
         if (!create)
             return realm::RowExpr();
         if (!_promote_existing)
-            return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, link, update)->_row;
-        RLMAddObjectToRealm(link, _realm, update);
+            return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, link, policy)->_row;
+        RLMAddObjectToRealm(link, _realm, policy);
     }
     else if (link->_realm != _realm) {
         if (_promote_existing)
             @throw RLMException(@"Object is already managed by another Realm. Use create instead to copy it into this Realm.");
-        return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, v, update)->_row;
+        return RLMCreateObjectInRealmWithValue(_realm, _info.rlmObjectSchema.className, v, policy)->_row;
     }
     return link->_row;
 }

+ 4 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMAnalytics.mm

@@ -72,7 +72,9 @@
 #import "RLMVersion.h"
 #endif
 
+#if REALM_ENABLE_SYNC
 #import <realm/sync/version.hpp>
+#endif
 
 // Declared for RealmSwiftObjectUtil
 @interface NSObject (SwiftVersion)
@@ -199,7 +201,9 @@ static NSDictionary *RLMAnalyticsPayload() {
                      @"Binding": @"cocoa",
                      @"Language": isSwift ? @"swift" : @"objc",
                      @"Realm Version": REALM_COCOA_VERSION,
+#if REALM_ENABLE_SYNC
                      @"Sync Version": @(REALM_SYNC_VER_STRING),
+#endif
 #if TARGET_OS_WATCH
                      @"Target OS Type": @"watchos",
 #elif TARGET_OS_TV

+ 97 - 2
Carthage/Checkouts/realm-cocoa/Realm/RLMObject.h

@@ -194,10 +194,13 @@ NS_ASSUME_NONNULL_BEGIN
  argument's type is the same as the receiver, and the objects have identical values for
  their managed properties, this method does nothing.
 
- If the object is being updated, all properties defined in its schema will be set by copying from
+ If the object is being updated, each property defined in its schema will be set by copying from
  `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
  given property name (or getter name, if defined), that value will remain untouched.
  Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
+ Each property is set even if the existing value is the same as the new value being set, and
+ notifications will report them all being changed. See `createOrUpdateModifiedInDefaultRealmWithValue:`
+ for a version of this function which only sets the values which have changed.
 
  If the `value` argument is an array, all properties must be present, valid and in the same
  order as the properties defined in the model.
@@ -208,6 +211,50 @@ NS_ASSUME_NONNULL_BEGIN
  */
 + (instancetype)createOrUpdateInDefaultRealmWithValue:(id)value;
 
+/**
+ Creates or updates a Realm object within the default Realm.
+
+ This method may only be called on Realm object types with a primary key defined. If there is already
+ an object with the same primary key value in the default Realm, its values are updated and the object
+ is returned. Otherwise, this method creates and populates a new instance of the object in the default Realm.
+
+ If nested objects are included in the argument, `createOrUpdateModifiedInDefaultRealmWithValue:` will be
+ recursively called on them if they have primary keys, `createInDefaultRealmWithValue:` if they do not.
+
+ The `value` argument is used to populate the object. It can be a Realm object, a key-value coding
+ compliant object, an array or dictionary returned from the methods in `NSJSONSerialization`, or an
+ array containing one element for each managed property.
+
+ If the object is being created, an exception will be thrown if any required properties
+ are not present and those properties were not defined with default values.
+
+ If the `value` argument is a Realm object already managed by the default Realm, the
+ argument's type is the same as the receiver, and the objects have identical values for
+ their managed properties, this method does nothing.
+
+ If the object is being updated, each property defined in its schema will be set by copying from
+ `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
+ given property name (or getter name, if defined), that value will remain untouched.
+ Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
+ Unlike `createOrUpdateInDefaultRealmWithValue:`, only properties which have changed in value are
+ set, and any change notifications produced by this call will report only which properies have
+ actually changed.
+
+ Checking which properties have changed imposes a small amount of overhead, and so this method
+ may be slower when all or nearly all of the properties being set have changed. If most or all
+ of the properties being set have not changed, this method will be much faster than unconditionally
+ setting all of them, and will also reduce how much data has to be written to the Realm, saving
+ both i/o time and disk space.
+
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
+
+ @param value    The value used to populate the object.
+
+ @see   `defaultPropertyValues`, `primaryKey`
+ */
++ (instancetype)createOrUpdateModifiedInDefaultRealmWithValue:(id)value;
+
 /**
  Creates or updates an Realm object within a specified Realm.
 
@@ -229,10 +276,13 @@ NS_ASSUME_NONNULL_BEGIN
  argument's type is the same as the receiver, and the objects have identical values for
  their managed properties, this method does nothing.
 
- If the object is being updated, all properties defined in its schema will be set by copying from
+ If the object is being updated, each property defined in its schema will be set by copying from
  `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
  given property name (or getter name, if defined), that value will remain untouched.
  Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
+ Each property is set even if the existing value is the same as the new value being set, and
+ notifications will report them all being changed. See `createOrUpdateModifiedInRealm:withValue:`
+ for a version of this function which only sets the values which have changed.
 
  If the `value` argument is an array, all properties must be present, valid and in the same
  order as the properties defined in the model.
@@ -244,6 +294,51 @@ NS_ASSUME_NONNULL_BEGIN
  */
 + (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value;
 
+/**
+ Creates or updates an Realm object within a specified Realm.
+
+ This method may only be called on Realm object types with a primary key defined. If there is already
+ an object with the same primary key value in the given Realm, its values are updated and the object
+ is returned. Otherwise this method creates and populates a new instance of this object in the given Realm.
+
+ If nested objects are included in the argument, `createOrUpdateInRealm:withValue:` will be
+ recursively called on them if they have primary keys, `createInRealm:withValue:` if they do not.
+
+ The `value` argument is used to populate the object. It can be a Realm object, a key-value coding
+ compliant object, an array or dictionary returned from the methods in `NSJSONSerialization`, or an
+ array containing one element for each managed property.
+
+ If the object is being created, an exception will be thrown if any required properties
+ are not present and those properties were not defined with default values.
+
+ If the `value` argument is a Realm object already managed by the given Realm, the
+ argument's type is the same as the receiver, and the objects have identical values for
+ their managed properties, this method does nothing.
+
+ If the object is being updated, each property defined in its schema will be set by copying from
+ `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
+ given property name (or getter name, if defined), that value will remain untouched.
+ Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
+ Unlike `createOrUpdateInRealm:withValue:`, only properties which have changed in value are
+ set, and any change notifications produced by this call will report only which properies have
+ actually changed.
+
+ Checking which properties have changed imposes a small amount of overhead, and so this method
+ may be slower when all or nearly all of the properties being set have changed. If most or all
+ of the properties being set have not changed, this method will be much faster than unconditionally
+ setting all of them, and will also reduce how much data has to be written to the Realm, saving
+ both i/o time and disk space.
+
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
+
+ @param realm    The Realm which should own the object.
+ @param value    The value used to populate the object.
+
+ @see   `defaultPropertyValues`, `primaryKey`
+ */
++ (instancetype)createOrUpdateModifiedInRealm:(RLMRealm *)realm withValue:(id)value;
+
 #pragma mark - Properties
 
 /**

+ 13 - 9
Carthage/Checkouts/realm-cocoa/Realm/RLMObject.mm

@@ -72,25 +72,29 @@
 #pragma mark - Class-based Object Creation
 
 + (instancetype)createInDefaultRealmWithValue:(id)value {
-    return (RLMObject *)RLMCreateObjectInRealmWithValue([RLMRealm defaultRealm], [self className], value, false);
+    return (RLMObject *)RLMCreateObjectInRealmWithValue([RLMRealm defaultRealm], [self className], value, RLMUpdatePolicyError);
 }
 
 + (instancetype)createInRealm:(RLMRealm *)realm withValue:(id)value {
-    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, false);
+    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyError);
 }
 
 + (instancetype)createOrUpdateInDefaultRealmWithValue:(id)value {
     return [self createOrUpdateInRealm:[RLMRealm defaultRealm] withValue:value];
 }
 
++ (instancetype)createOrUpdateModifiedInDefaultRealmWithValue:(id)value {
+    return [self createOrUpdateModifiedInRealm:[RLMRealm defaultRealm] withValue:value];
+}
+
 + (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value {
-    // verify primary key
-    RLMObjectSchema *schema = [self sharedSchema];
-    if (!schema.primaryKeyProperty) {
-        NSString *reason = [NSString stringWithFormat:@"'%@' does not have a primary key and can not be updated", schema.className];
-        @throw [NSException exceptionWithName:@"RLMExecption" reason:reason userInfo:nil];
-    }
-    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, true);
+    RLMVerifyHasPrimaryKey(self);
+    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyUpdateAll);
+}
+
++ (instancetype)createOrUpdateModifiedInRealm:(RLMRealm *)realm withValue:(id)value {
+    RLMVerifyHasPrimaryKey(self);
+    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyUpdateChanged);
 }
 
 #pragma mark - Subscripting

+ 6 - 1
Carthage/Checkouts/realm-cocoa/Realm/RLMObjectSchema.mm

@@ -328,7 +328,12 @@ const Ivar RLMDummySwiftIvar = []() {
                 // or it might be a String?, Data?, Date? or object field with
                 // a nil default value
                 else if (md.kind == RLMSwiftPropertyKindNilLiteralOptional) {
-                    propArray[existing].optional = true;
+                    RLMProperty *prop = propArray[existing];
+                    // RLMLinkingObjects properties on RLMObjects are allowed
+                    // to be optional as they'll be `nil` for unmanaged objects
+                    if (prop.type != RLMPropertyTypeLinkingObjects) {
+                        prop.optional = true;
+                    }
                 }
                 // or it may be some non-optional property which may have been
                 // previously marked as optional due to that being the default

+ 10 - 3
Carthage/Checkouts/realm-cocoa/Realm/RLMObjectStore.h

@@ -24,8 +24,16 @@ extern "C" {
 
 @class RLMRealm, RLMSchema, RLMObjectBase, RLMResults, RLMProperty;
 
+typedef NS_ENUM(NSUInteger, RLMUpdatePolicy) {
+    RLMUpdatePolicyError = 0,
+    RLMUpdatePolicyUpdateChanged = 1,
+    RLMUpdatePolicyUpdateAll = 2,
+};
+
 NS_ASSUME_NONNULL_BEGIN
 
+void RLMVerifyHasPrimaryKey(Class cls);
+
 //
 // Accessor Creation
 //
@@ -39,7 +47,7 @@ void RLMRealmCreateAccessors(RLMSchema *schema);
 //
 
 // add an object to the given realm
-void RLMAddObjectToRealm(RLMObjectBase *object, RLMRealm *realm, bool createOrUpdate);
+void RLMAddObjectToRealm(RLMObjectBase *object, RLMRealm *realm, RLMUpdatePolicy);
 
 // delete an object from its realm
 void RLMDeleteObjectFromRealm(RLMObjectBase *object, RLMRealm *realm);
@@ -56,10 +64,9 @@ id _Nullable RLMGetObject(RLMRealm *realm, NSString *objectClassName, id _Nullab
 
 // create object from array or dictionary
 RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className,
-                                               id _Nullable value, bool createOrUpdate)
+                                               id _Nullable value, RLMUpdatePolicy updatePolicy)
 NS_RETURNS_RETAINED;
 
-
 //
 // Accessor Creation
 //

+ 18 - 5
Carthage/Checkouts/realm-cocoa/Realm/RLMObjectStore.mm

@@ -36,6 +36,8 @@
 #import "results.hpp"
 #import "shared_realm.hpp"
 
+#import <realm/group.hpp>
+
 #import <objc/message.h>
 
 using namespace realm;
@@ -112,9 +114,17 @@ void RLMInitializeSwiftAccessorGenerics(__unsafe_unretained RLMObjectBase *const
     }
 }
 
+void RLMVerifyHasPrimaryKey(Class cls) {
+    RLMObjectSchema *schema = [cls sharedSchema];
+    if (!schema.primaryKeyProperty) {
+        NSString *reason = [NSString stringWithFormat:@"'%@' does not have a primary key and can not be updated", schema.className];
+        @throw [NSException exceptionWithName:@"RLMException" reason:reason userInfo:nil];
+    }
+}
+
 void RLMAddObjectToRealm(__unsafe_unretained RLMObjectBase *const object,
                          __unsafe_unretained RLMRealm *const realm,
-                         bool createOrUpdate) {
+                         RLMUpdatePolicy updatePolicy) {
     RLMVerifyInWriteTransaction(realm);
 
     // verify that object is unmanaged
@@ -140,7 +150,9 @@ void RLMAddObjectToRealm(__unsafe_unretained RLMObjectBase *const object,
     object->_objectSchema = info.rlmObjectSchema;
     try {
         realm::Object::create(c, realm->_realm, *info.objectSchema, (id)object,
-                              createOrUpdate, /* diff */ false, -1, &object->_row);
+                              updatePolicy != RLMUpdatePolicyError,
+                              updatePolicy == RLMUpdatePolicyUpdateChanged,
+                              -1, &object->_row);
     }
     catch (std::exception const& e) {
         @throw RLMException(e);
@@ -150,10 +162,10 @@ void RLMAddObjectToRealm(__unsafe_unretained RLMObjectBase *const object,
 }
 
 RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className,
-                                               id value, bool createOrUpdate = false) {
+                                               id value, RLMUpdatePolicy updatePolicy) {
     RLMVerifyInWriteTransaction(realm);
 
-    if (createOrUpdate && RLMIsObjectSubclass([value class])) {
+    if (updatePolicy != RLMUpdatePolicyError && RLMIsObjectSubclass([value class])) {
         RLMObjectBase *obj = value;
         if (obj->_realm == realm && [obj->_objectSchema.className isEqualToString:className]) {
             // This is a no-op if value is an RLMObject of the same type already backed by the target realm.
@@ -176,7 +188,8 @@ RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *classN
     RLMObjectBase *object = RLMCreateManagedAccessor(info.rlmObjectSchema.accessorClass, realm, &info);
     try {
         object->_row = realm::Object::create(c, realm->_realm, *info.objectSchema,
-                                             (id)value, createOrUpdate).row();
+                                             (id)value, updatePolicy != RLMUpdatePolicyError,
+                                             updatePolicy == RLMUpdatePolicyUpdateChanged).row();
     }
     catch (std::exception const& e) {
         @throw RLMException(e);

+ 37 - 10
Carthage/Checkouts/realm-cocoa/Realm/RLMProperty.mm

@@ -318,12 +318,6 @@ static realm::util::Optional<RLMPropertyType> typeFromProtocolString(const char
             case 'R':
                 *readOnly = true;
                 break;
-            case 'N':
-                // nonatomic
-                break;
-            case 'D':
-                // dynamic
-                break;
             case 'G':
                 _getterName = @(attrs[i].value);
                 break;
@@ -333,6 +327,25 @@ static realm::util::Optional<RLMPropertyType> typeFromProtocolString(const char
             case 'V': // backing ivar name
                 *computed = false;
                 break;
+
+            case '&':
+                // retain/assign
+                break;
+            case 'C':
+                // copy
+                break;
+            case 'D':
+                // dynamic
+                break;
+            case 'N':
+                // nonatomic
+                break;
+            case 'P':
+                // GC'able
+                break;
+            case 'W':
+                // weak
+                break;
             default:
                 break;
         }
@@ -364,12 +377,26 @@ static realm::util::Optional<RLMPropertyType> typeFromProtocolString(const char
     bool readOnly = false;
     bool isComputed = false;
     [self parseObjcProperty:property readOnly:&readOnly computed:&isComputed rawType:&rawType];
+
+    // Swift sometimes doesn't explicitly set the ivar name in the metadata, so check if
+    // there's an ivar with the same name as the property.
+    if (!readOnly && isComputed && class_getInstanceVariable([obj class], name.UTF8String)) {
+        isComputed = false;
+    }
+
+    // Check if there's a storage ivar for a lazy property in this name. We don't honor
+    // @lazy in managed objects, but allow it for unmanaged objects which are
+    // subclasses of RLMObject (but not RealmSwift.Object). It's unclear if there's a
+    // good reason for this difference.
     if (!readOnly && isComputed) {
-        // Check for lazy property.
+        // Xcode 10 and earlier
         NSString *backingPropertyName = [NSString stringWithFormat:@"%@.storage", name];
-        if (class_getInstanceVariable([obj class], backingPropertyName.UTF8String)) {
-            isComputed = false;
-        }
+        isComputed = !class_getInstanceVariable([obj class], backingPropertyName.UTF8String);
+    }
+    if (!readOnly && isComputed) {
+        // Xcode 11
+        NSString *backingPropertyName = [NSString stringWithFormat:@"$__lazy_storage_$_%@", name];
+        isComputed = !class_getInstanceVariable([obj class], backingPropertyName.UTF8String);
     }
 
     if (readOnly || isComputed) {

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h

@@ -19,7 +19,7 @@
 #import <Foundation/Foundation.h>
 #import "RLMConstants.h"
 
-@class RLMRealmConfiguration, RLMRealm, RLMObject, RLMSchema, RLMMigration, RLMNotificationToken, RLMThreadSafeReference;
+@class RLMRealmConfiguration, RLMRealm, RLMObject, RLMSchema, RLMMigration, RLMNotificationToken, RLMThreadSafeReference, RLMAsyncOpenTask;
 struct RLMRealmPrivileges;
 struct RLMClassPrivileges;
 struct RLMObjectPrivileges;
@@ -121,7 +121,7 @@ NS_ASSUME_NONNULL_BEGIN
        thread, accessing the returned Realm outside the callback block (even if
        accessed from `callbackQueue`) is unsafe.
  */
-+ (void)asyncOpenWithConfiguration:(RLMRealmConfiguration *)configuration
++ (RLMAsyncOpenTask *)asyncOpenWithConfiguration:(RLMRealmConfiguration *)configuration
                      callbackQueue:(dispatch_queue_t)callbackQueue
                           callback:(RLMAsyncOpenRealmCallback)callback;
 

+ 124 - 55
Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm

@@ -32,8 +32,6 @@
 #import "RLMRealmConfiguration_Private.hpp"
 #import "RLMRealmUtil.hpp"
 #import "RLMSchema_Private.hpp"
-#import "RLMSyncManager_Private.h"
-#import "RLMSyncUtil_Private.hpp"
 #import "RLMThreadSafeReference_Private.hpp"
 #import "RLMUpdateChecker.hpp"
 #import "RLMUtil.hpp"
@@ -42,12 +40,20 @@
 #include "object_store.hpp"
 #include "schema.hpp"
 #include "shared_realm.hpp"
+#include "thread_safe_reference.hpp"
 
 #include <realm/disable_sync_to_disk.hpp>
 #include <realm/util/scope_exit.hpp>
 #include <realm/version.hpp>
 
+#if REALM_ENABLE_SYNC
+#import "RLMSyncManager_Private.h"
+#import "RLMSyncSession_Private.hpp"
+#import "RLMSyncUtil_Private.hpp"
+
+#import "sync/async_open_task.hpp"
 #import "sync/sync_session.hpp"
+#endif
 
 using namespace realm;
 using util::File;
@@ -102,6 +108,13 @@ static void RLMAddSkipBackupAttributeToItemAtPath(std::string const& path) {
 }
 @end
 
+#if !REALM_ENABLE_SYNC
+@interface RLMAsyncOpenTask : NSObject
+@end
+@implementation RLMAsyncOpenTask
+@end
+#endif
+
 static bool shouldForciblyDisableEncryption() {
     static bool disableEncryption = getenv("REALM_DISABLE_ENCRYPTION");
     return disableEncryption;
@@ -183,69 +196,123 @@ NSData *RLMRealmValidatedEncryptionKey(NSData *key) {
     return [RLMRealm realmWithConfiguration:configuration error:nil];
 }
 
-+ (void)asyncOpenWithConfiguration:(RLMRealmConfiguration *)configuration
-                     callbackQueue:(dispatch_queue_t)callbackQueue
-                          callback:(RLMAsyncOpenRealmCallback)callback {
-    RLMRealm *strongReferenceToSyncedRealm = nil;
-    if (configuration.config.sync_config) {
-        NSError *error = nil;
-        strongReferenceToSyncedRealm = [RLMRealm uncachedSchemalessRealmWithConfiguration:configuration error:&error];
-        if (error) {
-            dispatch_async(callbackQueue, ^{
-                callback(nil, error);
-            });
-            return;
-        }
-    }
-    static dispatch_queue_t queue = dispatch_queue_create("io.realm.asyncOpenDispatchQueue", DISPATCH_QUEUE_CONCURRENT);
-    dispatch_async(queue, ^{
+// The server doesn't send us the subscriptions for permission types until the
+// first subscription is created. This is fine for synchronous opens (if we're
+// creating a new Realm we create the permission objects ourselves), but it
+// causes issues for asyncOpen because it means that when our download completes
+// we don't actually have the full Realm state yet.
+static void waitForPartialSyncSubscriptions(Realm::Config const& config) {
+#if REALM_ENABLE_SYNC
+    auto realm = Realm::get_shared_realm(config);
+    auto table = ObjectStore::table_for_object_type(realm->read_group(), "__ResultSets");
+
+    realm->begin_transaction();
+    size_t row = realm::sync::create_object(realm->read_group(), *table);
+
+    // Set expires_at to time 0 so that this object will be cleaned up the first
+    // time the user creates a subscription
+    size_t expires_at_col = table->get_column_index("expires_at");
+    if (expires_at_col == npos) {
+        expires_at_col = table->add_column(type_Timestamp, "expires_at", true);
+    }
+    table->set_timestamp(expires_at_col, row, Timestamp(0, 0));
+    realm->commit_transaction();
+
+    NotificationToken token;
+    Results results(realm, *table);
+    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
+    CFRunLoopPerformBlock(runLoop, kCFRunLoopDefaultMode, [&]() mutable {
+        token = results.add_notification_callback([&](CollectionChangeSet const&, std::exception_ptr) mutable {
+            if (table->size() > 1) {
+                token = {};
+                CFRunLoopStop(runLoop);
+            }
+        });
+    });
+    CFRunLoopRun();
+#else
+    static_cast<void>(config);
+#endif
+}
+
+static dispatch_queue_t s_async_open_queue = dispatch_queue_create("io.realm.asyncOpenDispatchQueue",
+                                                                   DISPATCH_QUEUE_CONCURRENT);
+void RLMSetAsyncOpenQueue(dispatch_queue_t queue) {
+    s_async_open_queue = queue;
+}
+
++ (RLMAsyncOpenTask *)asyncOpenWithConfiguration:(RLMRealmConfiguration *)configuration
+                                   callbackQueue:(dispatch_queue_t)callbackQueue
+                                        callback:(RLMAsyncOpenRealmCallback)callback {
+    auto openCompletion = [=](ThreadSafeReference<Realm> ref, std::exception_ptr err) {
         @autoreleasepool {
-            if (strongReferenceToSyncedRealm) {
-                // Sync behavior: get the raw session, then wait for it to download.
-                if (auto session = sync_session_for_realm(strongReferenceToSyncedRealm)) {
-                    // Wait for the session to download, then open it.
-                    session->wait_for_download_completion([=](std::error_code error_code) {
-                        dispatch_async(callbackQueue, ^{
-                            (void)strongReferenceToSyncedRealm;
-                            NSError *error = nil;
-                            if (error_code == std::error_code{}) {
-                                // Success
-                                @autoreleasepool {
-                                    // Try opening the Realm on the destination queue.
-                                    RLMRealm *localRealm = [RLMRealm realmWithConfiguration:configuration error:&error];
-                                    callback(localRealm, error);
-                                }
-                            } else {
-                                // Failure
-                                callback(nil, make_sync_error(RLMSyncSystemErrorKindSession,
-                                                              @(error_code.message().c_str()),
-                                                              error_code.value(),
-                                                              nil));
-                            }
-                        });
-                    });
-                } else {
+            if (err) {
+                try {
+                    std::rethrow_exception(err);
+                }
+                catch (...) {
+                    NSError *error;
+                    RLMRealmTranslateException(&error);
                     dispatch_async(callbackQueue, ^{
-                        callback(nil, make_sync_error(RLMSyncSystemErrorKindSession,
-                                                      @"Cannot asynchronously open synced Realm, because the associated session previously experienced a fatal error",
-                                                      NSNotFound,
-                                                      nil));
+                        callback(nil, error);
                     });
-                    return;
                 }
-            } else {
-                // Default behavior: just dispatch onto the destination queue and open the Realm.
+                return;
+            }
+
+            auto complete = ^{
                 dispatch_async(callbackQueue, ^{
                     @autoreleasepool {
-                        NSError *error = nil;
+                        NSError *error;
                         RLMRealm *localRealm = [RLMRealm realmWithConfiguration:configuration error:&error];
                         callback(localRealm, error);
                     }
                 });
-                return;
+            };
+
+            auto realm = Realm::get_shared_realm(std::move(ref));
+            bool needsSubscriptions = realm->is_partial() && ObjectStore::table_for_object_type(realm->read_group(), "__ResultSets")->size() == 0;
+            if (needsSubscriptions) {
+                // We need to dispatch back to the work queue to wait for the
+                // subscriptions as we're currently running on the sync worker
+                // thread and blocking it to wait for subscriptions means no syncing
+                dispatch_async(s_async_open_queue, ^{
+                    @autoreleasepool {
+                        waitForPartialSyncSubscriptions(realm->config());
+                        complete();
+                    }
+                });
+            }
+            else {
+                complete();
+            }
+        }
+    };
+
+    RLMAsyncOpenTask *ret = [RLMAsyncOpenTask new];
+    dispatch_async(s_async_open_queue, ^{
+        @autoreleasepool {
+            Realm::Config& config = configuration.config;
+            if (config.sync_config) {
+#if REALM_ENABLE_SYNC
+                auto task = realm::Realm::get_synchronized_realm(config);
+                ret.task = task;
+                task->start(openCompletion);
+#else
+                @throw RLMException(@"Realm was not built with sync enabled");
+#endif
+            }
+            else {
+                try {
+                    openCompletion(realm::_impl::RealmCoordinator::get_coordinator(config)->get_unbound_realm(), nullptr);
+                }
+                catch (...) {
+                    openCompletion({}, std::current_exception());
+                }
             }
         }
     });
+    return ret;
 }
 
 // ARC tries to eliminate calls to autorelease when the value is then immediately
@@ -712,7 +779,7 @@ REALM_NOINLINE static void translateSharedGroupOpenException(RLMRealmConfigurati
 }
 
 - (void)addObject:(__unsafe_unretained RLMObject *const)object {
-    RLMAddObjectToRealm(object, self, false);
+    RLMAddObjectToRealm(object, self, RLMUpdatePolicyError);
 }
 
 - (void)addObjects:(id<NSFastEnumeration>)objects {
@@ -731,7 +798,7 @@ REALM_NOINLINE static void translateSharedGroupOpenException(RLMRealmConfigurati
         @throw RLMException(@"'%@' does not have a primary key and can not be updated", object.objectSchema.className);
     }
 
-    RLMAddObjectToRealm(object, self, true);
+    RLMAddObjectToRealm(object, self, RLMUpdatePolicyUpdateAll);
 }
 
 - (void)addOrUpdateObjects:(id<NSFastEnumeration>)objects {
@@ -837,7 +904,7 @@ REALM_NOINLINE static void translateSharedGroupOpenException(RLMRealmConfigurati
 }
 
 - (RLMObject *)createObject:(NSString *)className withValue:(id)value {
-    return (RLMObject *)RLMCreateObjectInRealmWithValue(self, className, value, false);
+    return (RLMObject *)RLMCreateObjectInRealmWithValue(self, className, value, RLMUpdatePolicyError);
 }
 
 - (BOOL)writeCopyToURL:(NSURL *)fileURL encryptionKey:(NSData *)key error:(NSError **)error {
@@ -860,6 +927,7 @@ REALM_NOINLINE static void translateSharedGroupOpenException(RLMRealmConfigurati
     return NO;
 }
 
+#if REALM_ENABLE_SYNC
 using Privilege = realm::ComputedPrivileges;
 static bool hasPrivilege(realm::ComputedPrivileges actual, realm::ComputedPrivileges expected) {
     return (static_cast<int>(actual) & static_cast<int>(expected)) == static_cast<int>(expected);
@@ -903,6 +971,7 @@ static bool hasPrivilege(realm::ComputedPrivileges actual, realm::ComputedPrivil
         .create = hasPrivilege(p, Privilege::Create),
     };
 }
+#endif
 
 - (void)registerEnumerator:(RLMFastEnumerator *)enumerator {
     if (!_collectionEnumerators) {

+ 15 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMRealmConfiguration.mm

@@ -25,7 +25,12 @@
 
 #import "schema.hpp"
 #import "shared_realm.hpp"
+
+#if REALM_ENABLE_SYNC
 #import "sync/sync_config.hpp"
+#else
+@class RLMSyncConfiguration;
+#endif
 
 static NSString *const c_RLMRealmConfigurationProperties[] = {
     @"fileURL",
@@ -190,16 +195,20 @@ static void RLMNSStringToStdString(std::string &out, NSString *in) {
     if (NSData *key = RLMRealmValidatedEncryptionKey(encryptionKey)) {
         auto bytes = static_cast<const char *>(key.bytes);
         _config.encryption_key.assign(bytes, bytes + key.length);
+#if REALM_ENABLE_SYNC
         if (_config.sync_config) {
             auto& sync_encryption_key = self.config.sync_config->realm_encryption_key;
             sync_encryption_key = std::array<char, 64>();
             std::copy_n(_config.encryption_key.begin(), 64, sync_encryption_key->begin());
         }
+#endif
     }
     else {
         _config.encryption_key.clear();
+#if REALM_ENABLE_SYNC
         if (_config.sync_config)
             _config.sync_config->realm_encryption_key = realm::util::none;
+#endif
     }
 }
 
@@ -300,4 +309,10 @@ static void RLMNSStringToStdString(std::string &out, NSString *in) {
     _customSchema = schema;
 }
 
+#if !REALM_ENABLE_SYNC
+- (RLMSyncConfiguration *)syncConfiguration {
+    return nil;
+}
+#endif
+
 @end

+ 3 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMRealm_Private.h

@@ -29,6 +29,9 @@ FOUNDATION_EXTERN NSData * _Nullable RLMRealmValidatedEncryptionKey(NSData *key)
 
 FOUNDATION_EXTERN RLMSyncSubscription *RLMCastToSyncSubscription(id obj);
 
+// Set the queue used for async open. For testing purposes only.
+FOUNDATION_EXTERN void RLMSetAsyncOpenQueue(dispatch_queue_t queue);
+
 // Translate an in-flight exception resulting from an operation on a SharedGroup to
 // an NSError or NSException (if error is nil)
 void RLMRealmTranslateException(NSError **error);

+ 3 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMResults.mm

@@ -483,6 +483,9 @@ static inline void RLMResultsValidateInWriteTransaction(__unsafe_unretained RLMR
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wmismatched-parameter-types"
 - (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMResults *, RLMCollectionChange *, NSError *))block {
+    if (!_realm) {
+        @throw RLMException(@"Linking objects notifications are only supported on managed objects.");
+    }
     [_realm verifyNotificationsAreSupported:true];
     return RLMAddNotificationBlock(self, _results, block, true);
 }

+ 42 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.h

@@ -233,4 +233,46 @@ NS_REFINED_FOR_SWIFT;
 
 @end
 
+/**
+ A task object which can be used to observe or cancel an async open.
+
+ When a synchronized Realm is opened asynchronously, the latest state of the
+ Realm is downloaded from the server before the completion callback is invoked.
+ This task object can be used to observe the state of the download or to cancel
+ it. This should be used instead of trying to observe the download via the sync
+ session as the sync session itself is created asynchronously, and may not exist
+ yet when -[RLMRealm asyncOpenWithConfiguration:completion:] returns.
+ */
+@interface RLMAsyncOpenTask : NSObject
+/**
+ Register a progress notification block.
+
+ Each registered progress notification block is called whenever the sync
+ subsystem has new progress data to report until the task is either cancelled
+ or the completion callback is called. Progress notifications are delivered on
+ the main queue.
+ */
+- (void)addProgressNotificationBlock:(RLMProgressNotificationBlock)block;
+
+/**
+ Register a progress notification block which is called on the given queue.
+
+ Each registered progress notification block is called whenever the sync
+ subsystem has new progress data to report until the task is either cancelled
+ or the completion callback is called. Progress notifications are delivered on
+ the supplied queue.
+ */
+- (void)addProgressNotificationOnQueue:(dispatch_queue_t)queue
+                                 block:(RLMProgressNotificationBlock)block;
+
+/**
+ Cancel the asynchronous open.
+
+ Any download in progress will be cancelled, and the completion block for this
+ async open will never be called. If multiple async opens on the same Realm are
+ happening concurrently, all other opens will fail with the error "operation cancelled".
+ */
+- (void)cancel;
+@end
+
 NS_ASSUME_NONNULL_END

+ 59 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.mm

@@ -22,6 +22,8 @@
 #import "RLMSyncConfiguration_Private.hpp"
 #import "RLMSyncUser_Private.hpp"
 #import "RLMSyncUtil_Private.hpp"
+
+#import "sync/async_open_task.hpp"
 #import "sync/sync_session.hpp"
 
 using namespace realm;
@@ -245,3 +247,60 @@ static RLMSyncConnectionState convertConnectionState(SyncSession::ConnectionStat
 }
 
 @end
+
+@implementation RLMAsyncOpenTask {
+    bool _cancel;
+    NSMutableArray<RLMProgressNotificationBlock> *_blocks;
+}
+
+- (void)addProgressNotificationOnQueue:(dispatch_queue_t)queue block:(RLMProgressNotificationBlock)block {
+    auto wrappedBlock = ^(NSUInteger transferred_bytes, NSUInteger transferrable_bytes) {
+        dispatch_async(queue, ^{
+            @autoreleasepool {
+                block(transferred_bytes, transferrable_bytes);
+            }
+        });
+    };
+
+    @synchronized (self) {
+        if (_task) {
+            _task->register_download_progress_notifier(wrappedBlock);
+        }
+        else if (!_cancel) {
+            if (!_blocks) {
+                _blocks = [NSMutableArray new];
+            }
+            [_blocks addObject:wrappedBlock];
+        }
+    }
+}
+
+- (void)addProgressNotificationBlock:(RLMProgressNotificationBlock)block {
+    [self addProgressNotificationOnQueue:dispatch_get_main_queue() block:block];
+}
+
+- (void)cancel {
+    @synchronized (self) {
+        if (_task) {
+            _task->cancel();
+        }
+        else {
+            _cancel = true;
+            _blocks = nil;
+        }
+    }
+}
+
+- (void)setTask:(std::shared_ptr<realm::AsyncOpenTask>)task {
+    @synchronized (self) {
+        _task = task;
+        if (_cancel) {
+            _task->cancel();
+        }
+        for (RLMProgressNotificationBlock block in _blocks) {
+            _task->register_download_progress_notifier(block);
+        }
+        _blocks = nil;
+    }
+}
+@end

+ 5 - 0
Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession_Private.hpp

@@ -22,6 +22,7 @@
 #import <memory>
 
 namespace realm {
+class AsyncOpenTask;
 class SyncSession;
 }
 
@@ -48,4 +49,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @end
 
+@interface RLMAsyncOpenTask ()
+@property (nonatomic) std::shared_ptr<realm::AsyncOpenTask> task;
+@end
+
 NS_ASSUME_NONNULL_END

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist

@@ -17,11 +17,11 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>3.15.0</string>
+	<string>3.17.1</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>3.15.0</string>
+	<string>3.17.1</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>Copyright © 2014 Realm. All rights reserved.</string>
 	<key>NSPrincipalClass</key>

+ 2 - 6
Carthage/Checkouts/realm-cocoa/Realm/Swift/RLMSupport.swift

@@ -26,15 +26,9 @@ extension RLMRealm {
         return version
     }
 
-#if swift(>=3.2)
     @nonobjc public func resolve<Confined>(reference: RLMThreadSafeReference<Confined>) -> Confined? {
         return __resolve(reference as! RLMThreadSafeReference<RLMThreadConfined>) as! Confined?
     }
-#else
-    @nonobjc public func resolve<Confined: RLMThreadConfined>(reference: RLMThreadSafeReference<Confined>) -> Confined? {
-        return __resolve(reference as! RLMThreadSafeReference<RLMThreadConfined>) as! Confined?
-    }
-#endif
 }
 
 extension RLMObject {
@@ -87,6 +81,7 @@ extension RLMCollection {
 
 // MARK: - Sync-related
 
+#if REALM_ENABLE_SYNC
 extension RLMSyncManager {
     public static var shared: RLMSyncManager {
         return __shared()
@@ -141,6 +136,7 @@ extension RLMSyncSession {
                                          block: block)
     }
 }
+#endif
 
 extension RLMNotificationToken {
     @available(*, unavailable, renamed: "invalidate()")

+ 16 - 12
Carthage/Checkouts/realm-cocoa/Realm/Tests/DynamicTests.m

@@ -35,8 +35,8 @@
         // open realm in autoreleasepool to create tables and then dispose
         RLMRealm *realm = [RLMRealm realmWithURL:RLMTestRealmURL()];
         [realm beginWriteTransaction];
-        [DynamicObject createInRealm:realm withValue:@[@"column1", @1]];
-        [DynamicObject createInRealm:realm withValue:@[@"column2", @2]];
+        [DynamicTestObject createInRealm:realm withValue:@[@"column1", @1]];
+        [DynamicTestObject createInRealm:realm withValue:@[@"column2", @2]];
         [realm commitWriteTransaction];
     }
 
@@ -44,16 +44,16 @@
     XCTAssertNotNil(dyrealm, @"realm should not be nil");
 
     // verify schema
-    RLMObjectSchema *dynSchema = dyrealm.schema[@"DynamicObject"];
+    RLMObjectSchema *dynSchema = dyrealm.schema[@"DynamicTestObject"];
     XCTAssertNotNil(dynSchema, @"Should be able to get object schema dynamically");
-    XCTAssertEqual(dynSchema.properties.count, (NSUInteger)2, @"DynamicObject should have 2 properties");
+    XCTAssertEqual(dynSchema.properties.count, (NSUInteger)2, @"DynamicTestObject should have 2 properties");
     XCTAssertEqualObjects([dynSchema.properties[0] name], @"stringCol", @"Invalid property name");
     XCTAssertEqual([(RLMProperty *)dynSchema.properties[1] type], RLMPropertyTypeInt, @"Invalid type");
 
     // verify object type
-    RLMResults *results = [dyrealm allObjects:@"DynamicObject"];
+    RLMResults *results = [dyrealm allObjects:@"DynamicTestObject"];
     XCTAssertEqual(results.count, (NSUInteger)2, @"Array should have 2 elements");
-    XCTAssertNotEqual(results.objectClassName, DynamicObject.className,
+    XCTAssertNotEqual(results.objectClassName, DynamicTestObject.className,
                       @"Array class should by a dynamic object class");
 }
 
@@ -78,10 +78,8 @@
 
 - (void)testDynamicSchemaMatchesRegularSchema {
     RLMSchema *expectedSchema = nil;
-    // Force create and close realm
     @autoreleasepool {
-        RLMRealm *realm = self.realmWithTestPath;
-        expectedSchema = realm.schema;
+        expectedSchema = self.realmWithTestPath.schema;
     }
     XCTAssertNotNil(expectedSchema);
 
@@ -98,6 +96,12 @@
             // Class overrides names, so the dynamic schema for it shoudn't match
             continue;
         }
+        if (expectedObjectSchema.primaryKeyProperty.index != 0) {
+            // The dynamic schema will always put the primary key first, so it
+            // won't match if the static schema doesn't have it there
+            continue;
+        }
+
         RLMObjectSchema *dynamicObjectSchema = dynamicSchema[expectedObjectSchema.className];
         XCTAssertEqual(dynamicObjectSchema.properties.count, expectedObjectSchema.properties.count);
         for (NSUInteger propertyIndex = 0; propertyIndex < expectedObjectSchema.properties.count; propertyIndex++) {
@@ -129,14 +133,14 @@
         // open realm in autoreleasepool to create tables and then dispose
         RLMRealm *realm = [RLMRealm realmWithURL:RLMTestRealmURL()];
         [realm beginWriteTransaction];
-        [DynamicObject createInRealm:realm withValue:@[@"column1", @1]];
-        [DynamicObject createInRealm:realm withValue:@[@"column2", @2]];
+        [DynamicTestObject createInRealm:realm withValue:@[@"column1", @1]];
+        [DynamicTestObject createInRealm:realm withValue:@[@"column2", @2]];
         [realm commitWriteTransaction];
     }
 
     // verify properties
     RLMRealm *dyrealm = [self realmWithTestPathAndSchema:nil];
-    RLMResults *results = [dyrealm allObjects:@"DynamicObject"];
+    RLMResults *results = [dyrealm allObjects:@"DynamicTestObject"];
 
     RLMObject *o1 = results[0], *o2 = results[1];
     XCTAssertEqualObjects(o1[@"intCol"], @1);

+ 1 - 1
Carthage/Checkouts/realm-cocoa/Realm/Tests/InterprocessTests.m

@@ -65,7 +65,7 @@
         @autoreleasepool {
             RLMRealm *realm = RLMRealm.defaultRealm;
             [realm transactionWithBlock:^{
-                for (int i = 0; i < 100; ++i) {
+                for (int i = 0; i < 1000; ++i) {
                     [IntObject createInRealm:realm withValue:@[@(i)]];
                 }
             }];

+ 1 - 1
Carthage/Checkouts/realm-cocoa/Realm/Tests/KVOTests.mm

@@ -296,7 +296,7 @@ public:
 // remove it, and verify that there are no more notifications
 #define AssertIndexChange(kind, indexes) do { \
     if (NSDictionary *note = AssertNotification(r)) { \
-        XCTAssertEqual([note[NSKeyValueChangeKindKey] intValue], kind); \
+        XCTAssertEqual([note[NSKeyValueChangeKindKey] intValue], static_cast<int>(kind)); \
         XCTAssertEqualObjects(note[NSKeyValueChangeIndexesKey], indexes); \
     } \
     XCTAssertTrue(r.empty()); \

+ 3 - 0
Carthage/Checkouts/realm-cocoa/Realm/Tests/LinkingObjectsTests.mm

@@ -82,6 +82,9 @@
     PersonObject *mark = [[PersonObject alloc] initWithValue:@[ @"Mark", @30, @[] ]];
     XCTAssertEqual(NSNotFound, [don.parents indexOfObject:mark]);
     XCTAssertEqual(NSNotFound, [don.parents indexOfObjectWhere:@"TRUEPREDICATE"]);
+
+    RLMAssertThrowsWithReason(([don.parents addNotificationBlock:^(RLMResults *, RLMCollectionChange *, NSError *) { }]),
+                              @"Linking objects notifications are only supported on managed objects.");
 }
 
 - (void)testFilteredLinkingObjects {

+ 55 - 50
Carthage/Checkouts/realm-cocoa/Realm/Tests/MigrationTests.mm

@@ -51,13 +51,13 @@ static void RLMAssertRealmSchemaMatchesTable(id self, RLMRealm *realm) {
     }
 }
 
-@interface MigrationObject : RLMObject
+@interface MigrationTestObject : RLMObject
 @property int intCol;
 @property NSString *stringCol;
 @end
-RLM_ARRAY_TYPE(MigrationObject);
+RLM_ARRAY_TYPE(MigrationTestObject);
 
-@implementation MigrationObject
+@implementation MigrationTestObject
 @end
 
 @interface MigrationPrimaryKeyObject : RLMObject
@@ -80,13 +80,13 @@ RLM_ARRAY_TYPE(MigrationObject);
 }
 @end
 
-@interface ThreeFieldMigrationObject : RLMObject
+@interface ThreeFieldMigrationTestObject : RLMObject
 @property int col1;
 @property int col2;
 @property int col3;
 @end
 
-@implementation ThreeFieldMigrationObject
+@implementation ThreeFieldMigrationTestObject
 @end
 
 @interface MigrationTwoStringObject : RLMObject
@@ -98,8 +98,8 @@ RLM_ARRAY_TYPE(MigrationObject);
 @end
 
 @interface MigrationLinkObject : RLMObject
-@property MigrationObject *object;
-@property RLMArray<MigrationObject> *array;
+@property MigrationTestObject *object;
+@property RLMArray<MigrationTestObject> *array;
 @end
 
 @implementation MigrationLinkObject
@@ -345,19 +345,19 @@ RLM_ARRAY_TYPE(MigrationObject);
 
 - (void)testAddingClassDoesNotRequireMigration {
     RLMRealmConfiguration *config = [RLMRealmConfiguration new];
-    config.objectClasses = @[MigrationObject.class];
+    config.objectClasses = @[MigrationTestObject.class];
     @autoreleasepool { [RLMRealm realmWithConfiguration:config error:nil]; }
 
-    config.objectClasses = @[MigrationObject.class, ThreeFieldMigrationObject.class];
+    config.objectClasses = @[MigrationTestObject.class, ThreeFieldMigrationTestObject.class];
     XCTAssertNoThrow([RLMRealm realmWithConfiguration:config error:nil]);
 }
 
 - (void)testRemovingClassDoesNotRequireMigration {
     RLMRealmConfiguration *config = [RLMRealmConfiguration new];
-    config.objectClasses = @[MigrationObject.class, ThreeFieldMigrationObject.class];
+    config.objectClasses = @[MigrationTestObject.class, ThreeFieldMigrationTestObject.class];
     @autoreleasepool { [RLMRealm realmWithConfiguration:config error:nil]; }
 
-    config.objectClasses = @[MigrationObject.class];
+    config.objectClasses = @[MigrationTestObject.class];
     XCTAssertNoThrow([RLMRealm realmWithConfiguration:config error:nil]);
 }
 
@@ -453,7 +453,7 @@ RLM_ARRAY_TYPE(MigrationObject);
 }
 
 - (void)testChangingLinkTargetRequiresMigration {
-    NSArray *linkTargets = @[[RLMObjectSchema schemaForObjectClass:MigrationObject.class],
+    NSArray *linkTargets = @[[RLMObjectSchema schemaForObjectClass:MigrationTestObject.class],
                              [RLMObjectSchema schemaForObjectClass:MigrationTwoStringObject.class]];
     RLMObjectSchema *from = [RLMObjectSchema schemaForObjectClass:MigrationLinkObject.class];
 
@@ -465,7 +465,7 @@ RLM_ARRAY_TYPE(MigrationObject);
 }
 
 - (void)testChangingLinkListTargetRequiresMigration {
-    NSArray *linkTargets = @[[RLMObjectSchema schemaForObjectClass:MigrationObject.class],
+    NSArray *linkTargets = @[[RLMObjectSchema schemaForObjectClass:MigrationTestObject.class],
                              [RLMObjectSchema schemaForObjectClass:MigrationTwoStringObject.class]];
     RLMObjectSchema *from = [RLMObjectSchema schemaForObjectClass:MigrationLinkObject.class];
 
@@ -477,9 +477,9 @@ RLM_ARRAY_TYPE(MigrationObject);
 }
 
 - (void)testChangingPropertyTypesRequiresMigration {
-    RLMObjectSchema *from = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *from = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
 
-    RLMObjectSchema *to = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *to = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     to.objectClass = RLMObject.class;
     RLMProperty *prop = to.properties[0];
     RLMProperty *strProp = to.properties[1];
@@ -512,14 +512,14 @@ RLM_ARRAY_TYPE(MigrationObject);
 - (void)testDeleteRealmIfMigrationNeeded {
     for (uint64_t targetSchemaVersion = 1; targetSchemaVersion < 2; targetSchemaVersion++) {
         RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-        RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+        RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
         configuration.customSchema = [self schemaWithObjects:@[objectSchema]];
 
         @autoreleasepool {
             [[NSFileManager defaultManager] removeItemAtURL:configuration.fileURL error:nil];
             RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];
             [realm transactionWithBlock:^{
-                [realm addObject:[MigrationObject new]];
+                [realm addObject:[MigrationTestObject new]];
             }];
         }
 
@@ -713,17 +713,17 @@ RLM_ARRAY_TYPE(MigrationObject);
 
 - (void)testAddingPropertyAtEnd {
     // create schema to migrate from with single string column
-    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     objectSchema.properties = @[objectSchema.properties[0]];
     [self createTestRealmWithSchema:@[objectSchema] block:^(RLMRealm *realm) {
-        [realm createObject:MigrationObject.className withValue:@[@1]];
-        [realm createObject:MigrationObject.className withValue:@[@2]];
+        [realm createObject:MigrationTestObject.className withValue:@[@1]];
+        [realm createObject:MigrationTestObject.className withValue:@[@2]];
     }];
 
     // apply migration
     RLMRealm *realm = [self migrateTestRealmWithBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) {
         XCTAssertEqual(oldSchemaVersion, 0U, @"Initial schema version should be 0");
-        [migration enumerateObjects:MigrationObject.className
+        [migration enumerateObjects:MigrationTestObject.className
                               block:^(RLMObject *oldObject, RLMObject *newObject) {
             XCTAssertThrows(oldObject[@"stringCol"], @"stringCol should not exist on old object");
             NSNumber *intObj;
@@ -735,22 +735,22 @@ RLM_ARRAY_TYPE(MigrationObject);
     }];
 
     // verify migration
-    MigrationObject *mig1 = [MigrationObject allObjectsInRealm:realm][1];
+    MigrationTestObject *mig1 = [MigrationTestObject allObjectsInRealm:realm][1];
     XCTAssertEqual(mig1.intCol, 2, @"Int column should have value 2");
     XCTAssertEqualObjects(mig1.stringCol, @"2", @"String column should be populated");
 }
 
 - (void)testAddingPropertyAtBeginningPreservesData {
     // create schema to migrate from with the second and third columns from the final data
-    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:ThreeFieldMigrationObject.class];
+    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:ThreeFieldMigrationTestObject.class];
     objectSchema.properties = @[objectSchema.properties[1], objectSchema.properties[2]];
 
     [self createTestRealmWithSchema:@[objectSchema] block:^(RLMRealm *realm) {
-        [realm createObject:ThreeFieldMigrationObject.className withValue:@[@1, @2]];
+        [realm createObject:ThreeFieldMigrationTestObject.className withValue:@[@1, @2]];
     }];
 
     RLMRealm *realm = [self migrateTestRealmWithBlock:^(RLMMigration *migration, uint64_t) {
-        [migration enumerateObjects:ThreeFieldMigrationObject.className
+        [migration enumerateObjects:ThreeFieldMigrationTestObject.className
                               block:^(RLMObject *oldObject, RLMObject *newObject) {
             XCTAssertThrows(oldObject[@"col1"]);
             XCTAssertEqualObjects(oldObject[@"col2"], newObject[@"col2"]);
@@ -759,7 +759,7 @@ RLM_ARRAY_TYPE(MigrationObject);
     }];
 
     // verify migration
-    ThreeFieldMigrationObject *mig = [ThreeFieldMigrationObject allObjectsInRealm:realm][0];
+    ThreeFieldMigrationTestObject *mig = [ThreeFieldMigrationTestObject allObjectsInRealm:realm][0];
     XCTAssertEqual(0, mig.col1);
     XCTAssertEqual(1, mig.col2);
     XCTAssertEqual(2, mig.col3);
@@ -767,20 +767,20 @@ RLM_ARRAY_TYPE(MigrationObject);
 
 - (void)testRemoveProperty {
     // create schema with an extra column
-    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     RLMProperty *thirdProperty = [[RLMProperty alloc] initWithName:@"deletedCol" type:RLMPropertyTypeBool objectClassName:nil linkOriginPropertyName:nil indexed:NO optional:NO];
     objectSchema.properties = [objectSchema.properties arrayByAddingObject:thirdProperty];
 
     // create realm with old schema and populate
     [self createTestRealmWithSchema:@[objectSchema] block:^(RLMRealm *realm) {
-        [realm createObject:MigrationObject.className withValue:@[@1, @"1", @YES]];
-        [realm createObject:MigrationObject.className withValue:@[@2, @"2", @NO]];
+        [realm createObject:MigrationTestObject.className withValue:@[@1, @"1", @YES]];
+        [realm createObject:MigrationTestObject.className withValue:@[@2, @"2", @NO]];
     }];
 
     // apply migration
     RLMRealm *realm = [self migrateTestRealmWithBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) {
         XCTAssertEqual(oldSchemaVersion, 0U, @"Initial schema version should be 0");
-        [migration enumerateObjects:MigrationObject.className
+        [migration enumerateObjects:MigrationTestObject.className
                                        block:^(RLMObject *oldObject, RLMObject *newObject) {
             XCTAssertNoThrow(oldObject[@"deletedCol"], @"Deleted column should be accessible on old object.");
             XCTAssertThrows(newObject[@"deletedCol"], @"Deleted column should not be accessible on new object.");
@@ -791,20 +791,20 @@ RLM_ARRAY_TYPE(MigrationObject);
     }];
 
     // verify migration
-    MigrationObject *mig1 = [MigrationObject allObjectsInRealm:realm][1];
+    MigrationTestObject *mig1 = [MigrationTestObject allObjectsInRealm:realm][1];
     XCTAssertThrows(mig1[@"deletedCol"], @"Deleted column should no longer be accessible.");
 }
 
 - (void)testRemoveAndAddProperty {
     // create schema to migrate from with single string column
-    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     RLMProperty *oldInt = [[RLMProperty alloc] initWithName:@"oldIntCol" type:RLMPropertyTypeInt objectClassName:nil linkOriginPropertyName:nil indexed:NO optional:NO];
     objectSchema.properties = @[oldInt, objectSchema.properties[1]];
 
     // create realm with old schema and populate
     [self createTestRealmWithSchema:@[objectSchema] block:^(RLMRealm *realm) {
-        [realm createObject:MigrationObject.className withValue:@[@1, @"1"]];
-        [realm createObject:MigrationObject.className withValue:@[@1, @"2"]];
+        [realm createObject:MigrationTestObject.className withValue:@[@1, @"1"]];
+        [realm createObject:MigrationTestObject.className withValue:@[@1, @"2"]];
     }];
 
     // object migration object
@@ -820,17 +820,17 @@ RLM_ARRAY_TYPE(MigrationObject);
     // apply migration
     RLMRealm *realm = [self migrateTestRealmWithBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) {
         XCTAssertEqual(oldSchemaVersion, 0U, @"Initial schema version should be 0");
-        [migration enumerateObjects:MigrationObject.className block:migrateObjectBlock];
+        [migration enumerateObjects:MigrationTestObject.className block:migrateObjectBlock];
     }];
 
     // verify migration
-    MigrationObject *mig1 = [MigrationObject allObjectsInRealm:realm][1];
+    MigrationTestObject *mig1 = [MigrationTestObject allObjectsInRealm:realm][1];
     XCTAssertThrows(mig1[@"oldIntCol"], @"Deleted column should no longer be accessible.");
 }
 
 - (void)testChangePropertyType {
     // make string an int
-    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     objectSchema.objectClass = RLMObject.class;
     RLMProperty *stringCol = objectSchema.properties[1];
     stringCol.type = RLMPropertyTypeInt;
@@ -838,14 +838,14 @@ RLM_ARRAY_TYPE(MigrationObject);
 
     // create realm with old schema and populate
     [self createTestRealmWithSchema:@[objectSchema] block:^(RLMRealm *realm) {
-        [realm createObject:MigrationObject.className withValue:@[@1, @1]];
-        [realm createObject:MigrationObject.className withValue:@[@2, @2]];
+        [realm createObject:MigrationTestObject.className withValue:@[@1, @1]];
+        [realm createObject:MigrationTestObject.className withValue:@[@2, @2]];
     }];
 
     // apply migration
     RLMRealm *realm = [self migrateTestRealmWithBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) {
         XCTAssertEqual(oldSchemaVersion, 0U, @"Initial schema version should be 0");
-        [migration enumerateObjects:MigrationObject.className
+        [migration enumerateObjects:MigrationTestObject.className
                               block:^(RLMObject *oldObject, RLMObject *newObject) {
             XCTAssertEqualObjects(newObject[@"intCol"], oldObject[@"intCol"]);
             NSNumber *intObj = oldObject[@"stringCol"];
@@ -855,14 +855,14 @@ RLM_ARRAY_TYPE(MigrationObject);
     }];
 
     // verify migration
-    MigrationObject *mig1 = [MigrationObject allObjectsInRealm:realm][1];
+    MigrationTestObject *mig1 = [MigrationTestObject allObjectsInRealm:realm][1];
     XCTAssertEqualObjects(mig1[@"stringCol"], @"2", @"stringCol should be string after migration.");
 }
 
 - (void)testChangeObjectLinkType {
     // create realm with old schema and populate
     [self createTestRealmWithSchema:RLMSchema.sharedSchema.objectSchema block:^(RLMRealm *realm) {
-        id obj = [realm createObject:MigrationObject.className withValue:@[@1, @"1"]];
+        id obj = [realm createObject:MigrationTestObject.className withValue:@[@1, @"1"]];
         [realm createObject:MigrationLinkObject.className withValue:@[obj, @[obj]]];
     }];
 
@@ -870,7 +870,7 @@ RLM_ARRAY_TYPE(MigrationObject);
     RLMRealmConfiguration *config = self.config;
     RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationLinkObject.class];
     [objectSchema.properties[0] setObjectClassName:MigrationLinkObject.className];
-    config.customSchema = [self schemaWithObjects:@[objectSchema, [RLMObjectSchema schemaForObjectClass:MigrationObject.class]]];
+    config.customSchema = [self schemaWithObjects:@[objectSchema, [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class]]];
 
     // Apply migration
     config.schemaVersion = 1;
@@ -893,14 +893,14 @@ RLM_ARRAY_TYPE(MigrationObject);
     // create realm with old schema and populate
     RLMRealmConfiguration *config = [self config];
     [self createTestRealmWithSchema:RLMSchema.sharedSchema.objectSchema block:^(RLMRealm *realm) {
-        id obj = [realm createObject:MigrationObject.className withValue:@[@1, @"1"]];
+        id obj = [realm createObject:MigrationTestObject.className withValue:@[@1, @"1"]];
         [realm createObject:MigrationLinkObject.className withValue:@[obj, @[obj]]];
     }];
 
     // Make the array linklist property link to a different class
     RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationLinkObject.class];
     [objectSchema.properties[1] setObjectClassName:MigrationLinkObject.className];
-    config.customSchema = [self schemaWithObjects:@[objectSchema, [RLMObjectSchema schemaForObjectClass:MigrationObject.class]]];
+    config.customSchema = [self schemaWithObjects:@[objectSchema, [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class]]];
 
     // Apply migration
     config.schemaVersion = 1;
@@ -1373,6 +1373,7 @@ RLM_ARRAY_TYPE(MigrationObject);
     XCTAssertEqualObjects(@"World", [allObjects[1] stringCol]);
 }
 
+#ifndef REALM_SPM
 - (void)testDateTimeFormatAutoMigration {
     static const int cookieValue = 0xDEADBEEF;
 
@@ -1448,8 +1449,11 @@ RLM_ARRAY_TYPE(MigrationObject);
     @autoreleasepool {
         NSURL *bundledRealmURL = [[NSBundle bundleForClass:[DateMigrationObject class]]
                                   URLForResource:@"fileformat-pre-null" withExtension:@"realm"];
-        [NSFileManager.defaultManager removeItemAtURL:config.fileURL error:nil];
-        [NSFileManager.defaultManager copyItemAtURL:bundledRealmURL toURL:config.fileURL error:nil];
+        NSError *error;
+        [NSFileManager.defaultManager removeItemAtURL:config.fileURL error:&error];
+        XCTAssertNil(error);
+        [NSFileManager.defaultManager copyItemAtURL:bundledRealmURL toURL:config.fileURL error:&error];
+        XCTAssertNil(error);
 
         config.schemaVersion = 1; // Nullability of some properties changed
         RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
@@ -1508,6 +1512,7 @@ RLM_ARRAY_TYPE(MigrationObject);
     XCTAssertTrue(migrationCalled);
 #endif
 }
+#endif // REALM_SPM
 
 - (void)testModifyPrimaryKeyInMigration {
     RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:PrimaryStringObject.class];
@@ -1704,7 +1709,7 @@ RLM_ARRAY_TYPE(MigrationObject);
 
 - (void)testMigrationRenamePropertyObjectTypeMismatch {
     RLMObjectSchema *objectSchema = [RLMObjectSchema schemaForObjectClass:MigrationLinkObject.class];
-    RLMObjectSchema *migrationObjectSchema = [RLMObjectSchema schemaForObjectClass:MigrationObject.class];
+    RLMObjectSchema *migrationObjectSchema = [RLMObjectSchema schemaForObjectClass:MigrationTestObject.class];
     NSArray *afterProperties = objectSchema.properties;
     NSMutableArray *beforeProperties = [NSMutableArray arrayWithCapacity:2];
     for (RLMProperty *property in afterProperties) {
@@ -1720,13 +1725,13 @@ RLM_ARRAY_TYPE(MigrationObject);
 
     objectSchema.properties = afterProperties;
 
-    [self assertPropertyRenameError:@"Cannot rename property 'MigrationLinkObject.before_object' to 'object' because it would change from type '<MigrationLinkObject>' to '<MigrationObject>'."
+    [self assertPropertyRenameError:@"Cannot rename property 'MigrationLinkObject.before_object' to 'object' because it would change from type '<MigrationLinkObject>' to '<MigrationTestObject>'."
                       objectSchemas:@[objectSchema, migrationObjectSchema]
                           className:MigrationLinkObject.className
                             oldName:[beforeProperties[0] name]
                             newName:[afterProperties[0] name]];
 
-    [self assertPropertyRenameError:@"Cannot rename property 'MigrationLinkObject.before_array' to 'array' because it would change from type 'array<MigrationLinkObject>' to 'array<MigrationObject>'."
+    [self assertPropertyRenameError:@"Cannot rename property 'MigrationLinkObject.before_array' to 'array' because it would change from type 'array<MigrationLinkObject>' to 'array<MigrationTestObject>'."
                       objectSchemas:@[objectSchema, migrationObjectSchema]
                           className:MigrationLinkObject.className
                             oldName:[beforeProperties[1] name]

+ 64 - 1
Carthage/Checkouts/realm-cocoa/Realm/Tests/NotificationTests.m

@@ -867,7 +867,25 @@ static void ExpectChange(id self, NSArray *deletions, NSArray *insertions, NSArr
 
 @end
 
-// clang things the tests below have retain cycles because `_obj` could retain
+@interface AllTypesWithPrimaryKey : RLMObject
+@property BOOL          boolCol;
+@property int           intCol;
+@property float         floatCol;
+@property double        doubleCol;
+@property NSString     *stringCol;
+@property NSData       *binaryCol;
+@property NSDate       *dateCol;
+@property bool          cBoolCol;
+@property int64_t       longCol;
+@property StringObject *objectCol;
+
+@property (nonatomic) int pk;
+@end
+@implementation AllTypesWithPrimaryKey
++ (NSString *)primaryKey { return @"pk"; }
+@end
+
+// clang thinks the tests below have retain cycles because `_obj` could retain
 // the block passed to addNotificationBlock (but it doesn't)
 #pragma clang diagnostic ignored "-Warc-retain-cycles"
 
@@ -1087,4 +1105,49 @@ static void ExpectChange(id self, NSArray *deletions, NSArray *insertions, NSArr
     [token invalidate];
 }
 
+- (void)testDiffedUpdatesOnlyNotifyForPropertiesWhichActuallyChanged {
+    NSMutableArray *values = [_initialValues mutableCopy];
+    [values addObject:@1];
+
+    RLMRealm *realm = [RLMRealm defaultRealm];
+    [realm beginWriteTransaction];
+    [realm addObject:_values.lastObject];
+    AllTypesWithPrimaryKey *obj = [AllTypesWithPrimaryKey createInRealm:realm withValue:values];
+    [realm commitWriteTransaction];
+
+    __block NSUInteger i = 0;
+    __block XCTestExpectation *expectation = nil;
+    RLMNotificationToken *token = [obj addNotificationBlock:^(BOOL deleted, NSArray *changes, NSError *error) {
+        XCTAssertFalse(deleted);
+        XCTAssertNil(error);
+        XCTAssertEqual(changes.count, 1U);
+        RLMPropertyChange *prop = changes[0];
+        XCTAssertEqualObjects(prop.name, _propertyNames[i]);
+        XCTAssertNil(prop.previousValue);
+        if ([prop.name isEqualToString:@"objectCol"]) {
+            XCTAssertTrue([prop.value isEqualToObject:_values[i]],
+                          @"%d: %@ %@", (int)i, prop.value, _values[i]);
+        }
+        else {
+            XCTAssertEqualObjects(prop.value, _values[i]);
+        }
+
+        [expectation fulfill];
+    }];
+
+
+    for (i = 0; i < _values.count; ++i) {
+        expectation = [self expectationWithDescription:@""];
+
+        [realm beginWriteTransaction];
+        values[i] = _values[i];
+        [AllTypesWithPrimaryKey createOrUpdateModifiedInRealm:realm withValue:values];
+        [realm commitWriteTransaction];
+
+        [self waitForExpectationsWithTimeout:2.0 handler:nil];
+    }
+    [token invalidate];
+
+}
+
 @end

+ 1 - 1
Carthage/Checkouts/realm-cocoa/Realm/Tests/QueryTests.m

@@ -1081,7 +1081,7 @@
     RLMAssertCount(StringObject, 0U, @"stringCol LIKE 'aabc'");
     RLMAssertCount(StringObject, 0U, @"stringCol LIKE 'b*bc'");
 
-    RLMAssertCount(StringObject, 1U, @"stringCol LIKE 'a??'");
+    RLMAssertCount(StringObject, 1U, @"stringCol LIKE 'a?" "?'");
     RLMAssertCount(StringObject, 1U, @"stringCol LIKE '?b?'");
     RLMAssertCount(StringObject, 1U, @"stringCol LIKE '*?c'");
     RLMAssertCount(StringObject, 1U, @"stringCol LIKE 'ab?'");

+ 0 - 108
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMAssertions.h

@@ -1,108 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2015 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 <XCTest/XCTest.h>
-
-#define RLMAssertThrows(expression, ...) \
-    RLMPrimitiveAssertThrows(self, expression,  __VA_ARGS__)
-
-#define RLMPrimitiveAssertThrows(self, expression, format...) \
-({ \
-    NSException *caughtException = nil; \
-    @try { \
-        (expression); \
-    } \
-    @catch (id exception) { \
-        caughtException = exception; \
-    } \
-    if (!caughtException) { \
-        _XCTRegisterFailure(self, _XCTFailureDescription(_XCTAssertion_Throws, 0, @#expression), format); \
-    } \
-    caughtException; \
-})
-
-#define RLMAssertMatches(expression, regex, ...) \
-    RLMPrimitiveAssertMatches(self, expression, regex,  __VA_ARGS__)
-
-#define RLMPrimitiveAssertMatches(self, expression, regexString, format...) \
-({ \
-    NSString *string = (expression); \
-    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:(NSRegularExpressionOptions)0 error:nil]; \
-    if ([regex numberOfMatchesInString:string options:(NSMatchingOptions)0 range:NSMakeRange(0, string.length)] == 0) { \
-        _XCTRegisterFailure(self, [_XCTFailureDescription(_XCTAssertion_True, 0, @#expression @" (EXPR_STRING) matches " @#regexString) stringByReplacingOccurrencesOfString:@"EXPR_STRING" withString:string ?: @"<nil>"], format); \
-    } \
-})
-
-#define RLMAssertThrowsWithReasonMatching(expression, regex, ...) \
-({ \
-    NSException *exception = RLMAssertThrows(expression, __VA_ARGS__); \
-    if (exception) { \
-        RLMAssertMatches(exception.reason, regex, __VA_ARGS__); \
-    } \
-    exception; \
-})
-
-#define RLMAssertThrowsWithReason(expression, expected, ...) \
-({ \
-    NSException *exception = RLMAssertThrows(expression); \
-    if (exception) { \
-        if ([exception.reason rangeOfString:(expected)].location == NSNotFound) { \
-            _XCTRegisterFailure(self, \
-                                [_XCTFailureDescription(_XCTAssertion_True, 0, @#expression " (EXPR_STRING) contains " #expected) \
-                                 stringByReplacingOccurrencesOfString:@"EXPR_STRING" \
-                                                           withString:exception.reason ?: @"<nil>"]); \
-        } \
-    } \
-    exception; \
-})
-
-#define RLMAssertThrowsWithCodeMatching(expression, expectedCode, ...) \
-({ \
-    NSException *exception = RLMAssertThrows(expression, __VA_ARGS__); \
-    XCTAssertEqual([exception.userInfo[NSUnderlyingErrorKey] code], expectedCode, __VA_ARGS__); \
-})
-
-#define RLMValidateRealmError(macro_error, macro_errnum, macro_description, macro_underlying)            \
-({                                                                                                       \
-    NSString *macro_dsc = macro_description;                                                             \
-    NSString *macro_usl = macro_underlying;                                                              \
-    macro_dsc = [macro_dsc lowercaseString];                                                             \
-    macro_usl = [macro_usl lowercaseString];                                                             \
-    NSError *macro_castErr = (NSError *)macro_error;                                                     \
-    XCTAssertNotNil(macro_castErr);                                                                      \
-    XCTAssertEqual(macro_castErr.domain, RLMErrorDomain, @"Was expecting the error domain '%@', but got non-interned '%@' instead", RLMErrorDomain, macro_castErr.domain); \
-    XCTAssertEqual(macro_castErr.code, macro_errnum);                                                    \
-    if (macro_dsc.length) {                                                                              \
-        NSString *macro_dscActual = [macro_castErr.userInfo[NSLocalizedDescriptionKey] lowercaseString]; \
-        XCTAssertNotNil(macro_dscActual);                                                                \
-        XCTAssert([macro_dscActual rangeOfString:macro_dsc].location != NSNotFound, @"Did not find the expected string '%@' in the description string '%@'", macro_dsc, macro_dscActual); \
-    }                                                                                                    \
-    if (macro_usl.length) {                                                                              \
-        NSString *macro_uslActual = [macro_castErr.userInfo[@"Underlying"] lowercaseString];             \
-        XCTAssertNotNil(macro_uslActual);                                                                \
-        XCTAssert([macro_uslActual rangeOfString:macro_usl].location != NSNotFound, @"Did not find the expected string '%@' in the underlying info string '%@'", macro_usl, macro_uslActual); \
-    }                                                                                                    \
-})
-
-/// Check that an exception is thrown, and validate additional details about its underlying error.
-#define RLMAssertThrowsWithError(macro_expr, macro_except_string, macro_errnum, macro_underlying_string) \
-({                                                                                                       \
-    NSException *macro_exception = RLMAssertThrowsWithReasonMatching(macro_expr, macro_except_string);   \
-    NSError *macro_excErr = (NSError *)(macro_exception.userInfo[NSUnderlyingErrorKey]);                 \
-    RLMValidateRealmError(macro_excErr, macro_errnum, nil, macro_underlying_string);                     \
-})

+ 0 - 35
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.h

@@ -1,35 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2015 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 "RLMTestCase.h"
-
-@class NSTask;
-
-@interface RLMMultiProcessTestCase : RLMTestCase
-// if true, this is running the main test process
-@property (nonatomic, readonly) bool isParent;
-
-// spawn a child process running the current test and wait for it complete
-// returns the return code of the process
-- (int)runChildAndWait;
-
-- (NSTask *)childTask;
-@end
-
-#define RLMRunChildAndWait() \
-    XCTAssertEqual(0, [self runChildAndWait], @"Tests in child process failed")

+ 0 - 163
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.m

@@ -1,163 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2015 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 "RLMMultiProcessTestCase.h"
-
-@interface RLMMultiProcessTestCase ()
-@property (nonatomic) bool isParent;
-@property (nonatomic, strong) NSString *testName;
-
-@property (nonatomic, strong) NSString *xctestPath;
-@property (nonatomic, strong) NSString *testsPath;
-@end
-
-@implementation RLMMultiProcessTestCase
-// Override all of the methods for creating a XCTestCase object to capture the current test name
-+ (id)testCaseWithInvocation:(NSInvocation *)invocation {
-    RLMMultiProcessTestCase *testCase = [super testCaseWithInvocation:invocation];
-    testCase.testName = NSStringFromSelector(invocation.selector);
-    return testCase;
-}
-
-- (id)initWithInvocation:(NSInvocation *)invocation {
-    self = [super initWithInvocation:invocation];
-    if (self) {
-        self.testName = NSStringFromSelector(invocation.selector);
-    }
-    return self;
-}
-
-+ (id)testCaseWithSelector:(SEL)selector {
-    RLMMultiProcessTestCase *testCase = [super testCaseWithSelector:selector];
-    testCase.testName = NSStringFromSelector(selector);
-    return testCase;
-}
-
-- (id)initWithSelector:(SEL)selector {
-    self = [super initWithSelector:selector];
-    if (self) {
-        self.testName = NSStringFromSelector(selector);
-    }
-    return self;
-}
-
-- (void)setUp {
-    self.isParent = !getenv("RLMProcessIsChild");
-    self.xctestPath = [self locateXCTest];
-    self.testsPath = [NSBundle bundleForClass:[self class]].bundlePath;
-
-    if (!self.isParent) {
-        // For multi-process tests, the child's concept of a default path needs to match the parent.
-        // RLMRealmConfiguration isn't aware of this, but our test's RLMDefaultRealmURL helper does.
-        // Use it to reset the default configuration's path so it matches the parent.
-        RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-        configuration.fileURL = RLMDefaultRealmURL();
-        [RLMRealmConfiguration setDefaultConfiguration:configuration];
-    }
-
-    [super setUp];
-}
-
-- (void)invokeTest {
-    CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, ^{
-        [super invokeTest];
-        CFRunLoopStop(CFRunLoopGetCurrent());
-    });
-    CFRunLoopRun();
-}
-
-- (void)deleteFiles {
-    // Only the parent should delete files in setUp/tearDown
-    if (self.isParent) {
-        [super deleteFiles];
-    }
-}
-
-+ (void)preintializeSchema {
-    // Do nothing so that we can test global schema init in child processes
-}
-
-- (NSString *)locateXCTest {
-    NSString *pathString = [NSProcessInfo processInfo].environment[@"PATH"];
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    for (NSString *directory in [pathString componentsSeparatedByString:@":"]) {
-        NSString *candidatePath = [directory stringByAppendingPathComponent:@"xctest"];
-        if ([fileManager isExecutableFileAtPath:candidatePath])
-            return candidatePath;
-    }
-    return nil;
-}
-
-#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
-- (NSTask *)childTask {
-    NSString *testName = [NSString stringWithFormat:@"%@/%@", self.className, self.testName];
-    NSMutableDictionary *env = [NSProcessInfo.processInfo.environment mutableCopy];
-    env[@"RLMProcessIsChild"] = @"true";
-    env[@"RLMParentProcessBundleID"] = [NSBundle mainBundle].bundleIdentifier;
-
-    // Don't inherit the config file in the subprocess, as multiple XCTest
-    // processes talking to a single Xcode instance doesn't work at all
-    [env removeObjectForKey:@"XCTestConfigurationFilePath"];
-
-    NSTask *task = [[NSTask alloc] init];
-    task.launchPath = self.xctestPath;
-    task.arguments = @[@"-XCTest", testName, self.testsPath];
-    task.environment = env;
-    task.standardError = nil;
-    return task;
-}
-
-- (int)runChildAndWait {
-    NSPipe *pipe = [NSPipe pipe];
-    NSMutableData *buffer = [[NSMutableData alloc] init];
-
-    // Filter the output from the child process to reduce xctest noise
-    pipe.fileHandleForReading.readabilityHandler = ^(NSFileHandle *file) {
-        [buffer appendData:[file availableData]];
-        const char *newline;
-        const char *start = buffer.bytes;
-        const char *end = start + buffer.length;
-        while ((newline = memchr(start, '\n', end - start))) {
-            if (newline < start + 17 ||
-                (memcmp(start, "Test Suite", 10) && memcmp(start, "Test Case", 9) && memcmp(start, "	 Executed 1 test", 17))) {
-                fwrite(start, newline - start + 1, 1, stderr);
-            }
-            start = newline + 1;
-        }
-
-        // Remove everything up to the last newline, leaving any data not newline-terminated in the buffer
-        [buffer replaceBytesInRange:NSMakeRange(0, start - (char *)buffer.bytes) withBytes:0 length:0];
-    };
-
-    NSTask *task = [self childTask];
-    task.standardError = pipe;
-    [task launch];
-    [task waitUntilExit];
-
-    return task.terminationStatus;
-}
-#else
-- (NSTask *)childTask {
-    return nil;
-}
-
-- (int)runChildAndWait {
-    return 1;
-}
-#endif
-@end

+ 0 - 56
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.h

@@ -1,56 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2014 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 <XCTest/XCTest.h>
-#import "RLMAssertions.h"
-#import "RLMTestObjects.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-NSURL *RLMTestRealmURL(void);
-NSURL *RLMDefaultRealmURL(void);
-NSString *RLMRealmPathForFile(NSString *);
-NSData *RLMGenerateKey(void);
-#ifdef __cplusplus
-}
-#endif
-
-@interface RLMTestCase : XCTestCase
-
-- (RLMRealm *)realmWithTestPath;
-- (RLMRealm *)realmWithTestPathAndSchema:(nullable RLMSchema *)schema;
-
-- (RLMRealm *)inMemoryRealmWithIdentifier:(NSString *)identifier;
-- (RLMRealm *)readOnlyRealmWithURL:(NSURL *)fileURL error:(NSError **)error;
-
-- (void)deleteFiles;
-- (void)deleteRealmFileAtURL:(NSURL *)fileURL;
-
-- (void)waitForNotification:(RLMNotification)expectedNote realm:(RLMRealm *)realm block:(dispatch_block_t)block;
-
-- (nullable id)nonLiteralNil;
-
-- (void)dispatchAsync:(dispatch_block_t)block;
-- (void)dispatchAsyncAndWait:(dispatch_block_t)block;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 223
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.m

@@ -1,223 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2014 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 "RLMTestCase.h"
-
-#import "RLMRealmConfiguration_Private.h"
-#import <Realm/RLMRealm_Private.h>
-#import <Realm/RLMSchema_Private.h>
-#import <Realm/RLMRealmConfiguration_Private.h>
-
-static NSString *parentProcessBundleIdentifier()
-{
-    static BOOL hasInitializedIdentifier;
-    static NSString *identifier;
-    if (!hasInitializedIdentifier) {
-        identifier = [NSProcessInfo processInfo].environment[@"RLMParentProcessBundleID"];
-        hasInitializedIdentifier = YES;
-    }
-
-    return identifier;
-}
-
-NSURL *RLMDefaultRealmURL() {
-    return [NSURL fileURLWithPath:RLMRealmPathForFileAndBundleIdentifier(@"default.realm", parentProcessBundleIdentifier())];
-}
-
-NSURL *RLMTestRealmURL() {
-    return [NSURL fileURLWithPath:RLMRealmPathForFileAndBundleIdentifier(@"test.realm", parentProcessBundleIdentifier())];
-}
-
-static void deleteOrThrow(NSURL *fileURL) {
-    NSError *error;
-    if (![[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error]) {
-        if (error.code != NSFileNoSuchFileError) {
-            @throw [NSException exceptionWithName:@"RLMTestException"
-                                           reason:[@"Unable to delete realm: " stringByAppendingString:error.description]
-                                         userInfo:nil];
-        }
-    }
-}
-
-NSData *RLMGenerateKey() {
-    uint8_t buffer[64];
-    (void)SecRandomCopyBytes(kSecRandomDefault, 64, buffer);
-    return [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
-}
-
-static BOOL encryptTests() {
-    static BOOL encryptAll = NO;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        if (getenv("REALM_ENCRYPT_ALL")) {
-            encryptAll = YES;
-        }
-    });
-    return encryptAll;
-}
-
-@implementation RLMTestCase {
-    dispatch_queue_t _bgQueue;
-}
-
-+ (void)setUp {
-    [super setUp];
-#if DEBUG || !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
-    // Disable actually syncing anything to the disk to greatly speed up the
-    // tests, but only when not running on device because it can't be
-    // re-enabled and we need it enabled for performance tests
-    RLMDisableSyncToDisk();
-#endif
-
-    if (!getenv("RLMProcessIsChild")) {
-        [self preinitializeSchema];
-
-        // Clean up any potentially lingering Realm files from previous runs
-        [NSFileManager.defaultManager removeItemAtPath:RLMRealmPathForFile(@"") error:nil];
-    }
-
-    // Ensure the documents directory exists as it sometimes doesn't after
-    // resetting the simulator
-    [NSFileManager.defaultManager createDirectoryAtURL:RLMDefaultRealmURL().URLByDeletingLastPathComponent
-                           withIntermediateDirectories:YES attributes:nil error:nil];
-}
-
-// This ensures the shared schema is initialized outside of of a test case,
-// so if an exception is thrown, it will kill the test process rather than
-// allowing hundreds of test cases to fail in strange ways
-// This is overridden by RLMMultiProcessTestCase to support testing the schema init
-+ (void)preinitializeSchema {
-    [RLMSchema sharedSchema];
-}
-
-- (void)deleteFiles {
-    // Clear cache
-    [self resetRealmState];
-
-    // Delete Realm files
-    [self deleteRealmFileAtURL:RLMDefaultRealmURL()];
-    [self deleteRealmFileAtURL:RLMTestRealmURL()];
-}
-
-- (void)resetRealmState {
-    [RLMRealm resetRealmState];
-}
-
-- (void)deleteRealmFileAtURL:(NSURL *)fileURL
-{
-    deleteOrThrow(fileURL);
-    deleteOrThrow([fileURL URLByAppendingPathExtension:@"lock"]);
-    deleteOrThrow([fileURL URLByAppendingPathExtension:@"note"]);
-}
-
-- (void)invokeTest {
-    @autoreleasepool {
-        [self deleteFiles];
-
-        if (encryptTests()) {
-            RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-            configuration.encryptionKey = RLMGenerateKey();
-        }
-    }
-    @autoreleasepool {
-        [super invokeTest];
-    }
-    @autoreleasepool {
-        if (_bgQueue) {
-            dispatch_sync(_bgQueue, ^{});
-            _bgQueue = nil;
-        }
-        [self deleteFiles];
-    }
-}
-
-- (RLMRealm *)realmWithTestPath
-{
-    return [RLMRealm realmWithURL:RLMTestRealmURL()];
-}
-
-- (RLMRealm *)realmWithTestPathAndSchema:(RLMSchema *)schema {
-    RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-    configuration.fileURL = RLMTestRealmURL();
-    if (schema)
-        configuration.customSchema = schema;
-    else
-        configuration.dynamic = true;
-    return [RLMRealm realmWithConfiguration:configuration error:nil];
-}
-
-- (RLMRealm *)inMemoryRealmWithIdentifier:(NSString *)identifier {
-    RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-    configuration.inMemoryIdentifier = identifier;
-    return [RLMRealm realmWithConfiguration:configuration error:nil];
-}
-
-- (RLMRealm *)readOnlyRealmWithURL:(NSURL *)fileURL error:(NSError **)error {
-    RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
-    configuration.fileURL = fileURL;
-    configuration.readOnly = true;
-    return [RLMRealm realmWithConfiguration:configuration error:error];
-}
-
-- (void)waitForNotification:(NSString *)expectedNote realm:(RLMRealm *)realm block:(dispatch_block_t)block {
-    XCTestExpectation *notificationFired = [self expectationWithDescription:@"notification fired"];
-    __block RLMNotificationToken *token = [realm addNotificationBlock:^(NSString *note, RLMRealm *realm) {
-        XCTAssertNotNil(note, @"Note should not be nil");
-        XCTAssertNotNil(realm, @"Realm should not be nil");
-        if (note == expectedNote) { // Check pointer equality to ensure we're using the interned string constant
-            [notificationFired fulfill];
-            [token invalidate];
-        }
-    }];
-
-    dispatch_queue_t queue = dispatch_queue_create("background", 0);
-    dispatch_async(queue, ^{
-        @autoreleasepool {
-            block();
-        }
-    });
-
-    [self waitForExpectationsWithTimeout:10.0 handler:nil];
-
-    // wait for queue to finish
-    dispatch_sync(queue, ^{});
-}
-
-- (void)dispatchAsync:(dispatch_block_t)block {
-    if (!_bgQueue) {
-        _bgQueue = dispatch_queue_create("test background queue", 0);
-    }
-    dispatch_async(_bgQueue, ^{
-        @autoreleasepool {
-            block();
-        }
-    });
-}
-
-- (void)dispatchAsyncAndWait:(dispatch_block_t)block {
-    [self dispatchAsync:block];
-    dispatch_sync(_bgQueue, ^{});
-}
-
-- (id)nonLiteralNil
-{
-    return nil;
-}
-
-@end
-

+ 0 - 463
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.h

@@ -1,463 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2014 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 <Realm/Realm.h>
-
-#if __has_extension(objc_generics)
-#define RLM_GENERIC_ARRAY(CLASS) RLMArray<CLASS *><CLASS>
-#else
-#define RLM_GENERIC_ARRAY(CLASS) RLMArray<CLASS>
-#endif
-
-#pragma mark - Abstract Objects
-#pragma mark -
-
-#pragma mark SingleTypeObjects
-
-@interface StringObject : RLMObject
-
-@property NSString *stringCol;
-
-@end
-
-@interface IntObject : RLMObject
-
-@property int intCol;
-
-@end
-
-@interface AllIntSizesObject : RLMObject
-// int8_t not supported due to being ambiguous with BOOL
-
-@property int16_t int16;
-@property int32_t int32;
-@property int64_t int64;
-
-@end
-
-@interface FloatObject : RLMObject
-
-@property float floatCol;
-
-@end
-
-@interface DoubleObject : RLMObject
-
-@property double doubleCol;
-
-@end
-
-@interface BoolObject : RLMObject
-
-@property BOOL boolCol;
-
-@end
-
-@interface DateObject : RLMObject
-
-@property NSDate *dateCol;
-
-@end
-
-@interface BinaryObject : RLMObject
-
-@property NSData *binaryCol;
-
-@end
-
-@interface UTF8Object : RLMObject
-@property NSString *柱колоéнǢкƱаم;
-@end
-
-@interface IndexedStringObject : RLMObject
-@property NSString *stringCol;
-@end
-
-RLM_ARRAY_TYPE(StringObject)
-RLM_ARRAY_TYPE(IntObject)
-
-@interface LinkStringObject : RLMObject
-@property StringObject *objectCol;
-@end
-
-@interface LinkIndexedStringObject : RLMObject
-@property IndexedStringObject *objectCol;
-@end
-
-@interface RequiredPropertiesObject : RLMObject
-@property NSString *stringCol;
-@property NSData *binaryCol;
-@property NSDate *dateCol;
-@end
-
-@interface IgnoredURLObject : RLMObject
-@property NSString *name;
-@property NSURL *url;
-@end
-
-#pragma mark AllTypesObject
-
-@interface AllTypesObject : RLMObject
-
-@property BOOL          boolCol;
-@property int           intCol;
-@property float         floatCol;
-@property double        doubleCol;
-@property NSString     *stringCol;
-@property NSData       *binaryCol;
-@property NSDate       *dateCol;
-@property bool          cBoolCol;
-@property int64_t     longCol;
-@property StringObject *objectCol;
-@property (readonly) RLMLinkingObjects *linkingObjectsCol;
-
-@end
-
-RLM_ARRAY_TYPE(AllTypesObject)
-
-@interface LinkToAllTypesObject : RLMObject
-@property AllTypesObject *allTypesCol;
-@end
-
-@interface ArrayOfAllTypesObject : RLMObject
-@property RLM_GENERIC_ARRAY(AllTypesObject) *array;
-@end
-
-@interface AllOptionalTypes : RLMObject
-@property NSNumber<RLMInt> *intObj;
-@property NSNumber<RLMFloat> *floatObj;
-@property NSNumber<RLMDouble> *doubleObj;
-@property NSNumber<RLMBool> *boolObj;
-@property NSString *string;
-@property NSData *data;
-@property NSDate *date;
-@end
-
-@interface AllOptionalTypesPK : RLMObject
-@property int pk;
-
-@property NSNumber<RLMInt> *intObj;
-@property NSNumber<RLMFloat> *floatObj;
-@property NSNumber<RLMDouble> *doubleObj;
-@property NSNumber<RLMBool> *boolObj;
-@property NSString *string;
-@property NSData *data;
-@property NSDate *date;
-@end
-
-@interface AllPrimitiveArrays : RLMObject
-@property RLMArray<RLMInt> *intObj;
-@property RLMArray<RLMFloat> *floatObj;
-@property RLMArray<RLMDouble> *doubleObj;
-@property RLMArray<RLMBool> *boolObj;
-@property RLMArray<RLMString> *stringObj;
-@property RLMArray<RLMDate> *dateObj;
-@property RLMArray<RLMData> *dataObj;
-@end
-
-@interface AllOptionalPrimitiveArrays : RLMObject
-@property RLMArray<RLMInt> *intObj;
-@property RLMArray<RLMFloat> *floatObj;
-@property RLMArray<RLMDouble> *doubleObj;
-@property RLMArray<RLMBool> *boolObj;
-@property RLMArray<RLMString> *stringObj;
-@property RLMArray<RLMDate> *dateObj;
-@property RLMArray<RLMData> *dataObj;
-@end
-
-#pragma mark - Real Life Objects
-#pragma mark -
-
-#pragma mark EmployeeObject
-
-@interface EmployeeObject : RLMObject
-
-@property NSString *name;
-@property int age;
-@property BOOL hired;
-
-@end
-
-RLM_ARRAY_TYPE(EmployeeObject)
-
-#pragma mark CompanyObject
-
-@interface CompanyObject : RLMObject
-
-@property NSString *name;
-@property RLM_GENERIC_ARRAY(EmployeeObject) *employees;
-
-@end
-
-#pragma mark LinkToCompanyObject
-
-@interface LinkToCompanyObject : RLMObject
-
-@property CompanyObject *company;
-
-@end
-
-#pragma mark DogObject
-
-@interface DogObject : RLMObject
-@property NSString *dogName;
-@property int age;
-@property (readonly) RLMLinkingObjects *owners;
-@end
-
-RLM_ARRAY_TYPE(DogObject)
-
-@interface DogArrayObject : RLMObject
-@property RLM_GENERIC_ARRAY(DogObject) *dogs;
-@end
-
-
-#pragma mark OwnerObject
-
-@interface OwnerObject : RLMObject
-
-@property NSString *name;
-@property DogObject *dog;
-
-@end
-
-#pragma mark - Specific Use Objects
-#pragma mark -
-
-#pragma mark CustomAccessorsObject
-
-@interface CustomAccessorsObject : RLMObject
-
-@property (getter = getThatName) NSString *name;
-@property (setter = setTheInt:)  int age;
-
-@end
-
-#pragma mark BaseClassStringObject
-
-@interface BaseClassStringObject : RLMObject
-
-@property int intCol;
-
-@end
-
-@interface BaseClassStringObject ()
-
-@property NSString *stringCol;
-
-@end
-
-#pragma mark CircleObject
-
-@interface CircleObject : RLMObject
-
-@property NSString *data;
-@property CircleObject *next;
-
-@end
-
-RLM_ARRAY_TYPE(CircleObject);
-
-#pragma mark CircleArrayObject
-
-@interface CircleArrayObject : RLMObject
-@property RLM_GENERIC_ARRAY(CircleObject) *circles;
-@end
-
-#pragma mark ArrayPropertyObject
-
-@interface ArrayPropertyObject : RLMObject
-
-@property NSString *name;
-@property RLM_GENERIC_ARRAY(StringObject) *array;
-@property RLM_GENERIC_ARRAY(IntObject) *intArray;
-
-@end
-
-#pragma mark DynamicObject
-
-@interface DynamicObject : RLMObject
-
-@property NSString *stringCol;
-@property int intCol;
-
-@end
-
-#pragma mark AggregateObject
-
-@interface AggregateObject : RLMObject
-
-@property int     intCol;
-@property float   floatCol;
-@property double  doubleCol;
-@property BOOL    boolCol;
-@property NSDate *dateCol;
-
-@end
-
-RLM_ARRAY_TYPE(AggregateObject)
-@interface AggregateArrayObject : RLMObject
-@property RLMArray<AggregateObject *><AggregateObject> *array;
-@end
-
-#pragma mark PrimaryStringObject
-
-@interface PrimaryStringObject : RLMObject
-@property NSString *stringCol;
-@property int intCol;
-@end
-
-@interface PrimaryNullableStringObject : RLMObject
-@property NSString *stringCol;
-@property int intCol;
-@end
-
-@interface PrimaryIntObject : RLMObject
-@property int intCol;
-@end
-RLM_ARRAY_TYPE(PrimaryIntObject);
-
-@interface PrimaryInt64Object : RLMObject
-@property int64_t int64Col;
-@end
-
-@interface PrimaryNullableIntObject : RLMObject
-@property NSNumber<RLMInt> *optIntCol;
-@property int value;
-@end
-
-@interface ReadOnlyPropertyObject : RLMObject
-@property (readonly) NSNumber *readOnlyUnsupportedProperty;
-@property (readonly) int readOnlySupportedProperty;
-@property (readonly) int readOnlyPropertyMadeReadWriteInClassExtension;
-@end
-
-#pragma mark IntegerArrayPropertyObject
-
-@interface IntegerArrayPropertyObject : RLMObject
-
-@property NSInteger number;
-@property RLM_GENERIC_ARRAY(IntObject) *array;
-
-@end
-
-@interface NumberObject : RLMObject
-@property NSNumber<RLMInt> *intObj;
-@property NSNumber<RLMFloat> *floatObj;
-@property NSNumber<RLMDouble> *doubleObj;
-@property NSNumber<RLMBool> *boolObj;
-@end
-
-@interface NumberDefaultsObject : NumberObject
-@end
-
-@interface RequiredNumberObject : RLMObject
-@property NSNumber<RLMInt> *intObj;
-@property NSNumber<RLMFloat> *floatObj;
-@property NSNumber<RLMDouble> *doubleObj;
-@property NSNumber<RLMBool> *boolObj;
-@end
-
-#pragma mark CustomInitializerObject
-
-@interface CustomInitializerObject : RLMObject
-@property NSString *stringCol;
-@end
-
-#pragma mark AbstractObject
-
-@interface AbstractObject : RLMObject
-@end
-
-#pragma mark PersonObject
-
-@class PersonObject;
-RLM_ARRAY_TYPE(PersonObject);
-
-@interface PersonObject : RLMObject
-@property NSString *name;
-@property NSInteger age;
-@property RLMArray<PersonObject> *children;
-@property (readonly) RLMLinkingObjects *parents;
-@end
-
-@interface PrimaryEmployeeObject : EmployeeObject
-@end
-RLM_ARRAY_TYPE(PrimaryEmployeeObject);
-
-@interface LinkToPrimaryEmployeeObject : RLMObject
-@property PrimaryEmployeeObject *wrapped;
-@end
-
-@interface PrimaryCompanyObject : RLMObject
-@property NSString *name;
-@property RLM_GENERIC_ARRAY(PrimaryEmployeeObject) *employees;
-@property PrimaryEmployeeObject *intern;
-@property LinkToPrimaryEmployeeObject *wrappedIntern;
-@end
-RLM_ARRAY_TYPE(PrimaryCompanyObject);
-
-@interface ArrayOfPrimaryCompanies : RLMObject
-@property RLM_GENERIC_ARRAY(PrimaryCompanyObject) *companies;
-@end
-
-#pragma mark ComputedPropertyNotExplicitlyIgnoredObject
-
-@interface ComputedPropertyNotExplicitlyIgnoredObject : RLMObject
-@property NSString *_URLBacking;
-@property NSURL *URL;
-@end
-
-@interface RenamedProperties1 : RLMObject
-@property (nonatomic) int propA;
-@property (nonatomic) NSString *propB;
-@property (readonly, nonatomic) RLMLinkingObjects *linking1;
-@property (readonly, nonatomic) RLMLinkingObjects *linking2;
-@end
-
-@interface RenamedProperties2 : RLMObject
-@property (nonatomic) int propC;
-@property (nonatomic) NSString *propD;
-@property (readonly, nonatomic) RLMLinkingObjects *linking1;
-@property (readonly, nonatomic) RLMLinkingObjects *linking2;
-@end
-
-RLM_ARRAY_TYPE(RenamedProperties1)
-RLM_ARRAY_TYPE(RenamedProperties2)
-
-@interface LinkToRenamedProperties1 : RLMObject
-@property (nonatomic) RenamedProperties1 *linkA;
-@property (nonatomic) RenamedProperties2 *linkB;
-@property (nonatomic) RLM_GENERIC_ARRAY(RenamedProperties1) *array;
-@end
-
-@interface LinkToRenamedProperties2 : RLMObject
-@property (nonatomic) RenamedProperties2 *linkC;
-@property (nonatomic) RenamedProperties1 *linkD;
-@property (nonatomic) RLM_GENERIC_ARRAY(RenamedProperties2) *array;
-@end
-
-@interface RenamedPrimaryKey : RLMObject
-@property (nonatomic) int pk;
-@property (nonatomic) int value;
-@end
-
-#pragma mark FakeObject
-
-@interface FakeObject : NSObject
-@end

+ 0 - 409
Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.m

@@ -1,409 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2014 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 "RLMTestObjects.h"
-#import <Realm/RLMObject_Private.h>
-
-#pragma mark - Abstract Objects
-#pragma mark -
-
-#pragma mark OneTypeObjects
-
-@implementation StringObject
-@end
-
-@implementation IntObject
-@end
-
-@implementation AllIntSizesObject
-@end
-
-@implementation FloatObject
-@end
-
-@implementation DoubleObject
-@end
-
-@implementation BoolObject
-@end
-
-@implementation DateObject
-@end
-
-@implementation BinaryObject
-@end
-
-@implementation UTF8Object
-@end
-
-@implementation IndexedStringObject
-+ (NSArray *)indexedProperties {
-    return @[@"stringCol"];
-}
-@end
-
-@implementation LinkStringObject
-@end
-
-@implementation LinkIndexedStringObject
-@end
-
-@implementation RequiredPropertiesObject
-+ (NSArray *)requiredProperties {
-    return @[@"stringCol", @"binaryCol"];
-}
-@end
-
-@implementation IgnoredURLObject
-+ (NSArray *)ignoredProperties {
-    return @[@"url"];
-}
-@end
-
-#pragma mark AllTypesObject
-
-@implementation AllTypesObject
-+ (NSDictionary *)linkingObjectsProperties
-{
-    return @{ @"linkingObjectsCol": [RLMPropertyDescriptor descriptorWithClass:LinkToAllTypesObject.class propertyName:@"allTypesCol"] };
-}
-+ (NSArray *)requiredProperties
-{
-    return @[@"stringCol", @"dateCol", @"binaryCol"];
-}
-@end
-
-@implementation ArrayOfAllTypesObject
-@end
-
-@implementation LinkToAllTypesObject
-@end
-
-@implementation AllOptionalTypes
-@end
-@implementation AllPrimitiveArrays
-+ (NSArray *)requiredProperties {
-    return @[@"intObj", @"floatObj", @"doubleObj", @"boolObj", @"stringObj", @"dateObj", @"dataObj"];
-}
-@end
-@implementation AllOptionalPrimitiveArrays
-@end
-
-@implementation AllOptionalTypesPK
-+ (NSString *)primaryKey {
-    return @"pk";
-}
-+ (NSDictionary *)defaultPropertyValues {
-    return @{@"pk": NSUUID.UUID.UUIDString};
-}
-@end
-
-#pragma mark - Real Life Objects
-#pragma mark -
-
-#pragma mark EmployeeObject
-
-@implementation EmployeeObject
-@end
-
-#pragma mark CompanyObject
-
-@implementation CompanyObject
-@end
-
-@implementation PrimaryEmployeeObject
-+ (NSString *)primaryKey {
-    return @"name";
-}
-@end
-
-@implementation LinkToPrimaryEmployeeObject
-@end
-
-@implementation PrimaryCompanyObject
-+ (NSString *)primaryKey {
-    return @"name";
-}
-@end
-
-@implementation ArrayOfPrimaryCompanies
-@end
-
-#pragma mark LinkToCompanyObject
-
-@implementation LinkToCompanyObject
-@end
-
-#pragma mark DogObject
-
-@class OwnerObject;
-
-@implementation DogObject
-+ (NSDictionary *)linkingObjectsProperties
-{
-    return @{ @"owners": [RLMPropertyDescriptor descriptorWithClass:OwnerObject.class propertyName:@"dog"] };
-}
-@end
-
-#pragma mark OwnerObject
-
-@implementation OwnerObject
-
-- (BOOL)isEqual:(id)other
-{
-    return [self isEqualToObject:other];
-}
-
-@end
-
-#pragma mark - Specific Use Objects
-#pragma mark -
-
-#pragma mark CustomAccessorsObject
-
-@implementation CustomAccessorsObject
-@end
-
-#pragma mark BaseClassStringObject
-
-@implementation BaseClassStringObject
-@end
-
-#pragma mark CircleObject
-
-@implementation CircleObject
-@end
-
-#pragma mark CircleArrayObject
-
-@implementation CircleArrayObject
-@end
-
-#pragma mark ArrayPropertyObject
-
-@implementation ArrayPropertyObject
-@end
-
-#pragma mark DynamicObject
-
-@implementation DynamicObject
-@end
-
-#pragma mark AggregateObject
-
-@implementation AggregateObject
-@end
-@implementation AggregateArrayObject
-@end
-
-#pragma mark PrimaryStringObject
-
-@implementation PrimaryStringObject
-+ (NSString *)primaryKey {
-    return @"stringCol";
-}
-+ (NSArray *)requiredProperties {
-    return @[@"stringCol"];
-}
-@end
-
-@implementation PrimaryNullableStringObject
-+ (NSString *)primaryKey {
-    return @"stringCol";
-}
-@end
-
-@implementation PrimaryIntObject
-+ (NSString *)primaryKey {
-    return @"intCol";
-}
-@end
-
-@implementation PrimaryInt64Object
-+ (NSString *)primaryKey {
-    return @"int64Col";
-}
-@end
-
-@implementation PrimaryNullableIntObject
-+ (NSString *)primaryKey {
-    return @"optIntCol";
-}
-@end
-
-
-#pragma mark ReadOnlyPropertyObject
-
-@interface ReadOnlyPropertyObject ()
-@property (readwrite) int readOnlyPropertyMadeReadWriteInClassExtension;
-@end
-
-@implementation ReadOnlyPropertyObject
-- (NSNumber *)readOnlyUnsupportedProperty {
-    return nil;
-}
-@end
-
-#pragma mark IntegerArrayPropertyObject
-
-@implementation IntegerArrayPropertyObject
-@end
-
-@implementation NumberObject
-@end
-
-@implementation NumberDefaultsObject
-+ (NSDictionary *)defaultPropertyValues {
-    return @{@"intObj" : @1,
-             @"floatObj" : @2.2f,
-             @"doubleObj" : @3.3,
-             @"boolObj" : @NO};
-}
-@end
-
-@implementation RequiredNumberObject
-+ (NSArray *)requiredProperties {
-    return @[@"intObj", @"floatObj", @"doubleObj", @"boolObj"];
-}
-@end
-
-#pragma mark CustomInitializerObject
-
-@implementation CustomInitializerObject
-
-- (instancetype)init {
-    self = [super init];
-    if (self) {
-        self.stringCol = @"test";
-    }
-    return self;
-}
-
-@end
-
-#pragma mark AbstractObject
-
-@implementation AbstractObject
-@end
-
-#pragma mark PersonObject
-
-@implementation PersonObject
-
-+ (NSDictionary *)linkingObjectsProperties
-{
-    return @{ @"parents": [RLMPropertyDescriptor descriptorWithClass:PersonObject.class propertyName:@"children"] };
-}
-
-- (BOOL)isEqual:(id)other
-{
-    if (![other isKindOfClass:[PersonObject class]]) {
-        return NO;
-    }
-
-    PersonObject *otherPerson = other;
-    return [self.name isEqual:otherPerson.name] && self.age == otherPerson.age && [self.children isEqual:otherPerson.children];
-}
-
-@end
-
-@implementation RenamedProperties1
-+ (NSString *)_realmObjectName {
-    return @"Renamed Properties";
-}
-+ (NSDictionary *)_realmColumnNames {
-    return @{@"propA": @"prop 1",
-             @"propB": @"prop 2"};
-}
-+ (NSDictionary *)linkingObjectsProperties {
-    return @{@"linking1": [RLMPropertyDescriptor descriptorWithClass:LinkToRenamedProperties1.class propertyName:@"linkA"],
-             @"linking2": [RLMPropertyDescriptor descriptorWithClass:LinkToRenamedProperties2.class propertyName:@"linkD"]};
-}
-@end
-
-@implementation RenamedProperties2
-+ (NSString *)_realmObjectName {
-    return @"Renamed Properties";
-}
-+ (NSDictionary *)_realmColumnNames {
-    return @{@"propC": @"prop 1",
-             @"propD": @"prop 2"};
-}
-+ (NSDictionary *)linkingObjectsProperties {
-    return @{@"linking1": [RLMPropertyDescriptor descriptorWithClass:LinkToRenamedProperties1.class propertyName:@"linkA"],
-             @"linking2": [RLMPropertyDescriptor descriptorWithClass:LinkToRenamedProperties2.class propertyName:@"linkD"]};
-}
-@end
-
-@implementation LinkToRenamedProperties1
-+ (NSString *)_realmObjectName {
-    return @"Link To Renamed Properties";
-}
-+ (NSDictionary *)_realmColumnNames {
-    return @{@"linkA": @"Link A",
-             @"linkB": @"Link B"};
-}
-@end
-
-@implementation LinkToRenamedProperties2
-+ (NSString *)_realmObjectName {
-    return @"Link To Renamed Properties";
-}
-+ (NSDictionary *)_realmColumnNames {
-    return @{@"linkC": @"Link A",
-             @"linkD": @"Link B"};
-}
-@end
-
-@implementation RenamedPrimaryKey
-+ (NSString *)primaryKey {
-    return @"pk";
-}
-+ (NSDictionary *)_realmColumnNames {
-    return @{@"pk": @"Primary Key",
-             @"value": @"Value"};
-}
-@end
-
-#pragma mark FakeObject
-
-@implementation FakeObject
-+ (Class)objectUtilClass:(BOOL)isSwift { return RLMObjectUtilClass(isSwift); }
-+ (NSArray *)ignoredProperties { return nil; }
-+ (NSArray *)indexedProperties { return nil; }
-+ (NSString *)primaryKey { return nil; }
-+ (NSArray *)requiredProperties { return nil; }
-+ (NSDictionary *)linkingObjectsProperties { return nil; }
-+ (BOOL)shouldIncludeInDefaultSchema { return NO; }
-+ (NSString *)_realmObjectName { return nil; }
-+ (NSDictionary *)_realmColumnNames { return nil; }
-@end
-
-#pragma mark ComputedPropertyNotExplicitlyIgnoredObject
-
-@implementation ComputedPropertyNotExplicitlyIgnoredObject
-
-- (NSURL *)URL {
-    return [NSURL URLWithString:self._URLBacking];
-}
-
-- (void)setURL:(NSURL *)URL {
-    self._URLBacking = URL.absoluteString;
-}
-
-@end

+ 5 - 0
Carthage/Checkouts/realm-cocoa/Realm/Tests/RealmTests.mm

@@ -30,6 +30,7 @@
 #import <thread>
 
 #import <realm/util/file.hpp>
+#import <realm/group_shared_options.hpp>
 
 @interface RLMRealm ()
 + (BOOL)isCoreDebug;
@@ -204,6 +205,7 @@
         XCTAssertEqualObjects(oldData, newData); \
 } while (0)
 
+#ifndef REALM_SPM
 - (void)testFileFormatUpgradeRequiredDeleteRealmIfNeeded {
     RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
     config.deleteRealmIfMigrationNeeded = YES;
@@ -263,6 +265,7 @@
     XCTAssertEqualObjects([NSData dataWithContentsOfURL:bundledRealmURL],
                           [NSData dataWithContentsOfURL:config.fileURL]);
 }
+#endif // REALM_SPM
 
 #if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || !TARGET_RT_64_BIT)
 - (void)testExceedingVirtualAddressSpace {
@@ -1690,6 +1693,7 @@
 
 #pragma mark - Assorted tests
 
+#ifndef REALM_SPM
 - (void)testCoreDebug {
 #if DEBUG
     XCTAssertTrue([RLMRealm isCoreDebug], @"Debug version of Realm should use librealm{-ios}-dbg");
@@ -1697,6 +1701,7 @@
     XCTAssertFalse([RLMRealm isCoreDebug], @"Release version of Realm should use librealm{-ios}");
 #endif
 }
+#endif
 
 - (void)testIsEmpty {
     RLMRealm *realm = [RLMRealm defaultRealm];

+ 2 - 13
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/RLMTestCaseUtils.swift

@@ -16,22 +16,11 @@
 //
 ////////////////////////////////////////////////////////////////////////////
 
+import RealmTestSupport
+
 extension RLMTestCase {
     func assertThrowsWithReasonMatching<T>(_ block: @autoclosure @escaping () -> T, _ regexString: String,
         _ message: String? = nil, fileName: String = #file, lineNumber: UInt = #line) {
             RLMAssertThrowsWithReasonMatchingSwift(self, { _ = block() }, regexString, message, fileName, lineNumber)
     }
 }
-
-#if !swift(>=3.2)
-func XCTAssertEqual<F: FloatingPoint>(_ expression1: F, _ expression2: F, accuracy: F,
-                                      _ message: @autoclosure () -> String = "",
-                                      file: StaticString = #file, line: UInt = #line) {
-    XCTAssertEqualWithAccuracy(expression1, expression2, accuracy: accuracy, message, file: file, line: line)
-}
-func XCTAssertNotEqual<F: FloatingPoint>(_ expression1: F, _ expression2: F, accuracy: F,
-                                         _ message: @autoclosure () -> String = "",
-                                         file: StaticString = #file, line: UInt = #line) {
-    XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, message, file: file, line: line)
-}
-#endif

+ 24 - 23
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftArrayPropertyTests.swift

@@ -18,13 +18,14 @@
 
 import XCTest
 import Realm
+import RealmTestSupport
 
-class SwiftArrayPropertyTests: RLMTestCase {
+class SwiftRLMArrayPropertyTests: RLMTestCase {
 
     // Swift models
 
     func testBasicArray() {
-        let string = SwiftStringObject()
+        let string = SwiftRLMStringObject()
         string.stringCol = "string"
 
         let realm = realmWithTestPath()
@@ -32,9 +33,9 @@ class SwiftArrayPropertyTests: RLMTestCase {
         realm.add(string)
         try! realm.commitWriteTransaction()
 
-        XCTAssertEqual(SwiftStringObject.allObjects(in: realm).count, UInt(1), "There should be a single SwiftStringObject in the realm")
+        XCTAssertEqual(SwiftRLMStringObject.allObjects(in: realm).count, UInt(1), "There should be a single SwiftRLMStringObject in the realm")
 
-        let array = SwiftArrayPropertyObject()
+        let array = SwiftRLMArrayPropertyObject()
         array.name = "arrayObject"
         array.array.add(string)
         XCTAssertEqual(array.array.count, UInt(1))
@@ -45,9 +46,9 @@ class SwiftArrayPropertyTests: RLMTestCase {
         array.array.add(string)
         try! realm.commitWriteTransaction()
 
-        let arrayObjects = SwiftArrayPropertyObject.allObjects(in: realm) as! RLMResults<SwiftArrayPropertyObject>
+        let arrayObjects = SwiftRLMArrayPropertyObject.allObjects(in: realm) as! RLMResults<SwiftRLMArrayPropertyObject>
 
-        XCTAssertEqual(arrayObjects.count, UInt(1), "There should be a single SwiftStringObject in the realm")
+        XCTAssertEqual(arrayObjects.count, UInt(1), "There should be a single SwiftRLMStringObject in the realm")
         let cmp = arrayObjects.firstObject()!.array.firstObject()!
         XCTAssertTrue(string.isEqual(to: cmp), "First array object should be the string object we added")
     }
@@ -56,14 +57,14 @@ class SwiftArrayPropertyTests: RLMTestCase {
         let realm = realmWithTestPath()
 
         realm.beginWriteTransaction()
-        let array = SwiftArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []]);
+        let array = SwiftRLMArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
         XCTAssertNotNil(array.array, "Should be able to get an empty array")
         XCTAssertEqual(array.array.count, UInt(0), "Should start with no array elements")
 
-        let obj = SwiftStringObject()
+        let obj = SwiftRLMStringObject()
         obj.stringCol = "a"
         array.array.add(obj)
-        array.array.add(SwiftStringObject.create(in: realm, withValue: ["b"]))
+        array.array.add(SwiftRLMStringObject.create(in: realm, withValue: ["b"]))
         array.array.add(obj)
         try! realm.commitWriteTransaction()
 
@@ -80,15 +81,15 @@ class SwiftArrayPropertyTests: RLMTestCase {
     func testModifyDetatchedArray() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
-        let arObj = SwiftArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
+        let arObj = SwiftRLMArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
         XCTAssertNotNil(arObj.array, "Should be able to get an empty array")
         XCTAssertEqual(arObj.array.count, UInt(0), "Should start with no array elements")
 
-        let obj = SwiftStringObject()
+        let obj = SwiftRLMStringObject()
         obj.stringCol = "a"
         let array = arObj.array
         array.add(obj)
-        array.add(SwiftStringObject.create(in: realm, withValue: ["b"]))
+        array.add(SwiftRLMStringObject.create(in: realm, withValue: ["b"]))
         try! realm.commitWriteTransaction()
 
         XCTAssertEqual(array.count, UInt(2), "Should have two elements in array")
@@ -101,27 +102,27 @@ class SwiftArrayPropertyTests: RLMTestCase {
 
         realm.beginWriteTransaction()
 
-        let obj = SwiftArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
-        let child1 = SwiftStringObject.create(in: realm, withValue: ["a"])
-        let child2 = SwiftStringObject()
+        let obj = SwiftRLMArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
+        let child1 = SwiftRLMStringObject.create(in: realm, withValue: ["a"])
+        let child2 = SwiftRLMStringObject()
         child2.stringCol = "b"
         obj.array.addObjects([child2, child1] as NSArray)
         try! realm.commitWriteTransaction()
 
-        let children = SwiftStringObject.allObjects(in: realm)
-        XCTAssertEqual((children[0] as! SwiftStringObject).stringCol, "a", "First child should be 'a'")
-        XCTAssertEqual((children[1] as! SwiftStringObject).stringCol, "b", "Second child should be 'b'")
+        let children = SwiftRLMStringObject.allObjects(in: realm)
+        XCTAssertEqual((children[0] as! SwiftRLMStringObject).stringCol, "a", "First child should be 'a'")
+        XCTAssertEqual((children[1] as! SwiftRLMStringObject).stringCol, "b", "Second child should be 'b'")
     }
 
     // FIXME: Support unmanaged RLMArray's in Swift-defined models
     //    func testUnmanaged() {
     //        let realm = realmWithTestPath()
     //
-    //        let array = SwiftArrayPropertyObject()
+    //        let array = SwiftRLMArrayPropertyObject()
     //        array.name = "name"
     //        XCTAssertNotNil(array.array, "RLMArray property should get created on access")
     //
-    //        let obj = SwiftStringObject()
+    //        let obj = SwiftRLMStringObject()
     //        obj.stringCol = "a"
     //        array.array.addObject(obj)
     //        array.array.addObject(obj)
@@ -131,8 +132,8 @@ class SwiftArrayPropertyTests: RLMTestCase {
     //        try! realm.commitWriteTransaction()
     //
     //        XCTAssertEqual(array.array.count, UInt(2), "Should have two elements in array")
-    //        XCTAssertEqual((array.array[0] as SwiftStringObject).stringCol, "a", "First element should have property value 'a'")
-    //        XCTAssertEqual((array.array[1] as SwiftStringObject).stringCol, "a", "Second element should have property value 'a'")
+    //        XCTAssertEqual((array.array[0] as SwiftRLMStringObject).stringCol, "a", "First element should have property value 'a'")
+    //        XCTAssertEqual((array.array[1] as SwiftRLMStringObject).stringCol, "a", "Second element should have property value 'a'")
     //    }
 
     // Objective-C models
@@ -167,7 +168,7 @@ class SwiftArrayPropertyTests: RLMTestCase {
         let realm = realmWithTestPath()
 
         realm.beginWriteTransaction()
-        let array = ArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []]);
+        let array = ArrayPropertyObject.create(in: realm, withValue: ["arrayObject", [], []])
         XCTAssertNotNil(array.array, "Should be able to get an empty array")
         XCTAssertEqual(array.array.count, UInt(0), "Should start with no array elements")
 

+ 33 - 32
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftArrayTests.swift

@@ -19,8 +19,9 @@
 import XCTest
 import Realm
 import Foundation
+import RealmTestSupport
 
-class SwiftArrayTests: RLMTestCase {
+class SwiftRLMArrayTests: RLMTestCase {
 
     // Swift models
 
@@ -32,26 +33,26 @@ class SwiftArrayTests: RLMTestCase {
         let dateMinInput = Date()
         let dateMaxInput = dateMinInput.addingTimeInterval(1000)
 
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [10, 1.2 as Float, 0 as Double, true, dateMinInput])
 
         try! realm.commitWriteTransaction()
 
-        let result = SwiftAggregateObject.objects(in: realm, where: "intCol < %d", 100)
+        let result = SwiftRLMAggregateObject.objects(in: realm, where: "intCol < %d", 100)
         XCTAssertEqual(result.count, UInt(10), "10 objects added")
 
         var totalSum = 0
 
         for obj in result {
-            if let ao = obj as? SwiftAggregateObject {
+            if let ao = obj as? SwiftRLMAggregateObject {
                 totalSum += ao.intCol
             }
         }
@@ -67,21 +68,21 @@ class SwiftArrayTests: RLMTestCase {
         let dateMinInput = Date()
         let dateMaxInput = dateMinInput.addingTimeInterval(1000)
 
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
-        _ = SwiftAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [1, 0 as Float, 2.5 as Double, false, dateMaxInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
+        _ = SwiftRLMAggregateObject.create(in: realm, withValue: [0, 1.2 as Float, 0 as Double, true, dateMinInput])
 
         try! realm.commitWriteTransaction()
 
-        let noArray = SwiftAggregateObject.objects(in: realm, where: "boolCol == NO")
-        let yesArray = SwiftAggregateObject.objects(in: realm, where: "boolCol == YES")
+        let noArray = SwiftRLMAggregateObject.objects(in: realm, where: "boolCol == NO")
+        let yesArray = SwiftRLMAggregateObject.objects(in: realm, where: "boolCol == YES")
 
         // SUM ::::::::::::::::::::::::::::::::::::::::::::::
         // Test int sum
@@ -166,7 +167,7 @@ class SwiftArrayTests: RLMTestCase {
         realm.beginWriteTransaction()
 
         for _ in 0..<1012 {
-            let person = SwiftEmployeeObject()
+            let person = SwiftRLMEmployeeObject()
             person.name = "Mary"
             person.age = 24
             person.hired = true
@@ -175,7 +176,7 @@ class SwiftArrayTests: RLMTestCase {
 
         try! realm.commitWriteTransaction()
 
-        let description = SwiftEmployeeObject.allObjects(in: realm).description
+        let description = SwiftRLMEmployeeObject.allObjects(in: realm).description
 
         XCTAssertTrue((description as NSString).range(of: "name").location != Foundation.NSNotFound, "property names should be displayed when calling \"description\" on RLMArray")
         XCTAssertTrue((description as NSString).range(of: "Mary").location != Foundation.NSNotFound, "property values should be displayed when calling \"description\" on RLMArray")
@@ -191,17 +192,17 @@ class SwiftArrayTests: RLMTestCase {
 
         realm.beginWriteTransaction()
 
-        let po1 = SwiftEmployeeObject()
+        let po1 = SwiftRLMEmployeeObject()
         po1.age = 40
         po1.name = "Joe"
         po1.hired = true
 
-        let po2 = SwiftEmployeeObject()
+        let po2 = SwiftRLMEmployeeObject()
         po2.age = 30
         po2.name = "John"
         po2.hired = false
 
-        let po3 = SwiftEmployeeObject()
+        let po3 = SwiftRLMEmployeeObject()
         po3.age = 25
         po3.name = "Jill"
         po3.hired = true
@@ -210,9 +211,9 @@ class SwiftArrayTests: RLMTestCase {
         realm.add(po2)
         realm.add(po3)
 
-        let company = SwiftCompanyObject()
+        let company = SwiftRLMCompanyObject()
         realm.add(company)
-        company.employees.addObjects(SwiftEmployeeObject.allObjects(in: realm))
+        company.employees.addObjects(SwiftRLMEmployeeObject.allObjects(in: realm))
 
         try! realm.commitWriteTransaction()
 

+ 18 - 17
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftDynamicTests.swift

@@ -20,8 +20,9 @@ import XCTest
 import Foundation
 import Realm.Private
 import Realm.Dynamic
+import RealmTestSupport
 
-class SwiftDynamicTests: RLMTestCase {
+class SwiftRLMDynamicTests: RLMTestCase {
 
     // Swift models
 
@@ -30,24 +31,24 @@ class SwiftDynamicTests: RLMTestCase {
             // open realm in autoreleasepool to create tables and then dispose
             let realm = RLMRealm(url: RLMTestRealmURL())
             realm.beginWriteTransaction()
-            _ = SwiftDynamicObject.create(in: realm, withValue: ["column1", 1])
-            _ = SwiftDynamicObject.create(in: realm, withValue: ["column2", 2])
+            _ = SwiftRLMDynamicObject.create(in: realm, withValue: ["column1", 1])
+            _ = SwiftRLMDynamicObject.create(in: realm, withValue: ["column2", 2])
             try! realm.commitWriteTransaction()
         }
         let dyrealm = realm(withTestPathAndSchema: nil)
         XCTAssertNotNil(dyrealm, "realm should not be nil")
 
         // verify schema
-        let dynSchema = dyrealm.schema[SwiftDynamicObject.className()]
+        let dynSchema = dyrealm.schema[SwiftRLMDynamicObject.className()]
         XCTAssertNotNil(dynSchema, "Should be able to get object schema dynamically")
         XCTAssertEqual(dynSchema.properties.count, Int(2))
         XCTAssertEqual(dynSchema.properties[0].name, "stringCol")
         XCTAssertEqual(dynSchema.properties[1].type, RLMPropertyType.int)
 
         // verify object type
-        let array = SwiftDynamicObject.allObjects(in: dyrealm)
+        let array = SwiftRLMDynamicObject.allObjects(in: dyrealm)
         XCTAssertEqual(array.count, UInt(2))
-        XCTAssertEqual(array.objectClassName, SwiftDynamicObject.className())
+        XCTAssertEqual(array.objectClassName, SwiftRLMDynamicObject.className())
     }
 
     func testDynamicProperties() {
@@ -55,14 +56,14 @@ class SwiftDynamicTests: RLMTestCase {
             // open realm in autoreleasepool to create tables and then dispose
             let realm = RLMRealm(url: RLMTestRealmURL())
             realm.beginWriteTransaction()
-            _ = SwiftDynamicObject.create(in: realm, withValue: ["column1", 1])
-            _ = SwiftDynamicObject.create(in: realm, withValue: ["column2", 2])
+            _ = SwiftRLMDynamicObject.create(in: realm, withValue: ["column1", 1])
+            _ = SwiftRLMDynamicObject.create(in: realm, withValue: ["column2", 2])
             try! realm.commitWriteTransaction()
         }
 
         // verify properties
         let dyrealm = realm(withTestPathAndSchema: nil)
-        let array = dyrealm.allObjects("SwiftDynamicObject")
+        let array = dyrealm.allObjects("SwiftRLMDynamicObject")
 
         XCTAssertTrue(array[0]["intCol"] as! NSNumber == 1)
         XCTAssertTrue(array[1]["stringCol"] as! String == "column2")
@@ -75,24 +76,24 @@ class SwiftDynamicTests: RLMTestCase {
             // open realm in autoreleasepool to create tables and then dispose
             let realm = RLMRealm(url: RLMTestRealmURL())
             realm.beginWriteTransaction()
-            _ = DynamicObject.create(in: realm, withValue: ["column1", 1])
-            _ = DynamicObject.create(in: realm, withValue: ["column2", 2])
+            _ = DynamicTestObject.create(in: realm, withValue: ["column1", 1])
+            _ = DynamicTestObject.create(in: realm, withValue: ["column2", 2])
             try! realm.commitWriteTransaction()
         }
         let dyrealm = realm(withTestPathAndSchema: nil)
         XCTAssertNotNil(dyrealm, "realm should not be nil")
 
         // verify schema
-        let dynSchema = dyrealm.schema[DynamicObject.className()]
+        let dynSchema = dyrealm.schema[DynamicTestObject.className()]
         XCTAssertNotNil(dynSchema, "Should be able to get object schema dynamically")
         XCTAssertTrue(dynSchema.properties.count == 2)
         XCTAssertTrue(dynSchema.properties[0].name == "stringCol")
         XCTAssertTrue(dynSchema.properties[1].type == RLMPropertyType.int)
 
         // verify object type
-        let array = DynamicObject.allObjects(in: dyrealm)
+        let array = DynamicTestObject.allObjects(in: dyrealm)
         XCTAssertEqual(array.count, UInt(2))
-        XCTAssertEqual(array.objectClassName, DynamicObject.className())
+        XCTAssertEqual(array.objectClassName, DynamicTestObject.className())
     }
 
     func testDynamicProperties_objc() {
@@ -100,14 +101,14 @@ class SwiftDynamicTests: RLMTestCase {
             // open realm in autoreleasepool to create tables and then dispose
             let realm = RLMRealm(url: RLMTestRealmURL())
             realm.beginWriteTransaction()
-            _ = DynamicObject.create(in: realm, withValue: ["column1", 1])
-            _ = DynamicObject.create(in: realm, withValue: ["column2", 2])
+            _ = DynamicTestObject.create(in: realm, withValue: ["column1", 1])
+            _ = DynamicTestObject.create(in: realm, withValue: ["column2", 2])
             try! realm.commitWriteTransaction()
         }
 
         // verify properties
         let dyrealm = realm(withTestPathAndSchema: nil)
-        let array = dyrealm.allObjects("DynamicObject")
+        let array = dyrealm.allObjects("DynamicTestObject")
 
         XCTAssertTrue(array[0]["intCol"] as! NSNumber == 1)
         XCTAssertTrue(array[1]["stringCol"] as! String == "column2")

+ 27 - 26
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftLinkTests.swift

@@ -18,72 +18,73 @@
 
 import XCTest
 import Realm
+import RealmTestSupport
 
-class SwiftLinkTests: RLMTestCase {
+class SwiftRLMLinkTests: RLMTestCase {
 
     // Swift models
 
     func testBasicLink() {
         let realm = realmWithTestPath()
 
-        let owner = SwiftOwnerObject()
+        let owner = SwiftRLMOwnerObject()
         owner.name = "Tim"
-        owner.dog = SwiftDogObject()
+        owner.dog = SwiftRLMDogObject()
         owner.dog!.dogName = "Harvie"
 
         realm.beginWriteTransaction()
         realm.add(owner)
         try! realm.commitWriteTransaction()
 
-        let owners = SwiftOwnerObject.allObjects(in: realm)
-        let dogs = SwiftDogObject.allObjects(in: realm)
+        let owners = SwiftRLMOwnerObject.allObjects(in: realm)
+        let dogs = SwiftRLMDogObject.allObjects(in: realm)
         XCTAssertEqual(owners.count, UInt(1), "Expecting 1 owner")
         XCTAssertEqual(dogs.count, UInt(1), "Expecting 1 dog")
-        XCTAssertEqual((owners[0] as! SwiftOwnerObject).name, "Tim", "Tim is named Tim")
-        XCTAssertEqual((dogs[0] as! SwiftDogObject).dogName, "Harvie", "Harvie is named Harvie")
+        XCTAssertEqual((owners[0] as! SwiftRLMOwnerObject).name, "Tim", "Tim is named Tim")
+        XCTAssertEqual((dogs[0] as! SwiftRLMDogObject).dogName, "Harvie", "Harvie is named Harvie")
 
-        let tim = owners[0] as! SwiftOwnerObject
+        let tim = owners[0] as! SwiftRLMOwnerObject
         XCTAssertEqual(tim.dog!.dogName, "Harvie", "Tim's dog should be Harvie")
     }
 
     func testMultipleOwnerLink() {
         let realm = realmWithTestPath()
 
-        let owner = SwiftOwnerObject()
+        let owner = SwiftRLMOwnerObject()
         owner.name = "Tim"
-        owner.dog = SwiftDogObject()
+        owner.dog = SwiftRLMDogObject()
         owner.dog!.dogName = "Harvie"
 
         realm.beginWriteTransaction()
         realm.add(owner)
         try! realm.commitWriteTransaction()
 
-        XCTAssertEqual(SwiftOwnerObject.allObjects(in: realm).count, UInt(1), "Expecting 1 owner")
-        XCTAssertEqual(SwiftDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
+        XCTAssertEqual(SwiftRLMOwnerObject.allObjects(in: realm).count, UInt(1), "Expecting 1 owner")
+        XCTAssertEqual(SwiftRLMDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
 
         realm.beginWriteTransaction()
-        let fiel = SwiftOwnerObject.create(in: realm, withValue: ["Fiel", NSNull()])
+        let fiel = SwiftRLMOwnerObject.create(in: realm, withValue: ["Fiel", NSNull()])
         fiel.dog = owner.dog
         try! realm.commitWriteTransaction()
 
-        XCTAssertEqual(SwiftOwnerObject.allObjects(in: realm).count, UInt(2), "Expecting 2 owners")
-        XCTAssertEqual(SwiftDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
+        XCTAssertEqual(SwiftRLMOwnerObject.allObjects(in: realm).count, UInt(2), "Expecting 2 owners")
+        XCTAssertEqual(SwiftRLMDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
     }
 
     func testLinkRemoval() {
         let realm = realmWithTestPath()
 
-        let owner = SwiftOwnerObject()
+        let owner = SwiftRLMOwnerObject()
         owner.name = "Tim"
-        owner.dog = SwiftDogObject()
+        owner.dog = SwiftRLMDogObject()
         owner.dog!.dogName = "Harvie"
 
         realm.beginWriteTransaction()
         realm.add(owner)
         try! realm.commitWriteTransaction()
 
-        XCTAssertEqual(SwiftOwnerObject.allObjects(in: realm).count, UInt(1), "Expecting 1 owner")
-        XCTAssertEqual(SwiftDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
+        XCTAssertEqual(SwiftRLMOwnerObject.allObjects(in: realm).count, UInt(1), "Expecting 1 owner")
+        XCTAssertEqual(SwiftRLMDogObject.allObjects(in: realm).count, UInt(1), "Expecting 1 dog")
 
         realm.beginWriteTransaction()
         realm.delete(owner.dog!)
@@ -92,19 +93,19 @@ class SwiftLinkTests: RLMTestCase {
         XCTAssertNil(owner.dog, "Dog should be nullified when deleted")
 
         // refresh owner and check
-        let owner2 = SwiftOwnerObject.allObjects(in: realm).firstObject() as! SwiftOwnerObject
+        let owner2 = SwiftRLMOwnerObject.allObjects(in: realm).firstObject() as! SwiftRLMOwnerObject
         XCTAssertNotNil(owner2, "Should have 1 owner")
         XCTAssertNil(owner2.dog, "Dog should be nullified when deleted")
-        XCTAssertEqual(SwiftDogObject.allObjects(in: realm).count, UInt(0), "Expecting 0 dogs")
+        XCTAssertEqual(SwiftRLMDogObject.allObjects(in: realm).count, UInt(0), "Expecting 0 dogs")
     }
 
     func testLinkingObjects() {
         let realm = realmWithTestPath()
 
-        let target = SwiftLinkTargetObject()
+        let target = SwiftRLMLinkTargetObject()
         target.id = 0
 
-        let source = SwiftLinkSourceObject()
+        let source = SwiftRLMLinkSourceObject()
         source.id = 1234
         source.link = target
 
@@ -116,14 +117,14 @@ class SwiftLinkTests: RLMTestCase {
 
         XCTAssertNotNil(target.realm)
         XCTAssertEqual(1, target.backlinks!.count)
-        XCTAssertEqual(1234, (target.backlinks!.firstObject() as! SwiftLinkSourceObject).id)
+        XCTAssertEqual(1234, (target.backlinks!.firstObject() as! SwiftRLMLinkSourceObject).id)
     }
 
 //    FIXME - disabled until we fix commit log issue which break transacions when leaking realm objects
 //    func testCircularLinks() {
 //        let realm = realmWithTestPath()
 //
-//        let obj = SwiftCircleObject()
+//        let obj = SwiftRLMCircleObject()
 //        obj.data = "a"
 //        obj.next = obj
 //
@@ -132,7 +133,7 @@ class SwiftLinkTests: RLMTestCase {
 //        obj.next.data = "b"
 //        try! realm.commitWriteTransaction()
 //
-//        let obj2 = SwiftCircleObject.allObjectsInRealm(realm).firstObject() as SwiftCircleObject
+//        let obj2 = SwiftRLMCircleObject.allObjectsInRealm(realm).firstObject() as SwiftRLMCircleObject
 //        XCTAssertEqual(obj2.data, "b", "data should be 'b'")
 //        XCTAssertEqual(obj2.data, obj2.next.data, "objects should be equal")
 //    }

+ 50 - 41
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftObjectInterfaceTests.swift

@@ -19,6 +19,7 @@
 import XCTest
 import Realm
 import Foundation
+import RealmTestSupport
 
 class OuterClass {
     class InnerClass {
@@ -26,16 +27,16 @@ class OuterClass {
     }
 }
 
-class SwiftStringObjectSubclass : SwiftStringObject {
+class SwiftRLMStringObjectSubclass: SwiftRLMStringObject {
     @objc dynamic var stringCol2 = ""
 }
 
-class SwiftSelfRefrencingSubclass: SwiftStringObject {
-    @objc dynamic var objects = RLMArray<SwiftSelfRefrencingSubclass>(objectClassName: SwiftSelfRefrencingSubclass.className())
+class SwiftRLMSelfRefrencingSubclass: SwiftRLMStringObject {
+    @objc dynamic var objects = RLMArray<SwiftRLMSelfRefrencingSubclass>(objectClassName: SwiftRLMSelfRefrencingSubclass.className())
 }
 
 
-class SwiftDefaultObject: RLMObject {
+class SwiftRLMDefaultObject: RLMObject {
     @objc dynamic var intCol = 1
     @objc dynamic var boolCol = true
 
@@ -44,22 +45,22 @@ class SwiftDefaultObject: RLMObject {
     }
 }
 
-class SwiftOptionalNumberObject: RLMObject {
+class SwiftRLMOptionalNumberObject: RLMObject {
     @objc dynamic var intCol: NSNumber? = 1
     @objc dynamic var floatCol: NSNumber? = 2.2 as Float as NSNumber
     @objc dynamic var doubleCol: NSNumber? = 3.3
     @objc dynamic var boolCol: NSNumber? = true
 }
 
-class SwiftObjectInterfaceTests: RLMTestCase {
+class SwiftRLMObjectInterfaceTests: RLMTestCase {
 
     // Swift models
 
-    func testSwiftObject() {
+    func testSwiftRLMObject() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
 
-        let obj = SwiftObject()
+        let obj = SwiftRLMObject()
         realm.add(obj)
 
         obj.boolCol = true
@@ -69,14 +70,14 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         obj.stringCol = "abcd"
         obj.binaryCol = "abcd".data(using: String.Encoding.utf8)
         obj.dateCol = Date(timeIntervalSince1970: 123)
-        obj.objectCol = SwiftBoolObject()
+        obj.objectCol = SwiftRLMBoolObject()
         obj.objectCol.boolCol = true
         obj.arrayCol.add(obj.objectCol)
         try! realm.commitWriteTransaction()
 
         let data = "abcd".data(using: String.Encoding.utf8)
 
-        let firstObj = SwiftObject.allObjects(in: realm).firstObject() as! SwiftObject
+        let firstObj = SwiftRLMObject.allObjects(in: realm).firstObject() as! SwiftRLMObject
         XCTAssertEqual(firstObj.boolCol, true, "should be true")
         XCTAssertEqual(firstObj.intCol, 1234, "should be 1234")
         XCTAssertEqual(firstObj.floatCol, Float(1.1), "should be 1.1")
@@ -89,15 +90,15 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         XCTAssertEqual(obj.arrayCol.firstObject()!.boolCol, true, "should be true")
     }
 
-    func testDefaultValueSwiftObject() {
+    func testDefaultValueSwiftRLMObject() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
-        realm.add(SwiftObject())
+        realm.add(SwiftRLMObject())
         try! realm.commitWriteTransaction()
 
         let data = "a".data(using: String.Encoding.utf8)
 
-        let firstObj = SwiftObject.allObjects(in: realm).firstObject() as! SwiftObject
+        let firstObj = SwiftRLMObject.allObjects(in: realm).firstObject() as! SwiftRLMObject
         XCTAssertEqual(firstObj.boolCol, false, "should be false")
         XCTAssertEqual(firstObj.intCol, 123, "should be 123")
         XCTAssertEqual(firstObj.floatCol, Float(1.23), "should be 1.23")
@@ -109,44 +110,44 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         XCTAssertEqual(firstObj.arrayCol.count, UInt(0), "array count should be zero")
     }
 
-    func testMergedDefaultValuesSwiftObject() {
+    func testMergedDefaultValuesSwiftRLMObject() {
         let realm = self.realmWithTestPath()
         realm.beginWriteTransaction()
-        _ = SwiftDefaultObject.create(in: realm, withValue: NSDictionary())
+        _ = SwiftRLMDefaultObject.create(in: realm, withValue: NSDictionary())
         try! realm.commitWriteTransaction()
 
-        let object = SwiftDefaultObject.allObjects(in: realm).firstObject() as! SwiftDefaultObject
+        let object = SwiftRLMDefaultObject.allObjects(in: realm).firstObject() as! SwiftRLMDefaultObject
         XCTAssertEqual(object.intCol, 2, "defaultPropertyValues should override native property default value")
         XCTAssertEqual(object.boolCol, true, "native property default value should be used if defaultPropertyValues doesn't contain that key")
     }
 
     func testSubclass() {
         // test className methods
-        XCTAssertEqual("SwiftStringObject", SwiftStringObject.className())
-        XCTAssertEqual("SwiftStringObjectSubclass", SwiftStringObjectSubclass.className())
+        XCTAssertEqual("SwiftRLMStringObject", SwiftRLMStringObject.className())
+        XCTAssertEqual("SwiftRLMStringObjectSubclass", SwiftRLMStringObjectSubclass.className())
 
         let realm = RLMRealm.default()
         realm.beginWriteTransaction()
-        _ = SwiftStringObject.createInDefaultRealm(withValue: ["string"])
+        _ = SwiftRLMStringObject.createInDefaultRealm(withValue: ["string"])
 
-        _ = SwiftStringObjectSubclass.createInDefaultRealm(withValue: ["string", "string2"])
+        _ = SwiftRLMStringObjectSubclass.createInDefaultRealm(withValue: ["string", "string2"])
         try! realm.commitWriteTransaction()
 
         // ensure creation in proper table
-        XCTAssertEqual(UInt(1), SwiftStringObjectSubclass.allObjects().count)
-        XCTAssertEqual(UInt(1), SwiftStringObject.allObjects().count)
+        XCTAssertEqual(UInt(1), SwiftRLMStringObjectSubclass.allObjects().count)
+        XCTAssertEqual(UInt(1), SwiftRLMStringObject.allObjects().count)
 
         try! realm.transaction {
             // create self referencing subclass
-            let sub = SwiftSelfRefrencingSubclass.createInDefaultRealm(withValue: ["string", []])
-            let sub2 = SwiftSelfRefrencingSubclass()
+            let sub = SwiftRLMSelfRefrencingSubclass.createInDefaultRealm(withValue: ["string", []])
+            let sub2 = SwiftRLMSelfRefrencingSubclass()
             sub.objects.add(sub2)
         }
     }
 
     func testOptionalNSNumberProperties() {
         let realm = realmWithTestPath()
-        let no = SwiftOptionalNumberObject()
+        let no = SwiftRLMOptionalNumberObject()
         XCTAssertEqual([.int, .float, .double, .bool], no.objectSchema.properties.map { $0.type })
 
         XCTAssertEqual(1, no.intCol!)
@@ -180,11 +181,11 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         XCTAssertEqual(false, no.boolCol!)
     }
 
-    func testOptionalSwiftProperties() {
+    func testOptionalSwiftRLMProperties() {
         let realm = realmWithTestPath()
-        try! realm.transaction { realm.add(SwiftOptionalObject()) }
+        try! realm.transaction { realm.add(SwiftRLMOptionalObject()) }
 
-        let firstObj = SwiftOptionalObject.allObjects(in: realm).firstObject() as! SwiftOptionalObject
+        let firstObj = SwiftRLMOptionalObject.allObjects(in: realm).firstObject() as! SwiftRLMOptionalObject
         XCTAssertNil(firstObj.optObjectCol)
         XCTAssertNil(firstObj.optStringCol)
         XCTAssertNil(firstObj.optNSStringCol)
@@ -192,7 +193,7 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         XCTAssertNil(firstObj.optDateCol)
 
         try! realm.transaction {
-            firstObj.optObjectCol = SwiftBoolObject()
+            firstObj.optObjectCol = SwiftRLMBoolObject()
             firstObj.optObjectCol!.boolCol = true
 
             firstObj.optStringCol = "Hi!"
@@ -220,13 +221,13 @@ class SwiftObjectInterfaceTests: RLMTestCase {
         XCTAssertNil(firstObj.optDateCol)
     }
 
-    func testSwiftClassNameIsDemangled() {
-        XCTAssertEqual(SwiftObject.className(), "SwiftObject",
+    func testSwiftRLMClassNameIsDemangled() {
+        XCTAssertEqual(SwiftRLMObject.className(), "SwiftRLMObject",
                        "Calling className() on Swift class should return demangled name")
     }
 
     func testPrimitiveArray() {
-        let obj = SwiftPrimitiveArrayObject()
+        let obj = SwiftRLMPrimitiveArrayObject()
         let str = "str" as NSString
         let data = "str".data(using: .utf8)! as Data as NSData
         let date = NSDate()
@@ -298,17 +299,17 @@ class SwiftObjectInterfaceTests: RLMTestCase {
     func testCreateOrUpdate() {
         let realm = RLMRealm.default()
         realm.beginWriteTransaction()
-        _ = SwiftPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 1])
-        let objects = SwiftPrimaryStringObject.allObjects();
-        XCTAssertEqual(objects.count, UInt(1), "Should have 1 object");
-        XCTAssertEqual((objects[0] as! SwiftPrimaryStringObject).intCol, 1, "Value should be 1");
+        _ = SwiftRLMPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 1])
+        let objects = SwiftRLMPrimaryStringObject.allObjects()
+        XCTAssertEqual(objects.count, UInt(1), "Should have 1 object")
+        XCTAssertEqual((objects[0] as! SwiftRLMPrimaryStringObject).intCol, 1, "Value should be 1")
 
-        _ = SwiftPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["stringCol": "string2", "intCol": 2])
+        _ = SwiftRLMPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["stringCol": "string2", "intCol": 2])
         XCTAssertEqual(objects.count, UInt(2), "Should have 2 objects")
 
-        _ = SwiftPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 3])
+        _ = SwiftRLMPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 3])
         XCTAssertEqual(objects.count, UInt(2), "Should have 2 objects")
-        XCTAssertEqual((objects[0] as! SwiftPrimaryStringObject).intCol, 3, "Value should be 3");
+        XCTAssertEqual((objects[0] as! SwiftRLMPrimaryStringObject).intCol, 3, "Value should be 3")
 
         try! realm.commitWriteTransaction()
     }
@@ -316,9 +317,9 @@ class SwiftObjectInterfaceTests: RLMTestCase {
     func testObjectForPrimaryKey() {
         let realm = RLMRealm.default()
         realm.beginWriteTransaction()
-        _ = SwiftPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 1])
+        _ = SwiftRLMPrimaryStringObject.createOrUpdateInDefaultRealm(withValue: ["string", 1])
 
-        let obj = SwiftPrimaryStringObject.object(forPrimaryKey: "string")
+        let obj = SwiftRLMPrimaryStringObject.object(forPrimaryKey: "string")
         XCTAssertNotNil(obj!)
         XCTAssertEqual(obj!.intCol, 1)
 
@@ -328,13 +329,21 @@ class SwiftObjectInterfaceTests: RLMTestCase {
     // if this fails (and you haven't changed the test module name), the checks
     // for swift class names and the demangling logic need to be updated
     func testNSStringFromClassDemangledTopLevelClassNames() {
+#if SWIFT_PACKAGE
+        XCTAssertEqual(NSStringFromClass(OuterClass.self), "RealmObjcSwiftTests.OuterClass")
+#else
         XCTAssertEqual(NSStringFromClass(OuterClass.self), "Tests.OuterClass")
+#endif
     }
 
     // if this fails (and you haven't changed the test module name), the prefix
     // check in RLMSchema initialization needs to be updated
     func testNestedClassNameMangling() {
+#if SWIFT_PACKAGE
+        XCTAssertEqual(NSStringFromClass(OuterClass.InnerClass.self), "_TtCC19RealmObjcSwiftTests10OuterClass10InnerClass")
+#else
         XCTAssertEqual(NSStringFromClass(OuterClass.InnerClass.self), "_TtCC5Tests10OuterClass10InnerClass")
+#endif
     }
 
 }

+ 17 - 16
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftPropertyTypeTest.swift

@@ -18,8 +18,9 @@
 
 import XCTest
 import Realm
+import RealmTestSupport
 
-class SwiftPropertyTypeTest: RLMTestCase {
+class SwiftRLMPropertyTypeTest: RLMTestCase {
 
     func testLongType() {
         let longNumber: Int64 = 17179869184
@@ -30,22 +31,22 @@ class SwiftPropertyTypeTest: RLMTestCase {
         let realm = realmWithTestPath()
 
         realm.beginWriteTransaction()
-        _ = SwiftLongObject.create(in: realm, withValue: [NSNumber(value: longNumber)])
-        _ = SwiftLongObject.create(in: realm, withValue: [NSNumber(value: intNumber)])
-        _ = SwiftLongObject.create(in: realm, withValue: [NSNumber(value: negativeLongNumber)])
+        _ = SwiftRLMLongObject.create(in: realm, withValue: [NSNumber(value: longNumber)])
+        _ = SwiftRLMLongObject.create(in: realm, withValue: [NSNumber(value: intNumber)])
+        _ = SwiftRLMLongObject.create(in: realm, withValue: [NSNumber(value: negativeLongNumber)])
         try! realm.commitWriteTransaction()
 
-        let objects = SwiftLongObject.allObjects(in: realm)
+        let objects = SwiftRLMLongObject.allObjects(in: realm)
         XCTAssertEqual(objects.count, UInt(3), "3 rows expected")
-        XCTAssertEqual((objects[0] as! SwiftLongObject).longCol, longNumber, "2 ^ 34 expected")
-        XCTAssertEqual((objects[1] as! SwiftLongObject).longCol, intNumber, "2 ^ 31 - 1 expected")
-        XCTAssertEqual((objects[2] as! SwiftLongObject).longCol, negativeLongNumber, "-2 ^ 34 expected")
+        XCTAssertEqual((objects[0] as! SwiftRLMLongObject).longCol, longNumber, "2 ^ 34 expected")
+        XCTAssertEqual((objects[1] as! SwiftRLMLongObject).longCol, intNumber, "2 ^ 31 - 1 expected")
+        XCTAssertEqual((objects[2] as! SwiftRLMLongObject).longCol, negativeLongNumber, "-2 ^ 34 expected")
 
         realm.beginWriteTransaction()
-        (objects[0] as! SwiftLongObject).longCol = updatedLongNumber
+        (objects[0] as! SwiftRLMLongObject).longCol = updatedLongNumber
         try! realm.commitWriteTransaction()
 
-        XCTAssertEqual((objects[0] as! SwiftLongObject).longCol, updatedLongNumber, "After update: 2 ^ 33 expected")
+        XCTAssertEqual((objects[0] as! SwiftRLMLongObject).longCol, updatedLongNumber, "After update: 2 ^ 33 expected")
     }
 
     func testIntSizes() {
@@ -57,7 +58,7 @@ class SwiftPropertyTypeTest: RLMTestCase {
         // 1 << 40 doesn't auto-promote to Int64 on 32-bit platforms
         let v64 = Int64(1) << 40
         try! realm.transaction {
-            let obj = SwiftAllIntSizesObject()
+            let obj = SwiftRLMAllIntSizesObject()
 
             obj.int8  = v8
             XCTAssertEqual(obj.int8, v8)
@@ -71,7 +72,7 @@ class SwiftPropertyTypeTest: RLMTestCase {
             realm.add(obj)
         }
 
-        let obj = SwiftAllIntSizesObject.allObjects(in: realm)[0] as! SwiftAllIntSizesObject
+        let obj = SwiftRLMAllIntSizesObject.allObjects(in: realm)[0] as! SwiftRLMAllIntSizesObject
         XCTAssertEqual(obj.int8, v8)
         XCTAssertEqual(obj.int16, v16)
         XCTAssertEqual(obj.int32, v32)
@@ -107,7 +108,7 @@ class SwiftPropertyTypeTest: RLMTestCase {
     func testLazyVarProperties() {
         let realm = realmWithTestPath()
         let succeeded : Void? = try? realm.transaction {
-            realm.add(SwiftLazyVarObject())
+            realm.add(SwiftRLMLazyVarObject())
         }
         XCTAssertNotNil(succeeded, "Writing an NSObject-based object with an lazy property should work.")
     }
@@ -115,18 +116,18 @@ class SwiftPropertyTypeTest: RLMTestCase {
     func testIgnoredLazyVarProperties() {
         let realm = realmWithTestPath()
         let succeeded : Void? = try? realm.transaction {
-            realm.add(SwiftIgnoredLazyVarObject())
+            realm.add(SwiftRLMIgnoredLazyVarObject())
         }
         XCTAssertNotNil(succeeded, "Writing an object with an ignored lazy property should work.")
     }
 
     func testObjectiveCTypeProperties() {
         let realm = realmWithTestPath()
-        var object: SwiftObjectiveCTypesObject!
+        var object: SwiftRLMObjectiveCTypesObject!
         let now = NSDate()
         let data = "fizzbuzz".data(using: .utf8)! as Data as NSData
         try! realm.transaction {
-            object = SwiftObjectiveCTypesObject()
+            object = SwiftRLMObjectiveCTypesObject()
             realm.add(object)
             object.stringCol = "Hello world!"
             object.dateCol = now

+ 29 - 28
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftRealmTests.swift

@@ -18,8 +18,9 @@
 
 import XCTest
 import Realm
+import RealmTestSupport
 
-class SwiftRealmTests: RLMTestCase {
+class SwiftRLMRealmTests: RLMTestCase {
 
     // No models
 
@@ -40,26 +41,26 @@ class SwiftRealmTests: RLMTestCase {
     func testRealmAddAndRemoveObjects() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
-        _ = SwiftStringObject.create(in: realm, withValue: ["a"])
-        _ = SwiftStringObject.create(in: realm, withValue: ["b"])
-        _ = SwiftStringObject.create(in: realm, withValue: ["c"])
-        XCTAssertEqual(SwiftStringObject.allObjects(in: realm).count, UInt(3), "Expecting 3 objects")
+        _ = SwiftRLMStringObject.create(in: realm, withValue: ["a"])
+        _ = SwiftRLMStringObject.create(in: realm, withValue: ["b"])
+        _ = SwiftRLMStringObject.create(in: realm, withValue: ["c"])
+        XCTAssertEqual(SwiftRLMStringObject.allObjects(in: realm).count, UInt(3), "Expecting 3 objects")
         try! realm.commitWriteTransaction()
 
         // test again after write transaction
-        var objects = SwiftStringObject.allObjects(in: realm)
+        var objects = SwiftRLMStringObject.allObjects(in: realm)
         XCTAssertEqual(objects.count, UInt(3), "Expecting 3 objects")
-        XCTAssertEqual((objects[0] as! SwiftStringObject).stringCol, "a", "Expecting column to be 'a'")
+        XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "a", "Expecting column to be 'a'")
 
         realm.beginWriteTransaction()
-        realm.delete(objects[2] as! SwiftStringObject)
-        realm.delete(objects[0] as! SwiftStringObject)
-        XCTAssertEqual(SwiftStringObject.allObjects(in: realm).count, UInt(1), "Expecting 1 object")
+        realm.delete(objects[2] as! SwiftRLMStringObject)
+        realm.delete(objects[0] as! SwiftRLMStringObject)
+        XCTAssertEqual(SwiftRLMStringObject.allObjects(in: realm).count, UInt(1), "Expecting 1 object")
         try! realm.commitWriteTransaction()
 
-        objects = SwiftStringObject.allObjects(in: realm)
+        objects = SwiftRLMStringObject.allObjects(in: realm)
         XCTAssertEqual(objects.count, UInt(1), "Expecting 1 object")
-        XCTAssertEqual((objects[0] as! SwiftStringObject).stringCol, "b", "Expecting column to be 'b'")
+        XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "b", "Expecting column to be 'b'")
     }
 
     func testRealmIsUpdatedAfterBackgroundUpdate() {
@@ -75,22 +76,22 @@ class SwiftRealmTests: RLMTestCase {
         dispatchAsync {
             let realm = self.realmWithTestPath()
             realm.beginWriteTransaction()
-            _ = SwiftStringObject.create(in: realm, withValue: ["string"])
+            _ = SwiftRLMStringObject.create(in: realm, withValue: ["string"])
             try! realm.commitWriteTransaction()
         }
         waitForExpectations(timeout: 2.0, handler: nil)
         token.invalidate()
 
         // get object
-        let objects = SwiftStringObject.allObjects(in: realm)
+        let objects = SwiftRLMStringObject.allObjects(in: realm)
         XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
-        XCTAssertEqual((objects[0] as! SwiftStringObject).stringCol, "string", "Value of first column should be 'string'")
+        XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
     }
 
     func testRealmIgnoresProperties() {
         let realm = realmWithTestPath()
 
-        let object = SwiftIgnoredPropertiesObject()
+        let object = SwiftRLMIgnoredPropertiesObject()
         realm.beginWriteTransaction()
         object.name = "@fz"
         object.age = 31
@@ -102,9 +103,9 @@ class SwiftRealmTests: RLMTestCase {
         object.runtimeProperty = NSObject()
         try! realm.commitWriteTransaction()
 
-        let objects = SwiftIgnoredPropertiesObject.allObjects(in: realm)
-        XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type SwiftIgnoredPropertiesObject")
-        let retrievedObject = objects[0] as! SwiftIgnoredPropertiesObject
+        let objects = SwiftRLMIgnoredPropertiesObject.allObjects(in: realm)
+        XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type SwiftRLMIgnoredPropertiesObject")
+        let retrievedObject = objects[0] as! SwiftRLMIgnoredPropertiesObject
         XCTAssertNil(retrievedObject.runtimeProperty, "Ignored property should be nil")
         XCTAssertEqual(retrievedObject.name, "@fz", "Value of the name column doesn't match the assigned one.")
         XCTAssertEqual(retrievedObject.objectSchema.properties.count, 2, "Only 'name' and 'age' properties should be detected by Realm")
@@ -112,8 +113,8 @@ class SwiftRealmTests: RLMTestCase {
 
     func testUpdatingSortedArrayAfterBackgroundUpdate() {
         let realm = realmWithTestPath()
-        let objs = SwiftIntObject.allObjects(in: realm)
-        let objects = SwiftIntObject.allObjects(in: realm).sortedResults(usingKeyPath: "intCol", ascending: true)
+        let objs = SwiftRLMIntObject.allObjects(in: realm)
+        let objects = SwiftRLMIntObject.allObjects(in: realm).sortedResults(usingKeyPath: "intCol", ascending: true)
         let updateComplete = expectation(description: "background update complete")
 
         let token = realm.addNotificationBlock() { (_, _) in
@@ -126,11 +127,11 @@ class SwiftRealmTests: RLMTestCase {
         dispatchAsync {
             let realm = self.realmWithTestPath()
             try! realm.transaction {
-                var obj = SwiftIntObject()
+                var obj = SwiftRLMIntObject()
                 obj.intCol = 2;
                 realm.add(obj)
 
-                obj = SwiftIntObject()
+                obj = SwiftRLMIntObject()
                 obj.intCol = 1;
                 realm.add(obj)
             }
@@ -151,23 +152,23 @@ class SwiftRealmTests: RLMTestCase {
 
         dispatchAsync {
             let realm = self.realmWithTestPath()
-            let obj = SwiftStringObject(value: ["string"])
+            let obj = SwiftRLMStringObject(value: ["string"])
             realm.beginWriteTransaction()
             realm.add(obj)
             try! realm.commitWriteTransaction()
 
-            let objects = SwiftStringObject.allObjects(in: realm)
+            let objects = SwiftRLMStringObject.allObjects(in: realm)
             XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
-            XCTAssertEqual((objects[0] as! SwiftStringObject).stringCol, "string", "Value of first column should be 'string'")
+            XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
         }
 
         waitForExpectations(timeout: 2.0, handler: nil)
         token.invalidate()
 
         // get object
-        let objects = SwiftStringObject.allObjects(in: realm)
+        let objects = SwiftRLMStringObject.allObjects(in: realm)
         XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type RLMTestObject")
-        XCTAssertEqual((objects[0] as! SwiftStringObject).stringCol, "string", "Value of first column should be 'string'")
+        XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
     }
 
     // Objective-C models

+ 33 - 28
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftSchemaTests.swift

@@ -19,41 +19,42 @@
 import XCTest
 import Realm
 import Realm.Private
+import RealmTestSupport
 
 class InitLinkedToClass: RLMObject {
-    @objc dynamic var value = SwiftIntObject(value: [0])
+    @objc dynamic var value: SwiftRLMIntObject! = SwiftRLMIntObject(value: [0])
 }
 
-class SwiftNonDefaultObject: RLMObject {
+class SwiftRLMNonDefaultObject: RLMObject {
     @objc dynamic var value = 0
     public override class func shouldIncludeInDefaultSchema() -> Bool {
         return false
     }
 }
 
-class SwiftLinkedNonDefaultObject: RLMObject {
-    @objc dynamic var obj: SwiftNonDefaultObject?
+class SwiftRLMLinkedNonDefaultObject: RLMObject {
+    @objc dynamic var obj: SwiftRLMNonDefaultObject?
     public override class func shouldIncludeInDefaultSchema() -> Bool {
         return false
     }
 }
 
-class SwiftNonDefaultArrayObject: RLMObject {
-    @objc dynamic var array = RLMArray<SwiftNonDefaultObject>(objectClassName: SwiftNonDefaultObject.className())
+class SwiftRLMNonDefaultArrayObject: RLMObject {
+    @objc dynamic var array = RLMArray<SwiftRLMNonDefaultObject>(objectClassName: SwiftRLMNonDefaultObject.className())
     public override class func shouldIncludeInDefaultSchema() -> Bool {
         return false
     }
 }
 
-class SwiftMutualLink1Object: RLMObject {
-    @objc dynamic var object: SwiftMutualLink2Object?
+class SwiftRLMMutualLink1Object: RLMObject {
+    @objc dynamic var object: SwiftRLMMutualLink2Object?
     public override class func shouldIncludeInDefaultSchema() -> Bool {
         return false
     }
 }
 
-class SwiftMutualLink2Object: RLMObject {
-    @objc dynamic var object: SwiftMutualLink1Object?
+class SwiftRLMMutualLink2Object: RLMObject {
+    @objc dynamic var object: SwiftRLMMutualLink1Object?
     public override class func shouldIncludeInDefaultSchema() -> Bool {
         return false
     }
@@ -61,18 +62,18 @@ class SwiftMutualLink2Object: RLMObject {
 
 class IgnoredLinkPropertyObject : RLMObject {
     @objc dynamic var value = 0
-    var obj = SwiftIntObject()
+    var obj = SwiftRLMIntObject()
 
     override class func ignoredProperties() -> [String] {
         return ["obj"]
     }
 }
 
-class SwiftRecursingSchemaTestObject : RLMObject {
-    @objc dynamic var propertyWithIllegalDefaultValue: SwiftIntObject? = {
+class SwiftRLMRecursingSchemaTestObject : RLMObject {
+    @objc dynamic var propertyWithIllegalDefaultValue: SwiftRLMIntObject? = {
         if mayAccessSchema {
             let realm = RLMRealm.default()
-            return SwiftIntObject.allObjects().firstObject() as! SwiftIntObject?
+            return SwiftRLMIntObject.allObjects().firstObject() as! SwiftRLMIntObject?
         } else {
             return nil
         }
@@ -82,24 +83,28 @@ class SwiftRecursingSchemaTestObject : RLMObject {
 }
 
 class InvalidArrayType: FakeObject {
-    @objc dynamic var array = RLMArray<SwiftIntObject>(objectClassName: "invalid class")
+    @objc dynamic var array = RLMArray<SwiftRLMIntObject>(objectClassName: "invalid class")
 }
 
 class InitAppendsToArrayProperty : RLMObject {
-    @objc dynamic var propertyWithIllegalDefaultValue: RLMArray<SwiftIntObject> = {
+    @objc dynamic var propertyWithIllegalDefaultValue: RLMArray<InitAppendsToArrayValue> = {
         if mayAppend {
-            let array = RLMArray<SwiftIntObject>(objectClassName: SwiftIntObject.className())
-            array.add(SwiftIntObject())
+            let array = RLMArray<InitAppendsToArrayValue>(objectClassName: InitAppendsToArrayValue.className())
+            array.add(InitAppendsToArrayValue())
             return array
         } else {
-            return RLMArray<SwiftIntObject>(objectClassName: SwiftIntObject.className())
+            return RLMArray<InitAppendsToArrayValue>(objectClassName: InitAppendsToArrayValue.className())
         }
     }()
 
     static var mayAppend = false
 }
 
-class SwiftSchemaTests: RLMMultiProcessTestCase {
+class InitAppendsToArrayValue : RLMObject {
+    @objc dynamic var value: Int = 0
+}
+
+class SwiftRLMSchemaTests: RLMMultiProcessTestCase {
     func testWorksAtAll() {
         if isParent {
             XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
@@ -128,9 +133,9 @@ class SwiftSchemaTests: RLMMultiProcessTestCase {
         }
 
         // Object in default schema
-        _ = SwiftIntObject()
+        _ = SwiftRLMIntObject()
         // Object not in default schema
-        _ = SwiftNonDefaultObject()
+        _ = SwiftRLMNonDefaultObject()
     }
 
     func testCreateUnmanagedObjectWithNestedObjectWithUninitializedSchema() {
@@ -146,12 +151,12 @@ class SwiftSchemaTests: RLMMultiProcessTestCase {
         _ = InitLinkedToClass()
         // Again with an object that links to an unintialized type
         // rather than creating one
-        _ = SwiftCompanyObject()
+        _ = SwiftRLMCompanyObject()
 
         // Objects not in default schema
-        _ = SwiftLinkedNonDefaultObject(value: [[1]])
-        _ = SwiftNonDefaultArrayObject(value: [[[1]]])
-        _ = SwiftMutualLink1Object(value: [[[:]]])
+        _ = SwiftRLMLinkedNonDefaultObject(value: [[1]])
+        _ = SwiftRLMNonDefaultArrayObject(value: [[[1]]])
+        _ = SwiftRLMMutualLink1Object(value: [[[:]]])
     }
 
     func testCreateUnmanagedObjectWhichCreatesAnotherClassViaInitWithValueDuringSchemaInit() {
@@ -161,7 +166,7 @@ class SwiftSchemaTests: RLMMultiProcessTestCase {
         }
 
         _ = InitLinkedToClass(value: [[0]])
-        _ = SwiftCompanyObject(value: [[["Jaden", 20, false]]])
+        _ = SwiftRLMCompanyObject(value: [[["Jaden", 20, false]]])
     }
 
     func testInitUnmanagedObjectNotInClassSubsetDuringSchemaInit() {
@@ -186,7 +191,7 @@ class SwiftSchemaTests: RLMMultiProcessTestCase {
             return
         }
 
-        SwiftRecursingSchemaTestObject.mayAccessSchema = true
+        SwiftRLMRecursingSchemaTestObject.mayAccessSchema = true
         assertThrowsWithReasonMatching(RLMSchema.shared(), ".*recursive.*")
     }
 

+ 46 - 39
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftTestObjects.swift

@@ -17,24 +17,25 @@
 ////////////////////////////////////////////////////////////////////////////
 
 import Realm
+import RealmTestSupport
 
-class SwiftStringObject: RLMObject {
+class SwiftRLMStringObject: RLMObject {
     @objc dynamic var stringCol = ""
 }
 
-class SwiftBoolObject: RLMObject {
+class SwiftRLMBoolObject: RLMObject {
     @objc dynamic var boolCol = false
 }
 
-class SwiftIntObject: RLMObject {
+class SwiftRLMIntObject: RLMObject {
     @objc dynamic var intCol = 0
 }
 
-class SwiftLongObject: RLMObject {
+class SwiftRLMLongObject: RLMObject {
     @objc dynamic var longCol: Int64 = 0
 }
 
-class SwiftObject: RLMObject {
+class SwiftRLMObject: RLMObject {
     @objc dynamic var boolCol = false
     @objc dynamic var intCol = 123
     @objc dynamic var floatCol = 1.23 as Float
@@ -42,19 +43,25 @@ class SwiftObject: RLMObject {
     @objc dynamic var stringCol = "a"
     @objc dynamic var binaryCol = "a".data(using: String.Encoding.utf8)
     @objc dynamic var dateCol = Date(timeIntervalSince1970: 1)
-    @objc dynamic var objectCol = SwiftBoolObject()
-    @objc dynamic var arrayCol = RLMArray<SwiftBoolObject>(objectClassName: SwiftBoolObject.className())
+    #if SWIFT_PACKAGE
+    // FIXME: we fail to check if an object property is actually optional unless
+    // RealmSwift happens to be loaded in the process
+    @objc dynamic var objectCol: SwiftRLMBoolObject! = SwiftRLMBoolObject()
+    #else
+    @objc dynamic var objectCol = SwiftRLMBoolObject()
+    #endif
+    @objc dynamic var arrayCol = RLMArray<SwiftRLMBoolObject>(objectClassName: SwiftRLMBoolObject.className())
 }
 
-class SwiftOptionalObject: RLMObject {
+class SwiftRLMOptionalObject: RLMObject {
     @objc dynamic var optStringCol: String?
     @objc dynamic var optNSStringCol: NSString?
     @objc dynamic var optBinaryCol: Data?
     @objc dynamic var optDateCol: Date?
-    @objc dynamic var optObjectCol: SwiftBoolObject?
+    @objc dynamic var optObjectCol: SwiftRLMBoolObject?
 }
 
-class SwiftPrimitiveArrayObject: RLMObject {
+class SwiftRLMPrimitiveArrayObject: RLMObject {
     @objc dynamic var stringCol = RLMArray<NSString>(objectType: .string, optional: false)
     @objc dynamic var optStringCol = RLMArray<NSObject>(objectType: .string, optional: true)
     @objc dynamic var dataCol = RLMArray<NSData>(objectType: .data, optional: false)
@@ -63,16 +70,16 @@ class SwiftPrimitiveArrayObject: RLMObject {
     @objc dynamic var optDateCol = RLMArray<NSObject>(objectType: .date, optional: true)
 }
 
-class SwiftDogObject: RLMObject {
+class SwiftRLMDogObject: RLMObject {
     @objc dynamic var dogName = ""
 }
 
-class SwiftOwnerObject: RLMObject {
+class SwiftRLMOwnerObject: RLMObject {
     @objc dynamic var name = ""
-    @objc dynamic var dog: SwiftDogObject? = SwiftDogObject()
+    @objc dynamic var dog: SwiftRLMDogObject? = SwiftRLMDogObject()
 }
 
-class SwiftAggregateObject: RLMObject {
+class SwiftRLMAggregateObject: RLMObject {
     @objc dynamic var intCol = 0
     @objc dynamic var floatCol = 0 as Float
     @objc dynamic var doubleCol = 0.0
@@ -80,39 +87,39 @@ class SwiftAggregateObject: RLMObject {
     @objc dynamic var dateCol = Date()
 }
 
-class SwiftAllIntSizesObject: RLMObject {
-    @objc dynamic var int8  : Int8  = 0
-    @objc dynamic var int16 : Int16 = 0
-    @objc dynamic var int32 : Int32 = 0
-    @objc dynamic var int64 : Int64 = 0
+class SwiftRLMAllIntSizesObject: RLMObject {
+    @objc dynamic var int8: Int8  = 0
+    @objc dynamic var int16: Int16 = 0
+    @objc dynamic var int32: Int32 = 0
+    @objc dynamic var int64: Int64 = 0
 }
 
-class SwiftEmployeeObject: RLMObject {
+class SwiftRLMEmployeeObject: RLMObject {
     @objc dynamic var name = ""
     @objc dynamic var age = 0
     @objc dynamic var hired = false
 }
 
-class SwiftCompanyObject: RLMObject {
-    @objc dynamic var employees = RLMArray<SwiftEmployeeObject>(objectClassName: SwiftEmployeeObject.className())
+class SwiftRLMCompanyObject: RLMObject {
+    @objc dynamic var employees = RLMArray<SwiftRLMEmployeeObject>(objectClassName: SwiftRLMEmployeeObject.className())
 }
 
-class SwiftArrayPropertyObject: RLMObject {
+class SwiftRLMArrayPropertyObject: RLMObject {
     @objc dynamic var name = ""
-    @objc dynamic var array = RLMArray<SwiftStringObject>(objectClassName: SwiftStringObject.className())
-    @objc dynamic var intArray = RLMArray<SwiftIntObject>(objectClassName: SwiftIntObject.className())
+    @objc dynamic var array = RLMArray<SwiftRLMStringObject>(objectClassName: SwiftRLMStringObject.className())
+    @objc dynamic var intArray = RLMArray<SwiftRLMIntObject>(objectClassName: SwiftRLMIntObject.className())
 }
 
-class SwiftDynamicObject: RLMObject {
+class SwiftRLMDynamicObject: RLMObject {
     @objc dynamic var stringCol = "a"
     @objc dynamic var intCol = 0
 }
 
-class SwiftUTF8Object: RLMObject {
+class SwiftRLMUTF8Object: RLMObject {
     @objc dynamic var 柱колоéнǢкƱаم👍 = "值значен™👍☞⎠‱௹♣︎☐▼❒∑⨌⧭иеمرحبا"
 }
 
-class SwiftIgnoredPropertiesObject: RLMObject {
+class SwiftRLMIgnoredPropertiesObject: RLMObject {
     @objc dynamic var name = ""
     @objc dynamic var age = 0
     @objc dynamic var runtimeProperty: AnyObject?
@@ -123,7 +130,7 @@ class SwiftIgnoredPropertiesObject: RLMObject {
     }
 }
 
-class SwiftPrimaryStringObject: RLMObject {
+class SwiftRLMPrimaryStringObject: RLMObject {
     @objc dynamic var stringCol = ""
     @objc dynamic var intCol = 0
 
@@ -132,31 +139,31 @@ class SwiftPrimaryStringObject: RLMObject {
     }
 }
 
-class SwiftLinkSourceObject: RLMObject {
+class SwiftRLMLinkSourceObject: RLMObject {
     @objc dynamic var id = 0
-    @objc dynamic var link: SwiftLinkTargetObject?
+    @objc dynamic var link: SwiftRLMLinkTargetObject?
 }
 
-class SwiftLinkTargetObject: RLMObject {
+class SwiftRLMLinkTargetObject: RLMObject {
     @objc dynamic var id = 0
-    @objc dynamic var backlinks: RLMLinkingObjects<SwiftLinkSourceObject>?
+    @objc dynamic var backlinks: RLMLinkingObjects<SwiftRLMLinkSourceObject>?
 
     override class func linkingObjectsProperties() -> [String : RLMPropertyDescriptor] {
-        return ["backlinks": RLMPropertyDescriptor(with: SwiftLinkSourceObject.self, propertyName: "link")]
+        return ["backlinks": RLMPropertyDescriptor(with: SwiftRLMLinkSourceObject.self, propertyName: "link")]
     }
 }
 
-class SwiftLazyVarObject : RLMObject {
-    @objc dynamic lazy var lazyProperty : String = "hello world"
+class SwiftRLMLazyVarObject: RLMObject {
+    @objc dynamic lazy var lazyProperty: String = "hello world"
 }
 
-class SwiftIgnoredLazyVarObject : RLMObject {
+class SwiftRLMIgnoredLazyVarObject: RLMObject {
     @objc dynamic var id = 0
-    @objc dynamic lazy var ignoredVar : String = "hello world"
+    @objc dynamic lazy var ignoredVar: String = "hello world"
     override class func ignoredProperties() -> [String] { return ["ignoredVar"] }
 }
 
-class SwiftObjectiveCTypesObject: RLMObject {
+class SwiftRLMObjectiveCTypesObject: RLMObject {
     @objc dynamic var stringCol: NSString?
     @objc dynamic var dateCol: NSDate?
     @objc dynamic var dataCol: NSData?

+ 8 - 7
Carthage/Checkouts/realm-cocoa/Realm/Tests/Swift/SwiftUnicodeTests.swift

@@ -18,37 +18,38 @@
 
 import XCTest
 import Realm
+import RealmTestSupport
 
 let utf8TestString = "值значен™👍☞⎠‱௹♣︎☐▼❒∑⨌⧭иеمرحبا"
 
-class SwiftUnicodeTests: RLMTestCase {
+class SwiftRLMUnicodeTests: RLMTestCase {
 
     // Swift models
 
     func testUTF8StringContents() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
-        _ = SwiftStringObject.create(in: realm, withValue: [utf8TestString])
+        _ = SwiftRLMStringObject.create(in: realm, withValue: [utf8TestString])
         try! realm.commitWriteTransaction()
 
-        let obj1 = SwiftStringObject.allObjects(in: realm).firstObject() as! SwiftStringObject
+        let obj1 = SwiftRLMStringObject.allObjects(in: realm).firstObject() as! SwiftRLMStringObject
         XCTAssertEqual(obj1.stringCol, utf8TestString, "Storing and retrieving a string with UTF8 content should work")
 
-        let obj2 = SwiftStringObject.objects(in: realm, where: "stringCol == %@", utf8TestString).firstObject() as! SwiftStringObject
+        let obj2 = SwiftRLMStringObject.objects(in: realm, where: "stringCol == %@", utf8TestString).firstObject() as! SwiftRLMStringObject
         XCTAssertTrue(obj1.isEqual(to: obj2), "Querying a realm searching for a string with UTF8 content should work")
     }
 
     func testUTF8PropertyWithUTF8StringContents() {
         let realm = realmWithTestPath()
         realm.beginWriteTransaction()
-        _ = SwiftUTF8Object.create(in: realm, withValue: [utf8TestString])
+        _ = SwiftRLMUTF8Object.create(in: realm, withValue: [utf8TestString])
         try! realm.commitWriteTransaction()
 
-        let obj1 = SwiftUTF8Object.allObjects(in: realm).firstObject() as! SwiftUTF8Object
+        let obj1 = SwiftRLMUTF8Object.allObjects(in: realm).firstObject() as! SwiftRLMUTF8Object
         XCTAssertEqual(obj1.柱колоéнǢкƱаم👍, utf8TestString, "Storing and retrieving a string with UTF8 content should work")
 
         // Test fails because of rdar://17735684
-//        let obj2 = SwiftUTF8Object.objectsInRealm(realm, "柱колоéнǢкƱаم👍 == %@", utf8TestString).firstObject() as SwiftUTF8Object
+//        let obj2 = SwiftRLMUTF8Object.objectsInRealm(realm, "柱колоéнǢкƱаم👍 == %@", utf8TestString).firstObject() as SwiftRLMUTF8Object
 //        XCTAssertEqual(obj1, obj2, "Querying a realm searching for a string with UTF8 content should work")
     }
 

+ 0 - 27
Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.h

@@ -1,27 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2015 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 <Foundation/Foundation.h>
-#import <XCTest/XCTestCase.h>
-
-FOUNDATION_EXTERN void RLMAssertThrowsWithReasonMatchingSwift(XCTestCase *self,
-                                                              __attribute__((noescape)) dispatch_block_t block,
-                                                              NSString *regexString,
-                                                              NSString *message,
-                                                              NSString *fileName,
-                                                              NSUInteger lineNumber);

+ 0 - 48
Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.mm

@@ -1,48 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2015 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 "TestUtils.h"
-
-#import <Realm/Realm.h>
-#import <Realm/RLMSchema_Private.h>
-#import "RLMRealmUtil.hpp"
-
-void RLMAssertThrowsWithReasonMatchingSwift(XCTestCase *self,
-                                            __attribute__((noescape)) dispatch_block_t block,
-                                            NSString *regexString, NSString *message,
-                                            NSString *fileName, NSUInteger lineNumber) {
-    BOOL didThrow = NO;
-    @try {
-        block();
-    }
-    @catch (NSException *e) {
-        didThrow = YES;
-        NSString *reason = e.reason;
-        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:(NSRegularExpressionOptions)0 error:nil];
-        if ([regex numberOfMatchesInString:reason options:(NSMatchingOptions)0 range:NSMakeRange(0, reason.length)] == 0) {
-            NSString *msg = [NSString stringWithFormat:@"The given expression threw an exception with reason '%@', but expected to match '%@'",
-                             reason, regexString];
-            [self recordFailureWithDescription:msg inFile:fileName atLine:lineNumber expected:NO];
-        }
-    }
-    if (!didThrow) {
-        NSString *prefix = @"The given expression failed to throw an exception";
-        message = message ? [NSString stringWithFormat:@"%@ (%@)",  prefix, message] : prefix;
-        [self recordFailureWithDescription:message inFile:fileName atLine:lineNumber expected:NO];
-    }
-}

+ 3 - 0
Carthage/Checkouts/realm-cocoa/Realm/Tests/UtilTests.mm

@@ -20,7 +20,10 @@
 
 #import "RLMConstants.h"
 #import "RLMUtil.hpp"
+
+#ifndef REALM_COCOA_VERSION
 #import "RLMVersion.h"
+#endif
 
 #import "shared_realm.hpp"
 

+ 1 - 0
Carthage/Checkouts/realm-cocoa/RealmSwift.podspec

@@ -19,6 +19,7 @@ Pod::Spec.new do |s|
 
   s.dependency 'Realm', "= #{s.version}"
   s.source_files = 'RealmSwift/*.swift'
+  s.exclude_files = 'RealmSwift/Nonsync.swift'
 
   s.prepare_command           = 'sh build.sh cocoapods-setup swift'
   s.preserve_paths            = %w(build.sh)

+ 21 - 11
Carthage/Checkouts/realm-cocoa/RealmSwift/List.swift

@@ -705,19 +705,29 @@ extension List: RangeReplaceableCollection {
         _rlmArray.removeLastObject()
     }
 
-#if swift(>=3.2)
-    // The issue described below is fixed in Swift 3.2 and above.
-#else
-    // These should not be necessary, but Swift 3.1's compiler fails to infer the `SubSequence`,
-    // and the standard library neglects to provide the default implementation of `subscript`
-    /// :nodoc:
-    public typealias SubSequence = RangeReplaceableRandomAccessSlice<List>
+}
+#endif
 
-    /// :nodoc:
-    public subscript(slice: Range<Int>) -> SubSequence {
-        return SubSequence(base: self, bounds: slice)
+// MARK: - Codable
+
+#if swift(>=4.1)
+extension List: Decodable where Element: Decodable {
+    public convenience init(from decoder: Decoder) throws {
+        self.init()
+        var container = try decoder.unkeyedContainer()
+        while !container.isAtEnd {
+            append(try container.decode(Element.self))
+        }
+    }
+}
+
+extension List: Encodable where Element: Encodable {
+    public func encode(to encoder: Encoder) throws {
+        var container = encoder.unkeyedContainer()
+        for value in self {
+            try container.encode(value)
+        }
     }
-#endif
 }
 #endif
 

+ 24 - 0
Carthage/Checkouts/realm-cocoa/RealmSwift/Object.swift

@@ -396,13 +396,20 @@ public final class DynamicObject: Object {
 @objc(RealmSwiftObjectUtil)
 public class ObjectUtil: NSObject {
     @objc private class func swiftVersion() -> NSString {
+#if SWIFT_PACKAGE
+        return "5.1"
+#else
         return swiftLanguageVersion as NSString
+#endif
     }
 
     @objc private class func ignoredPropertiesForClass(_ type: AnyClass) -> NSArray? {
         if let type = type as? Object.Type {
             return type.ignoredProperties() as NSArray?
         }
+        if let type = type as? RLMObject.Type {
+            return type.ignoredProperties() as NSArray?
+        }
         return nil
     }
 
@@ -410,10 +417,16 @@ public class ObjectUtil: NSObject {
         if let type = type as? Object.Type {
             return type.indexedProperties() as NSArray?
         }
+        if let type = type as? RLMObject.Type {
+            return type.indexedProperties() as NSArray?
+        }
         return nil
     }
 
     @objc private class func linkingObjectsPropertiesForClass(_ type: AnyClass) -> NSDictionary? {
+        if let type = type as? RLMObject.Type {
+            return type.linkingObjectsProperties() as NSDictionary?
+        }
         // Not used for Swift. getLinkingObjectsProperties(_:) is used instead.
         return nil
     }
@@ -431,6 +444,12 @@ public class ObjectUtil: NSObject {
                 return name.substring(to: storageRange.lowerBound)
             #endif
         }
+        // Xcode 11 changed the name of the storage property to "$__lazy_storage_$_propName"
+        #if swift(>=4.0)
+            if let storageRange = name.range(of: "$__lazy_storage_$_", options: [.anchored]) {
+                return String(name[storageRange.upperBound...])
+            }
+        #endif
         return nil
     }
 
@@ -456,6 +475,11 @@ public class ObjectUtil: NSObject {
                     // Ignored lazy property.
                     return false
                 }
+                if object is RLMObject {
+                    // Implicitly ignore lazy properties on RLMObject subclasses
+                    // FIXME: should align RLMObject/Object behavior in 4.0
+                    return false
+                }
                 // Managed lazy property; not currently supported.
                 // FIXME: revisit this once Swift gets property behaviors/property macros.
                 throwRealmException("Lazy managed property '\(lazyBaseName)' is not allowed on a Realm Swift object"

+ 0 - 25
Carthage/Checkouts/realm-cocoa/RealmSwift/ObjectiveCSupport.swift

@@ -130,16 +130,6 @@ public final class ObjectiveCSupport {
         return SortDescriptor(keyPath: object.keyPath, ascending: object.ascending)
     }
 
-    /// Convert a `SyncCredentials` to a `RLMSyncCredentials`.
-    public static func convert(object: SyncCredentials) -> RLMSyncCredentials {
-        return RLMSyncCredentials(object)
-    }
-
-    /// Convert a `RLMSyncCredentials` to a `SyncCredentials`.
-    public static func convert(object: RLMSyncCredentials) -> SyncCredentials {
-        return SyncCredentials(object)
-    }
-
     /// Convert a `RLMShouldCompactOnLaunchBlock` to a Realm Swift compact block.
     public static func convert(object: @escaping RLMShouldCompactOnLaunchBlock) -> (Int, Int) -> Bool {
         return { totalBytes, usedBytes in
@@ -153,19 +143,4 @@ public final class ObjectiveCSupport {
             return object(Int(totalBytes), Int(usedBytes))
         }
     }
-
-    /// Convert a `SyncConfiguration` to a `RLMSyncConfiguration`.
-    public static func convert(object: SyncConfiguration) -> RLMSyncConfiguration {
-        return object.asConfig()
-    }
-
-    /// Convert a `RLMSyncConfiguration` to a `SyncConfiguration`.
-    public static func convert(object: RLMSyncConfiguration) -> SyncConfiguration {
-        return SyncConfiguration(config: object)
-    }
-
-    /// Convert a `RLMSyncSubscription` to a `SyncSubscription`.
-    public static func convert(object: RLMSyncSubscription) -> SyncSubscription<Object> {
-        return SyncSubscription(object)
-    }
 }

+ 16 - 0
Carthage/Checkouts/realm-cocoa/RealmSwift/Optional.swift

@@ -64,3 +64,19 @@ public final class RealmOptional<Value: RealmOptionalType>: RLMOptionalBase {
         self.value = value
     }
 }
+
+#if swift(>=4.1)
+extension RealmOptional: Codable where Value: Codable {
+    public convenience init(from decoder: Decoder) throws {
+        self.init()
+        // `try decoder.singleValueContainer().decode(Value?.self)` incorrectly
+        // rejects null values: https://bugs.swift.org/browse/SR-7404
+        let container = try decoder.singleValueContainer()
+        self.value = container.decodeNil() ? nil : try container.decode(Value.self)
+    }
+
+    public func encode(to encoder: Encoder) throws {
+        try self.value.encode(to: encoder)
+    }
+}
+#endif

+ 231 - 23
Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift

@@ -110,17 +110,60 @@ public final class Realm {
                                 it will be passed in as an argument.
                                 Otherwise, a `Swift.Error` describing what went wrong will be
                                 passed to the block instead.
+     - returns: A task object which can be used to observe or cancel the async open.
 
      - note: The returned Realm is confined to the thread on which it was created.
              Because GCD does not guarantee that queues will always use the same
              thread, accessing the returned Realm outside the callback block (even if
              accessed from `callbackQueue`) is unsafe.
      */
+    @discardableResult
     public static func asyncOpen(configuration: Realm.Configuration = .defaultConfiguration,
                                  callbackQueue: DispatchQueue = .main,
-                                 callback: @escaping (Realm?, Swift.Error?) -> Void) {
-        RLMRealm.asyncOpen(with: configuration.rlmConfiguration, callbackQueue: callbackQueue) { rlmRealm, error in
+                                 callback: @escaping (Realm?, Swift.Error?) -> Void) -> AsyncOpenTask {
+        return AsyncOpenTask(rlmTask: RLMRealm.asyncOpen(with: configuration.rlmConfiguration, callbackQueue: callbackQueue) { rlmRealm, error in
             callback(rlmRealm.flatMap(Realm.init), error)
+        })
+    }
+
+    /**
+     A task object which can be used to observe or cancel an async open.
+
+     When a synchronized Realm is opened asynchronously, the latest state of the
+     Realm is downloaded from the server before the completion callback is
+     invoked. This task object can be used to observe the state of the download
+     or to cancel it. This should be used instead of trying to observe the
+     download via the sync session as the sync session itself is created
+     asynchronously, and may not exist yet when Realm.asyncOpen() returns.
+     */
+    public struct AsyncOpenTask {
+        fileprivate let rlmTask: RLMAsyncOpenTask
+
+        /**
+         Cancel the asynchronous open.
+
+         Any download in progress will be cancelled, and the completion block for this
+         async open will never be called. If multiple async opens on the same Realm are
+         happening concurrently, all other opens will fail with the error "operation cancelled".
+         */
+        public func cancel() { rlmTask.cancel() }
+
+        /**
+         Register a progress notification block.
+
+         Each registered progress notification block is called whenever the sync
+         subsystem has new progress data to report until the task is either cancelled
+         or the completion callback is called. Progress notifications are delivered on
+         the supplied queue.
+
+         - parameter queue: The queue to deliver progress notifications on.
+         - parameter block: The block to invoke when notifications are available.
+         */
+        public func addProgressNotification(queue: DispatchQueue = .main,
+                                            block: @escaping (SyncSession.Progress) -> Void) {
+            rlmTask.addProgressNotification(on: queue) { transferred, transferrable in
+                block(SyncSession.Progress(transferred: transferred, transferrable: transferrable))
+            }
         }
     }
 
@@ -264,31 +307,94 @@ public final class Realm {
     // MARK: Adding and Creating objects
 
     /**
-     Adds or updates an existing object into the Realm.
+     What to do when an object being added to or created in a Realm has a primary key that already exists.
+     */
+    public enum UpdatePolicy: Int {
+        /**
+         Throw an exception. This is the default when no policy is specified for `add()` or `create()`.
+
+         This behavior is the same as passing `update: false` to `add()` or `create()`.
+         */
+        case error = 0
+        /**
+         Overwrite only properties in the existing object which are different from the new values. This results
+         in change notifications reporting only the properties which changed, and influences the sync merge logic.
+
+         If few or no of the properties are changing this will be faster than .all and reduce how much data has
+         to be written to the Realm file. If all of the properties are changing, it may be slower than .all (but
+         will never result in *more* data being written).
+         */
+        case modified = 1
+        /**
+         Overwrite all properties in the existing object with the new values, even if they have not changed. This
+         results in change notifications reporting all properties as changed, and influences the sync merge logic.
+
+         This behavior is the same as passing `update: true` to `add()` or `create()`.
+         */
+        case all = 2
+    }
+
+    /**
+     Adds an unmanaged object to this Realm.
+
+     If `update` is `true` and an object with the same primary key already exists in this Realm, the existing object
+     will be overwritten by the newly added one. If `update` is `false` then it is instead a non-recoverable error
+     to add an object with a primary key that is already in use. `update` must be `false` for object types which
+     do not have a primary key.
 
-     Only pass `true` to `update` if the object has a primary key. If no object exists in the Realm with the same
-     primary key value, the object is inserted. Otherwise, the existing object is updated with any changed values.
+     Adding an object to a Realm will also add all child relationships referenced by that object (via `Object` and
+     `List<Object>` properties). Those objects must also be valid objects to add to this Realm, and the value of
+     the `update:` parameter is propagated to those adds.
 
-     When added, all child relationships referenced by this object will also be added to the Realm if they are not
-     already in it. If the object or any related objects are already being managed by a different Realm an error will be
-     thrown. Instead, use one of the `create` functions to insert a copy of a managed object into a different Realm.
+     The object to be added must either be an unmanaged object or a valid object which is already managed by this
+     Realm. Adding an object already managed by this Realm is a no-op, while adding an object which is managed by
+     another Realm or which has been deleted from any Realm (i.e. one where `isInvalidated` is `true`) is an error.
 
-     The object to be added must be valid and cannot have been previously deleted from a Realm (i.e. `isInvalidated`
-     must be `false`).
+     To copy a managed object from one Realm to another, use `create()` instead.
+
+     - warning: This method may only be called during a write transaction.
 
      - parameter object: The object to be added to this Realm.
      - parameter update: If `true`, the Realm will try to find an existing copy of the object (with the same primary
                          key), and update it. Otherwise, the object will be added.
      */
-    public func add(_ object: Object, update: Bool = false) {
-        if update && object.objectSchema.primaryKeyProperty == nil {
+    @available(*, deprecated, message: "Pass .error, .modified or .all rather than a boolean. .error is equivalent to false and .all is equivalent to true.")
+    public func add(_ object: Object, update: Bool) {
+        add(object, update: update ? .all : .error)
+    }
+
+    /**
+     Adds an unmanaged object to this Realm.
+
+     If an object with the same primary key already exists in this Realm, it is updated with the property values from
+     this object as specified by the `UpdatePolicy` selected. The update policy must be `.error` for objects with no
+     primary key.
+
+     Adding an object to a Realm will also add all child relationships referenced by that object (via `Object` and
+     `List<Object>` properties). Those objects must also be valid objects to add to this Realm, and the value of
+     the `update:` parameter is propagated to those adds.
+
+     The object to be added must either be an unmanaged object or a valid object which is already managed by this
+     Realm. Adding an object already managed by this Realm is a no-op, while adding an object which is managed by
+     another Realm or which has been deleted from any Realm (i.e. one where `isInvalidated` is `true`) is an error.
+
+     To copy a managed object from one Realm to another, use `create()` instead.
+
+     - warning: This method may only be called during a write transaction.
+
+     - parameter object: The object to be added to this Realm.
+     - parameter update: What to do if an object with the same primary key alredy exists. Must be `.error` for objects
+     without a primary key.
+     */
+    public func add(_ object: Object, update: UpdatePolicy = .error) {
+        if update != .error && object.objectSchema.primaryKeyProperty == nil {
             throwRealmException("'\(object.objectSchema.className)' does not have a primary key and can not be updated")
         }
-        RLMAddObjectToRealm(object, rlmRealm, update)
+        RLMAddObjectToRealm(object, rlmRealm, RLMUpdatePolicy(rawValue: UInt(update.rawValue))!)
     }
 
     /**
-     Adds or updates all the objects in a collection into the Realm.
+     Adds all the objects in a collection into the Realm.
 
      - see: `add(_:update:)`
 
@@ -297,7 +403,27 @@ public final class Realm {
      - parameter objects: A sequence which contains objects to be added to the Realm.
      - parameter update: If `true`, objects that are already in the Realm will be updated instead of added anew.
      */
-    public func add<S: Sequence>(_ objects: S, update: Bool = false) where S.Iterator.Element: Object {
+    @available(*, deprecated, message: "Pass .error, .modified or .all rather than a boolean. .error is equivalent to false and .all is equivalent to true.")
+    public func add<S: Sequence>(_ objects: S, update: Bool) where S.Iterator.Element: Object {
+        for obj in objects {
+            add(obj, update: update)
+        }
+    }
+
+    /**
+     Adds all the objects in a collection into the Realm.
+
+     - see: `add(_:update:)`
+
+     - warning: This method may only be called during a write transaction.
+
+     - parameter objects: A sequence which contains objects to be added to the Realm.
+     - parameter update: How to handle
+     without a primary key.
+     - parameter update: How to handle objects in the collection with a primary key that alredy exists in this
+     Realm. Must be `.error` for object types without a primary key.
+     */
+    public func add<S: Sequence>(_ objects: S, update: UpdatePolicy = .error) where S.Iterator.Element: Object {
         for obj in objects {
             add(obj, update: update)
         }
@@ -339,12 +465,49 @@ public final class Realm {
      - returns: The newly created object.
      */
     @discardableResult
-    public func create<T: Object>(_ type: T.Type, value: Any = [:], update: Bool = false) -> T {
-        let typeName = (type as Object.Type).className()
-        if update && schema[typeName]?.primaryKeyProperty == nil {
-            throwRealmException("'\(typeName)' does not have a primary key and can not be updated")
+    @available(*, deprecated, message: "Pass .error, .modified or .all rather than a boolean. .error is equivalent to false and .all is equivalent to true.")
+    public func create<T: Object>(_ type: T.Type, value: Any = [:], update: Bool) -> T {
+        return create(type, value: value, update: update ? .all : .error)
+    }
+
+    /**
+     Creates a Realm object with a given value, adding it to the Realm and returning it.
+
+     The `value` argument can be a Realm object, a key-value coding compliant object, an array
+     or dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing
+     one element for each managed property. Do not pass in a `LinkingObjects` instance, either
+     by itself or as a member of a collection. If the `value` argument is an array, all properties
+     must be present, valid and in the same order as the properties defined in the model.
+
+     If the object type does not have a primary key or no object with the specified primary key
+     already exists, a new object is created in the Realm. If an object already exists in the Realm
+     with the specified primary key and the update policy is `.modified` or `.all`, the existing
+     object will be updated and a reference to that object will be returned.
+
+     If the object is being updated, all properties defined in its schema will be set by copying
+     from `value` using key-value coding. If the `value` argument does not respond to `value(forKey:)`
+     for a given property name (or getter name, if defined), that value will remain untouched.
+     Nullable properties on the object can be set to nil by using `NSNull` as the updated value,
+     or (if you are passing in an instance of an `Object` subclass) setting the corresponding
+     property on `value` to nil.
+
+     - warning: This method may only be called during a write transaction.
+
+     - parameter type:   The type of the object to create.
+     - parameter value:  The value used to populate the object.
+     - parameter update: What to do if an object with the same primary key alredy exists. Must be `.error` for object
+     types without a primary key.
+
+     - returns: The newly created object.
+     */
+    @discardableResult
+    public func create<T: Object>(_ type: T.Type, value: Any = [:], update: UpdatePolicy = .error) -> T {
+        if update != .error {
+            RLMVerifyHasPrimaryKey(type)
         }
-        return unsafeDowncast(RLMCreateObjectInRealmWithValue(rlmRealm, typeName, value, update), to: T.self)
+        let typeName = (type as Object.Type).className()
+        return unsafeDowncast(RLMCreateObjectInRealmWithValue(rlmRealm, typeName, value,
+                                                              RLMUpdatePolicy(rawValue: UInt(update.rawValue))!), to: type)
     }
 
     /**
@@ -387,11 +550,56 @@ public final class Realm {
      :nodoc:
      */
     @discardableResult
-    public func dynamicCreate(_ typeName: String, value: Any = [:], update: Bool = false) -> DynamicObject {
-        if update && schema[typeName]?.primaryKeyProperty == nil {
+    @available(*, deprecated, message: "Pass .error, .modified or .all rather than a boolean. .error is equivalent to false and .all is equivalent to true.")
+    public func dynamicCreate(_ typeName: String, value: Any = [:], update: Bool) -> DynamicObject {
+        return dynamicCreate(typeName, value: value, update: update ? .all : .error)
+    }
+
+    /**
+     This method is useful only in specialized circumstances, for example, when building
+     components that integrate with Realm. If you are simply building an app on Realm, it is
+     recommended to use the typed method `create(_:value:update:)`.
+
+     Creates or updates an object with the given class name and adds it to the `Realm`, populating
+     the object with the given value.
+
+     The `value` argument can be a Realm object, a key-value coding compliant object, an array
+     or dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing
+     one element for each managed property. Do not pass in a `LinkingObjects` instance, either
+     by itself or as a member of a collection. If the `value` argument is an array, all properties
+     must be present, valid and in the same order as the properties defined in the model.
+
+     If the object type does not have a primary key or no object with the specified primary key
+     already exists, a new object is created in the Realm. If an object already exists in the Realm
+     with the specified primary key and the update policy is `.modified` or `.all`, the existing
+     object will be updated and a reference to that object will be returned.
+
+     If the object is being updated, all properties defined in its schema will be set by copying
+     from `value` using key-value coding. If the `value` argument does not respond to `value(forKey:)`
+     for a given property name (or getter name, if defined), that value will remain untouched.
+     Nullable properties on the object can be set to nil by using `NSNull` as the updated value,
+     or (if you are passing in an instance of an `Object` subclass) setting the corresponding
+     property on `value` to nil.
+
+
+     - warning: This method can only be called during a write transaction.
+
+     - parameter className:  The class name of the object to create.
+     - parameter value:      The value used to populate the object.
+     - parameter update:     What to do if an object with the same primary key alredy exists.
+     Must be `.error` for object types without a primary key.
+
+     - returns: The created object.
+
+     :nodoc:
+     */
+    @discardableResult
+    public func dynamicCreate(_ typeName: String, value: Any = [:], update: UpdatePolicy = .error) -> DynamicObject {
+        if update != .error && schema[typeName]?.primaryKeyProperty == nil {
             throwRealmException("'\(typeName)' does not have a primary key and can not be updated")
         }
-        return noWarnUnsafeBitCast(RLMCreateObjectInRealmWithValue(rlmRealm, typeName, value, update),
+        return noWarnUnsafeBitCast(RLMCreateObjectInRealmWithValue(rlmRealm, typeName, value,
+                                                                   RLMUpdatePolicy(rawValue: UInt(update.rawValue))!),
                                    to: DynamicObject.self)
     }
 

+ 19 - 123
Carthage/Checkouts/realm-cocoa/RealmSwift/RealmCollection.swift

@@ -181,7 +181,7 @@ private func arrayType<T>(_ type: T.Type) -> RLMArray<AnyObject> {
     case is String.Type: return RLMArray(objectType: .string, optional: true)
     case is Data.Type:   return RLMArray(objectType: .data, optional: true)
     case is Date.Type:   return RLMArray(objectType: .date, optional: true)
-    default: fatalError("Unsupported type for List: \(T.self)?")
+    default: fatalError("Unsupported type for List: \(type)?")
     }
 }
 
@@ -252,21 +252,12 @@ extension Data: RealmCollectionValue {
     }
 }
 
-#if swift(>=3.2)
-// FIXME: When we drop support for Swift 3.1, change ElementType to Element
-// throughout the project (this is a non-breaking change). We use ElementType
-// only because of limitations in Swift 3.1's compiler.
 /// :nodoc:
 public protocol RealmCollectionBase: RandomAccessCollection, LazyCollectionProtocol, CustomStringConvertible, ThreadConfined where Element: RealmCollectionValue {
+    // This typealias was needed with Swift 3.1. It no longer is, but remains
+    // just in case someone was depending on it
     typealias ElementType = Element
 }
-#else
-/// :nodoc:
-public protocol RealmCollectionBase: RandomAccessCollection, LazyCollectionProtocol, CustomStringConvertible, ThreadConfined {
-    /// The type of the objects contained in the collection.
-    associatedtype ElementType: RealmCollectionValue
-}
-#endif
 
 /**
  A homogenous collection of `Object`s which can be retrieved, filtered, sorted, and operated upon.
@@ -300,7 +291,7 @@ public protocol RealmCollection: RealmCollectionBase {
 
      - parameter object: An object.
      */
-    func index(of object: ElementType) -> Int?
+    func index(of object: Element) -> Int?
 
     /**
      Returns the index of the first object matching the predicate, or `nil` if no objects match.
@@ -324,14 +315,14 @@ public protocol RealmCollection: RealmCollectionBase {
 
      - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments.
      */
-    func filter(_ predicateFormat: String, _ args: Any...) -> Results<ElementType>
+    func filter(_ predicateFormat: String, _ args: Any...) -> Results<Element>
 
     /**
      Returns a `Results` containing all objects matching the given predicate in the collection.
 
      - parameter predicate: The predicate to use to filter the objects.
      */
-    func filter(_ predicate: NSPredicate) -> Results<ElementType>
+    func filter(_ predicate: NSPredicate) -> Results<Element>
 
 
     // MARK: Sorting
@@ -349,7 +340,7 @@ public protocol RealmCollection: RealmCollectionBase {
      - parameter keyPath:   The key path to sort by.
      - parameter ascending: The direction to sort in.
      */
-    func sorted(byKeyPath keyPath: String, ascending: Bool) -> Results<ElementType>
+    func sorted(byKeyPath keyPath: String, ascending: Bool) -> Results<Element>
 
     /**
      Returns a `Results` containing the objects in the collection, but sorted.
@@ -361,7 +352,7 @@ public protocol RealmCollection: RealmCollectionBase {
 
      - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by.
      */
-    func sorted<S: Sequence>(by sortDescriptors: S) -> Results<ElementType> where S.Iterator.Element == SortDescriptor
+    func sorted<S: Sequence>(by sortDescriptors: S) -> Results<Element> where S.Iterator.Element == SortDescriptor
 
     // MARK: Aggregate Operations
 
@@ -493,7 +484,7 @@ public protocol RealmCollection: RealmCollectionBase {
     func observe(_ block: @escaping (RealmCollectionChange<Self>) -> Void) -> NotificationToken
 
     /// :nodoc:
-    func _observe(_ block: @escaping (RealmCollectionChange<AnyRealmCollection<ElementType>>) -> Void) -> NotificationToken
+    func _observe(_ block: @escaping (RealmCollectionChange<AnyRealmCollection<Element>>) -> Void) -> NotificationToken
 }
 
 /// :nodoc:
@@ -511,8 +502,6 @@ extension Optional: OptionalProtocol {
 }
 
 
-// FIXME: See the declaration of RealmCollectionBase for why this `#if` is required.
-#if swift(>=3.2)
 public extension RealmCollection where Element: MinMaxType {
     /**
      Returns the minimum (lowest) value of the collection, or `nil` if the collection is empty.
@@ -600,95 +589,6 @@ public extension RealmCollection where Element: OptionalProtocol, Element.Wrappe
         return sorted(byKeyPath: "self", ascending: ascending)
     }
 }
-#else
-public extension RealmCollection where ElementType: MinMaxType {
-    /**
-     Returns the minimum (lowest) value of the collection, or `nil` if the collection is empty.
-     */
-    public func min() -> ElementType? {
-        return min(ofProperty: "self")
-    }
-    /**
-     Returns the maximum (highest) value of the collection, or `nil` if the collection is empty.
-     */
-    public func max() -> ElementType? {
-        return max(ofProperty: "self")
-    }
-}
-
-public extension RealmCollection where ElementType: OptionalProtocol, ElementType.Wrapped: MinMaxType {
-    /**
-     Returns the minimum (lowest) value of the collection, or `nil` if the collection is empty.
-     */
-    public func min() -> ElementType.Wrapped? {
-        return min(ofProperty: "self")
-    }
-    /**
-     Returns the maximum (highest) value of the collection, or `nil` if the collection is empty.
-     */
-    public func max() -> ElementType.Wrapped? {
-        return max(ofProperty: "self")
-    }
-}
-
-public extension RealmCollection where ElementType: AddableType {
-    /**
-     Returns the sum of the values in the collection, or `nil` if the collection is empty.
-     */
-    public func sum() -> ElementType {
-        return sum(ofProperty: "self")
-    }
-    /**
-     Returns the average of all of the values in the collection.
-     */
-    public func average() -> Double? {
-        return average(ofProperty: "self")
-    }
-}
-
-public extension RealmCollection where ElementType: OptionalProtocol, ElementType.Wrapped: AddableType {
-    /**
-     Returns the sum of the values in the collection, or `nil` if the collection is empty.
-     */
-    public func sum() -> ElementType.Wrapped {
-        return sum(ofProperty: "self")
-    }
-    /**
-     Returns the average of all of the values in the collection.
-     */
-    public func average() -> Double? {
-        return average(ofProperty: "self")
-    }
-}
-
-public extension RealmCollection where ElementType: Comparable {
-    /**
-     Returns a `Results` containing the objects in the collection, but sorted.
-
-     Objects are sorted based on their values. For example, to sort a collection of `Date`s from
-     neweset to oldest based, you might call `dates.sorted(ascending: true)`.
-
-     - parameter ascending: The direction to sort in.
-     */
-    public func sorted(ascending: Bool = true) -> Results<ElementType> {
-        return sorted(byKeyPath: "self", ascending: ascending)
-    }
-}
-
-public extension RealmCollection where ElementType: OptionalProtocol, ElementType.Wrapped: Comparable {
-    /**
-     Returns a `Results` containing the objects in the collection, but sorted.
-
-     Objects are sorted based on their values. For example, to sort a collection of `Date`s from
-     neweset to oldest based, you might call `dates.sorted(ascending: true)`.
-
-     - parameter ascending: The direction to sort in.
-     */
-    public func sorted(ascending: Bool = true) -> Results<ElementType> {
-        return sorted(byKeyPath: "self", ascending: ascending)
-    }
-}
-#endif
 
 private class _AnyRealmCollectionBase<T: RealmCollectionValue>: AssistedObjectiveCBridgeable {
     typealias Wrapper = AnyRealmCollection<Element>
@@ -723,7 +623,7 @@ private class _AnyRealmCollectionBase<T: RealmCollectionValue>: AssistedObjectiv
     var bridged: (objectiveCValue: Any, metadata: Any?) { fatalError() }
 }
 
-private final class _AnyRealmCollection<C: RealmCollection>: _AnyRealmCollectionBase<C.ElementType> {
+private final class _AnyRealmCollection<C: RealmCollection>: _AnyRealmCollectionBase<C.Element> {
     let base: C
     init(base: C) {
         self.base = base
@@ -739,7 +639,7 @@ private final class _AnyRealmCollection<C: RealmCollection>: _AnyRealmCollection
 
     // MARK: Index Retrieval
 
-    override func index(of object: C.ElementType) -> Int? { return base.index(of: object) }
+    override func index(of object: C.Element) -> Int? { return base.index(of: object) }
 
     override func index(matching predicate: NSPredicate) -> Int? { return base.index(matching: predicate) }
 
@@ -749,20 +649,20 @@ private final class _AnyRealmCollection<C: RealmCollection>: _AnyRealmCollection
 
     // MARK: Filtering
 
-    override func filter(_ predicateFormat: String, _ args: Any...) -> Results<C.ElementType> {
+    override func filter(_ predicateFormat: String, _ args: Any...) -> Results<C.Element> {
         return base.filter(NSPredicate(format: predicateFormat, argumentArray: unwrapOptionals(in: args)))
     }
 
-    override func filter(_ predicate: NSPredicate) -> Results<C.ElementType> { return base.filter(predicate) }
+    override func filter(_ predicate: NSPredicate) -> Results<C.Element> { return base.filter(predicate) }
 
     // MARK: Sorting
 
-    override func sorted(byKeyPath keyPath: String, ascending: Bool) -> Results<C.ElementType> {
+    override func sorted(byKeyPath keyPath: String, ascending: Bool) -> Results<C.Element> {
         return base.sorted(byKeyPath: keyPath, ascending: ascending)
     }
 
     override func sorted<S: Sequence>
-        (by sortDescriptors: S) -> Results<C.ElementType> where S.Iterator.Element == SortDescriptor {
+        (by sortDescriptors: S) -> Results<C.Element> where S.Iterator.Element == SortDescriptor {
         return base.sorted(by: sortDescriptors)
     }
 
@@ -788,12 +688,8 @@ private final class _AnyRealmCollection<C: RealmCollection>: _AnyRealmCollection
 
     // MARK: Sequence Support
 
-    override subscript(position: Int) -> C.ElementType {
-        #if swift(>=3.2)
-            return base[position as! C.Index]
-        #else
-            return base[position as! C.Index] as! C.ElementType
-        #endif
+    override subscript(position: Int) -> C.Element {
+        return base[position as! C.Index]
     }
 
     override func makeIterator() -> RLMIterator<Element> {
@@ -862,7 +758,7 @@ public final class AnyRealmCollection<Element: RealmCollectionValue>: RealmColle
     }
 
     /// Creates an `AnyRealmCollection` wrapping `base`.
-    public init<C: RealmCollection>(_ base: C) where C.ElementType == Element {
+    public init<C: RealmCollection>(_ base: C) where C.Element == Element {
         self.base = _AnyRealmCollection(base: base)
     }
 
@@ -1155,7 +1051,7 @@ extension AnyRealmCollection: AssistedObjectiveCBridgeable {
 
 extension RealmCollection {
     @available(*, unavailable, renamed: "sorted(byKeyPath:ascending:)")
-    func sorted(byProperty property: String, ascending: Bool) -> Results<ElementType> { fatalError() }
+    func sorted(byProperty property: String, ascending: Bool) -> Results<Element> { fatalError() }
 
     @available(*, unavailable, renamed: "observe(_:)")
     public func addNotificationBlock(_ block: @escaping (RealmCollectionChange<Self>) -> Void) -> NotificationToken {

+ 14 - 1
Carthage/Checkouts/realm-cocoa/RealmSwift/Results.swift

@@ -337,7 +337,7 @@ public final class Results<Element: RealmCollectionValue>: NSObject, NSFastEnume
      will reflect the state of the Realm after the write transaction.
 
      ```swift
-     let results = realm.objects(Dog.self)
+     let dogs = realm.objects(Dog.self)
      print("dogs.count: \(dogs?.count)") // => 0
      let token = dogs.observe { changes in
          switch changes {
@@ -418,3 +418,16 @@ extension Results: AssistedObjectiveCBridgeable {
         return (objectiveCValue: rlmResults, metadata: nil)
     }
 }
+
+// MARK: - Codable
+
+#if swift(>=4.1)
+extension Results: Encodable where Element: Encodable {
+    public func encode(to encoder: Encoder) throws {
+        var container = encoder.unkeyedContainer()
+        for value in self {
+            try container.encode(value)
+        }
+    }
+}
+#endif

+ 18 - 25
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/KVOTests.swift

@@ -25,7 +25,7 @@ func nextPrimaryKey() -> Int {
     return pkCounter
 }
 
-class KVOObject: Object {
+class SwiftKVOObject: Object {
     @objc dynamic var pk = nextPrimaryKey() // primary key for equality
     @objc dynamic var ignored: Int = 0
 
@@ -39,8 +39,8 @@ class KVOObject: Object {
     @objc dynamic var stringCol: String = ""
     @objc dynamic var binaryCol: Data = Data()
     @objc dynamic var dateCol: Date = Date(timeIntervalSince1970: 0)
-    @objc dynamic var objectCol: KVOObject?
-    let arrayCol = List<KVOObject>()
+    @objc dynamic var objectCol: SwiftKVOObject?
+    let arrayCol = List<SwiftKVOObject>()
     let optIntCol = RealmOptional<Int>()
     let optFloatCol = RealmOptional<Float>()
     let optDoubleCol = RealmOptional<Double>()
@@ -100,7 +100,7 @@ class KVOTests: TestCase {
     }
 
     // swiftlint:disable:next cyclomatic_complexity
-    func observeChange<T: Equatable>(_ obj: KVOObject, _ key: String, _ old: T?, _ new: T?,
+    func observeChange<T: Equatable>(_ obj: SwiftKVOObject, _ key: String, _ old: T?, _ new: T?,
                                      fileName: StaticString = #file, lineNumber: UInt = #line, _ block: () -> Void) {
         let kvoOptions: NSKeyValueObservingOptions = [.old, .new]
         obj.addObserver(self, forKeyPath: key, options: kvoOptions, context: nil)
@@ -123,8 +123,7 @@ class KVOTests: TestCase {
         changeDictionary = nil
     }
 
-#if swift(>=3.2)
-    func observeChange<T: Equatable>(_ obj: KVOObject, _ keyPath: KeyPath<KVOObject, T>, _ old: Any?, _ new: Any?,
+    func observeChange<T: Equatable>(_ obj: SwiftKVOObject, _ keyPath: KeyPath<SwiftKVOObject, T>, _ old: Any?, _ new: Any?,
                                      fileName: StaticString = #file, lineNumber: UInt = #line, _ block: () -> Void) {
         let kvoOptions: NSKeyValueObservingOptions = [.old, .new]
         var gotNotification = false
@@ -147,7 +146,6 @@ class KVOTests: TestCase {
 
         XCTAssertTrue(gotNotification, file: fileName, line: lineNumber)
     }
-#endif
 
     func observeListChange(_ obj: NSObject, _ key: String, _ kind: NSKeyValueChange, _ indexes: NSIndexSet = NSIndexSet(index: 0),
                            fileName: StaticString = #file, lineNumber: UInt = #line, _ block: () -> Void) {
@@ -167,27 +165,20 @@ class KVOTests: TestCase {
         changeDictionary = nil
     }
 
-    func getObject(_ obj: KVOObject) -> (KVOObject, KVOObject) {
+    func getObject(_ obj: SwiftKVOObject) -> (SwiftKVOObject, SwiftKVOObject) {
         return (obj, obj)
     }
 
     // Actual tests follow
 
     func testAllPropertyTypes() {
-        let (obj, obs) = getObject(KVOObject())
+        let (obj, obs) = getObject(SwiftKVOObject())
 
         observeChange(obs, "boolCol", false, true) { obj.boolCol = true }
-#if swift(>=3.2)
         observeChange(obs, "int8Col", 1 as Int8, 10) { obj.int8Col = 10 }
         observeChange(obs, "int16Col", 2 as Int16, 10) { obj.int16Col = 10 }
         observeChange(obs, "int32Col", 3 as Int32, 10) { obj.int32Col = 10 }
         observeChange(obs, "int64Col", 4 as Int64, 10) { obj.int64Col = 10 }
-#else
-        observeChange(obs, "int8Col", 1, 10) { obj.int8Col = 10 }
-        observeChange(obs, "int16Col", 2, 10) { obj.int16Col = 10 }
-        observeChange(obs, "int32Col", 3, 10) { obj.int32Col = 10 }
-        observeChange(obs, "int64Col", 4, 10) { obj.int64Col = 10 }
-#endif
         observeChange(obs, "floatCol", 5 as Float, 10) { obj.floatCol = 10 }
         observeChange(obs, "doubleCol", 6 as Double, 10) { obj.doubleCol = 10 }
         observeChange(obs, "stringCol", "", "abc") { obj.stringCol = "abc" }
@@ -257,15 +248,14 @@ class KVOTests: TestCase {
             self.realm.delete(obj)
         }
 
-        let (obj2, obs2) = getObject(KVOObject())
+        let (obj2, obs2) = getObject(SwiftKVOObject())
         observeChange(obs2, "arrayCol.invalidated", false, true) {
             self.realm.delete(obj2)
         }
     }
 
-#if swift(>=3.2)
     func testTypedObservation() {
-        let (obj, obs) = getObject(KVOObject())
+        let (obj, obs) = getObject(SwiftKVOObject())
 
         observeChange(obs, \.boolCol, false, true) { obj.boolCol = true }
 
@@ -299,30 +289,33 @@ class KVOTests: TestCase {
             return
         }
 
+        // FIXME: crashes xcode11b1 compiler even when disabled with #if
+        // FB6115674
+        /*
         observeChange(obs, \.isInvalidated, false, true) {
             self.realm.delete(obj)
         }
+         */
     }
-#endif
 
     func testReadSharedSchemaFromObservedObject() {
-        let obj = KVOObject()
+        let obj = SwiftKVOObject()
         obj.addObserver(self, forKeyPath: "boolCol", options: [.old, .new], context: nil)
-        XCTAssertEqual(type(of: obj).sharedSchema(), KVOObject.sharedSchema())
+        XCTAssertEqual(type(of: obj).sharedSchema(), SwiftKVOObject.sharedSchema())
         obj.removeObserver(self, forKeyPath: "boolCol")
     }
 }
 
 class KVOPersistedTests: KVOTests {
-    override func getObject(_ obj: KVOObject) -> (KVOObject, KVOObject) {
+    override func getObject(_ obj: SwiftKVOObject) -> (SwiftKVOObject, SwiftKVOObject) {
         realm.add(obj)
         return (obj, obj)
     }
 }
 
 class KVOMultipleAccessorsTests: KVOTests {
-    override func getObject(_ obj: KVOObject) -> (KVOObject, KVOObject) {
+    override func getObject(_ obj: SwiftKVOObject) -> (SwiftKVOObject, SwiftKVOObject) {
         realm.add(obj)
-        return (obj, realm.object(ofType: KVOObject.self, forPrimaryKey: obj.pk)!)
+        return (obj, realm.object(ofType: SwiftKVOObject.self, forPrimaryKey: obj.pk)!)
     }
 }

+ 10 - 10
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectAccessorTests.swift

@@ -356,11 +356,11 @@ class ObjectAccessorTests: TestCase {
     }
 
     func testRenamedProperties() {
-        let obj = RenamedProperties1()
+        let obj = SwiftRenamedProperties1()
         obj.propA = 5
         obj.propB = "a"
 
-        let link = LinkToRenamedProperties1()
+        let link = LinkToSwiftRenamedProperties1()
         link.linkA = obj
         link.array1.append(obj)
 
@@ -377,14 +377,14 @@ class ObjectAccessorTests: TestCase {
 
         XCTAssertEqual(obj["propA"]! as! Int, 5)
         XCTAssertEqual(obj["propB"]! as! String, "a")
-        XCTAssertTrue((link["linkA"]! as! RenamedProperties1).isSameObject(as: obj))
-        XCTAssertTrue((link["array1"]! as! List<RenamedProperties1>)[0].isSameObject(as: obj))
-        XCTAssertTrue((obj["linking1"]! as! LinkingObjects<LinkToRenamedProperties1>)[0].isSameObject(as: link))
+        XCTAssertTrue((link["linkA"]! as! SwiftRenamedProperties1).isSameObject(as: obj))
+        XCTAssertTrue((link["array1"]! as! List<SwiftRenamedProperties1>)[0].isSameObject(as: obj))
+        XCTAssertTrue((obj["linking1"]! as! LinkingObjects<LinkToSwiftRenamedProperties1>)[0].isSameObject(as: link))
 
         XCTAssertTrue(link.dynamicList("array1")[0].isSameObject(as: obj))
 
-        let obj2 = realm.objects(RenamedProperties2.self).first!
-        let link2 = realm.objects(LinkToRenamedProperties2.self).first!
+        let obj2 = realm.objects(SwiftRenamedProperties2.self).first!
+        let link2 = realm.objects(LinkToSwiftRenamedProperties2.self).first!
 
         XCTAssertEqual(obj2.propC, 5)
         XCTAssertEqual(obj2.propD, "a")
@@ -394,9 +394,9 @@ class ObjectAccessorTests: TestCase {
 
         XCTAssertEqual(obj2["propC"]! as! Int, 5)
         XCTAssertEqual(obj2["propD"]! as! String, "a")
-        XCTAssertTrue((link2["linkC"]! as! RenamedProperties1).isSameObject(as: obj))
-        XCTAssertTrue((link2["array2"]! as! List<RenamedProperties2>)[0].isSameObject(as: obj))
-        XCTAssertTrue((obj2["linking1"]! as! LinkingObjects<LinkToRenamedProperties1>)[0].isSameObject(as: link))
+        XCTAssertTrue((link2["linkC"]! as! SwiftRenamedProperties1).isSameObject(as: obj))
+        XCTAssertTrue((link2["array2"]! as! List<SwiftRenamedProperties2>)[0].isSameObject(as: obj))
+        XCTAssertTrue((obj2["linking1"]! as! LinkingObjects<LinkToSwiftRenamedProperties1>)[0].isSameObject(as: link))
 
         XCTAssertTrue(link2.dynamicList("array2")[0].isSameObject(as: obj))
     }

+ 234 - 12
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectCreationTests.swift

@@ -353,7 +353,24 @@ class ObjectCreationTests: TestCase {
         let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
         try! Realm().beginWrite()
         let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
-            [["primary", 12]]], update: true)
+            [["primary", 12]]], update: .all)
+        try! Realm().commitWrite()
+
+        let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
+        XCTAssertEqual(stringObjects.count, 1)
+        let persistedObject = object.object!
+
+        XCTAssertEqual(persistedObject.intCol, 12)
+        XCTAssertNil(standalone.realm) // the standalone object should be copied, rather than added, to the realm
+        XCTAssertEqual(object.object!, persistedObject)
+        XCTAssertEqual(object.objects.first!, persistedObject)
+    }
+
+    func testUpdateChangedWithNestedObjects() {
+        let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
+        try! Realm().beginWrite()
+        let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
+                                                                                      [["primary", 12]]], update: .modified)
         try! Realm().commitWrite()
 
         let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
@@ -435,7 +452,23 @@ class ObjectCreationTests: TestCase {
 
         try! Realm().beginWrite()
         try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
-        let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: true)
+        let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .all)
+        try! Realm().commitWrite()
+
+        XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
+        XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1)
+        XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4)
+    }
+
+    func testUpdateChangedWithObjectsFromAnotherRealm() {
+        realmWithTestPath().beginWrite()
+        let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self,
+                                                          value: ["primary", NSNull(), [["2", 2], ["4", 4]]])
+        try! realmWithTestPath().commitWrite()
+
+        try! Realm().beginWrite()
+        try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
+        let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .modified)
         try! Realm().commitWrite()
 
         XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
@@ -465,7 +498,6 @@ class ObjectCreationTests: TestCase {
     }
 
     func testCreateWithObjcName() {
-
         let realm = try! Realm()
         try! realm.write {
             let object = realm.create(SwiftObjcRenamedObject.self)
@@ -480,7 +512,6 @@ class ObjectCreationTests: TestCase {
     }
 
     func testCreateWithDifferentObjcName() {
-
         let realm = try! Realm()
         try! realm.write {
             let object = realm.create(SwiftObjcArbitrarilyRenamedObject.self)
@@ -499,7 +530,83 @@ class ObjectCreationTests: TestCase {
         realm.beginWrite()
 
         // Create with all fields nil
-        let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: true)
+        let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
+
+        XCTAssertNil(object.id.value)
+        XCTAssertNil(object.optIntCol.value)
+        XCTAssertNil(object.optInt8Col.value)
+        XCTAssertNil(object.optInt16Col.value)
+        XCTAssertNil(object.optInt32Col.value)
+        XCTAssertNil(object.optInt64Col.value)
+        XCTAssertNil(object.optBoolCol.value)
+        XCTAssertNil(object.optFloatCol.value)
+        XCTAssertNil(object.optDoubleCol.value)
+        XCTAssertNil(object.optDateCol)
+        XCTAssertNil(object.optStringCol)
+        XCTAssertNil(object.optNSStringCol)
+        XCTAssertNil(object.optBinaryCol)
+        XCTAssertNil(object.optObjectCol)
+
+        // Try to switch to non-nil
+        let object2 = SwiftOptionalPrimaryObject()
+        object2.optIntCol.value = 1
+        object2.optInt8Col.value = 1
+        object2.optInt16Col.value = 1
+        object2.optInt32Col.value = 1
+        object2.optInt64Col.value = 1
+        object2.optFloatCol.value = 1
+        object2.optDoubleCol.value = 1
+        object2.optBoolCol.value = true
+        object2.optDateCol = Date()
+        object2.optStringCol = ""
+        object2.optNSStringCol = ""
+        object2.optBinaryCol = Data()
+        object2.optObjectCol = SwiftBoolObject()
+        realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .all)
+
+        XCTAssertNil(object.id.value)
+        XCTAssertNotNil(object.optIntCol.value)
+        XCTAssertNotNil(object.optInt8Col.value)
+        XCTAssertNotNil(object.optInt16Col.value)
+        XCTAssertNotNil(object.optInt32Col.value)
+        XCTAssertNotNil(object.optInt64Col.value)
+        XCTAssertNotNil(object.optBoolCol.value)
+        XCTAssertNotNil(object.optFloatCol.value)
+        XCTAssertNotNil(object.optDoubleCol.value)
+        XCTAssertNotNil(object.optDateCol)
+        XCTAssertNotNil(object.optStringCol)
+        XCTAssertNotNil(object.optNSStringCol)
+        XCTAssertNotNil(object.optBinaryCol)
+        XCTAssertNotNil(object.optObjectCol)
+
+        // Try to switch back to nil
+        realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
+
+        XCTAssertNil(object.id.value)
+
+        XCTAssertNil(object.optIntCol.value)
+        XCTAssertNil(object.optInt8Col.value)
+        XCTAssertNil(object.optInt16Col.value)
+        XCTAssertNil(object.optInt32Col.value)
+        XCTAssertNil(object.optInt64Col.value)
+        XCTAssertNil(object.optBoolCol.value)
+        XCTAssertNil(object.optFloatCol.value)
+        XCTAssertNil(object.optDoubleCol.value)
+        XCTAssertNil(object.optDateCol)
+        XCTAssertNil(object.optStringCol)
+        XCTAssertNil(object.optNSStringCol)
+        XCTAssertNil(object.optBinaryCol)
+        XCTAssertNil(object.optObjectCol)
+
+        realm.cancelWrite()
+    }
+
+    func testCreateOrUpdateModifiedNil() {
+        let realm = try! Realm()
+        realm.beginWrite()
+
+        // Create with all fields nil
+        let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
 
         XCTAssertNil(object.id.value)
         XCTAssertNil(object.optIntCol.value)
@@ -531,7 +638,7 @@ class ObjectCreationTests: TestCase {
         object2.optNSStringCol = ""
         object2.optBinaryCol = Data()
         object2.optObjectCol = SwiftBoolObject()
-        realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: true)
+        realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .modified)
 
         XCTAssertNil(object.id.value)
         XCTAssertNotNil(object.optIntCol.value)
@@ -549,7 +656,7 @@ class ObjectCreationTests: TestCase {
         XCTAssertNotNil(object.optObjectCol)
 
         // Try to switch back to nil
-        realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: true)
+        realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
 
         XCTAssertNil(object.id.value)
 
@@ -575,7 +682,7 @@ class ObjectCreationTests: TestCase {
         let unmanagedValue = SwiftOptionalPrimaryObject()
         // Shouldn't throw.
         realm.beginWrite()
-        _ = realm.create(type(of: unmanagedValue), value: unmanagedValue, update: true)
+        _ = realm.create(type(of: unmanagedValue), value: unmanagedValue, update: .modified)
         realm.cancelWrite()
     }
 
@@ -587,10 +694,33 @@ class ObjectCreationTests: TestCase {
         }
         // Shouldn't throw.
         realm.beginWrite()
-        _ = realm.create(type(of: managedValue), value: managedValue, update: true)
+        _ = realm.create(type(of: managedValue), value: managedValue, update: .all)
         realm.cancelWrite()
     }
 
+    func testCreateOrUpdateModifiedDynamicManagedType() {
+        let realm = try! Realm()
+        let managedValue = SwiftOptionalPrimaryObject()
+        try! realm.write {
+            realm.add(managedValue)
+        }
+        // Shouldn't throw.
+        realm.beginWrite()
+        _ = realm.create(type(of: managedValue), value: managedValue, update: .modified)
+        realm.cancelWrite()
+    }
+
+    func testCreateOrUpdateWithMismatchedStaticAndDynamicTypes() {
+        let realm = try! Realm()
+        let obj: Object = SwiftOptionalPrimaryObject()
+        try! realm.write {
+            let obj2 = realm.create(type(of: obj), value: obj)
+            XCTAssertEqual(obj2.objectSchema.className, "SwiftOptionalPrimaryObject")
+            let obj3 = realm.create(type(of: obj), value: obj, update: .all)
+            XCTAssertEqual(obj3.objectSchema.className, "SwiftOptionalPrimaryObject")
+        }
+    }
+
     // test null object
     // test null list
 
@@ -617,7 +747,22 @@ class ObjectCreationTests: TestCase {
 
         try! Realm().beginWrite()
         let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
-        try! Realm().add(object, update: true)
+        try! Realm().add(object, update: .all)
+        try! Realm().commitWrite()
+
+        XCTAssertNotNil(object.realm)
+        XCTAssertEqual(object.object!, existingObject) // the existing object should be updated
+        XCTAssertEqual(existingObject.intCol, 2)
+    }
+
+    func testAddAndUpdateChangedWithExisingNestedObjects() {
+        try! Realm().beginWrite()
+        let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1])
+        try! Realm().commitWrite()
+
+        try! Realm().beginWrite()
+        let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
+        try! Realm().add(object, update: .modified)
         try! Realm().commitWrite()
 
         XCTAssertNotNil(object.realm)
@@ -688,7 +833,84 @@ class ObjectCreationTests: TestCase {
         object2.optNSStringCol = ""
         object2.optBinaryCol = Data()
         object2.optObjectCol = SwiftBoolObject()
-        realm.add(object2, update: true)
+        realm.add(object2, update: .all)
+
+        XCTAssertNil(object.id.value)
+        XCTAssertNotNil(object.optIntCol.value)
+        XCTAssertNotNil(object.optInt8Col.value)
+        XCTAssertNotNil(object.optInt16Col.value)
+        XCTAssertNotNil(object.optInt32Col.value)
+        XCTAssertNotNil(object.optInt64Col.value)
+        XCTAssertNotNil(object.optBoolCol.value)
+        XCTAssertNotNil(object.optFloatCol.value)
+        XCTAssertNotNil(object.optDoubleCol.value)
+        XCTAssertNotNil(object.optDateCol)
+        XCTAssertNotNil(object.optStringCol)
+        XCTAssertNotNil(object.optNSStringCol)
+        XCTAssertNotNil(object.optBinaryCol)
+        XCTAssertNotNil(object.optObjectCol)
+
+        // Try to switch back to nil
+        let object3 = SwiftOptionalPrimaryObject()
+        realm.add(object3, update: .all)
+
+        XCTAssertNil(object.id.value)
+        XCTAssertNil(object.optIntCol.value)
+        XCTAssertNil(object.optInt8Col.value)
+        XCTAssertNil(object.optInt16Col.value)
+        XCTAssertNil(object.optInt32Col.value)
+        XCTAssertNil(object.optInt64Col.value)
+        XCTAssertNil(object.optBoolCol.value)
+        XCTAssertNil(object.optFloatCol.value)
+        XCTAssertNil(object.optDoubleCol.value)
+        XCTAssertNil(object.optDateCol)
+        XCTAssertNil(object.optStringCol)
+        XCTAssertNil(object.optNSStringCol)
+        XCTAssertNil(object.optBinaryCol)
+        XCTAssertNil(object.optObjectCol)
+
+        realm.cancelWrite()
+    }
+
+    func testAddOrUpdateModifiedNil() {
+        let realm = try! Realm()
+        realm.beginWrite()
+
+        // Create with all fields nil
+        let object = SwiftOptionalPrimaryObject()
+        realm.add(object)
+
+        XCTAssertNil(object.id.value)
+        XCTAssertNil(object.optIntCol.value)
+        XCTAssertNil(object.optInt8Col.value)
+        XCTAssertNil(object.optInt16Col.value)
+        XCTAssertNil(object.optInt32Col.value)
+        XCTAssertNil(object.optInt64Col.value)
+        XCTAssertNil(object.optBoolCol.value)
+        XCTAssertNil(object.optFloatCol.value)
+        XCTAssertNil(object.optDoubleCol.value)
+        XCTAssertNil(object.optDateCol)
+        XCTAssertNil(object.optStringCol)
+        XCTAssertNil(object.optNSStringCol)
+        XCTAssertNil(object.optBinaryCol)
+        XCTAssertNil(object.optObjectCol)
+
+        // Try to switch to non-nil
+        let object2 = SwiftOptionalPrimaryObject()
+        object2.optIntCol.value = 1
+        object2.optInt8Col.value = 1
+        object2.optInt16Col.value = 1
+        object2.optInt32Col.value = 1
+        object2.optInt64Col.value = 1
+        object2.optFloatCol.value = 1
+        object2.optDoubleCol.value = 1
+        object2.optBoolCol.value = true
+        object2.optDateCol = Date()
+        object2.optStringCol = ""
+        object2.optNSStringCol = ""
+        object2.optBinaryCol = Data()
+        object2.optObjectCol = SwiftBoolObject()
+        realm.add(object2, update: .modified)
 
         XCTAssertNil(object.id.value)
         XCTAssertNotNil(object.optIntCol.value)
@@ -707,7 +929,7 @@ class ObjectCreationTests: TestCase {
 
         // Try to switch back to nil
         let object3 = SwiftOptionalPrimaryObject()
-        realm.add(object3, update: true)
+        realm.add(object3, update: .modified)
 
         XCTAssertNil(object.id.value)
         XCTAssertNil(object.optIntCol.value)

+ 11 - 11
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectTests.swift

@@ -25,7 +25,7 @@ private func nextDynamicDefaultSeed() -> Int {
     dynamicDefaultSeed += 1
     return dynamicDefaultSeed
 }
-class DynamicDefaultObject: Object {
+class SwiftDynamicDefaultObject: Object {
     @objc dynamic var intCol = nextDynamicDefaultSeed()
     @objc dynamic var floatCol = Float(nextDynamicDefaultSeed())
     @objc dynamic var doubleCol = Double(nextDynamicDefaultSeed())
@@ -121,15 +121,15 @@ class ObjectTests: TestCase {
         recursiveObject.objects.append(recursiveObject)
         assertMatches(recursiveObject.description, "SwiftRecursiveObject \\{\n\tobjects = List<SwiftRecursiveObject> <0x[0-9a-f]+> \\(\n\t\t\\[0\\] SwiftRecursiveObject \\{\n\t\t\tobjects = List<SwiftRecursiveObject> <0x[0-9a-f]+> \\(\n\t\t\t\t\\[0\\] SwiftRecursiveObject \\{\n\t\t\t\t\tobjects = <Maximum depth exceeded>;\n\t\t\t\t\\}\n\t\t\t\\);\n\t\t\\}\n\t\\);\n\\}")
 
-        let renamedObject = LinkToRenamedProperties1()
-        renamedObject.linkA = RenamedProperties1()
-        assertMatches(renamedObject.description, "LinkToRenamedProperties1 \\{\n\tlinkA = RenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<RenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
-        assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToRenamedProperties1> <0x[0-9a-f]+> \\(\n\n\\)")
+        let renamedObject = LinkToSwiftRenamedProperties1()
+        renamedObject.linkA = SwiftRenamedProperties1()
+        assertMatches(renamedObject.description, "LinkToSwiftRenamedProperties1 \\{\n\tlinkA = SwiftRenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
+        assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToSwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\n\\)")
 
         let realm = try! Realm()
         try! realm.write { realm.add(renamedObject) }
-        assertMatches(renamedObject.description, "LinkToRenamedProperties1 \\{\n\tlinkA = RenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<RenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
-        assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\\[0\\] LinkToRenamedProperties1 \\{\n\t\tlinkA = RenamedProperties1 \\{\n\t\t\tpropA = 0;\n\t\t\tpropB = ;\n\t\t\\};\n\t\tlinkB = \\(null\\);\n\t\tarray1 = List<RenamedProperties1> <0x[0-9a-f]+> \\(\n\t\t\n\t\t\\);\n\t\\}\n\\)")
+        assertMatches(renamedObject.description, "LinkToSwiftRenamedProperties1 \\{\n\tlinkA = SwiftRenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
+        assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToSwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\\[0\\] LinkToSwiftRenamedProperties1 \\{\n\t\tlinkA = SwiftRenamedProperties1 \\{\n\t\t\tpropA = 0;\n\t\t\tpropB = ;\n\t\t\\};\n\t\tlinkB = \\(null\\);\n\t\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\t\n\t\t\\);\n\t\\}\n\\)")
         // swiftlint:enable line_length
     }
 
@@ -221,7 +221,7 @@ class ObjectTests: TestCase {
     }
 
     func testDynamicDefaultPropertyValues() {
-        func assertDifferentPropertyValues(_ obj1: DynamicDefaultObject, _ obj2: DynamicDefaultObject) {
+        func assertDifferentPropertyValues(_ obj1: SwiftDynamicDefaultObject, _ obj2: SwiftDynamicDefaultObject) {
             XCTAssertNotEqual(obj1.intCol, obj2.intCol)
             XCTAssertNotEqual(obj1.floatCol, obj2.floatCol)
             XCTAssertNotEqual(obj1.doubleCol, obj2.doubleCol)
@@ -230,11 +230,11 @@ class ObjectTests: TestCase {
             XCTAssertNotEqual(obj1.stringCol, obj2.stringCol)
             XCTAssertNotEqual(obj1.binaryCol, obj2.binaryCol)
         }
-        assertDifferentPropertyValues(DynamicDefaultObject(), DynamicDefaultObject())
+        assertDifferentPropertyValues(SwiftDynamicDefaultObject(), SwiftDynamicDefaultObject())
         let realm = try! Realm()
         try! realm.write {
-            assertDifferentPropertyValues(realm.create(DynamicDefaultObject.self),
-                                          realm.create(DynamicDefaultObject.self))
+            assertDifferentPropertyValues(realm.create(SwiftDynamicDefaultObject.self),
+                                          realm.create(SwiftDynamicDefaultObject.self))
         }
     }
 

+ 2 - 2
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/ObjectiveCSupportTests.swift

@@ -59,12 +59,10 @@ class ObjectiveCSupportTests: TestCase {
     }
 
     func testConfigurationSupport() {
-
         let realm = try! Realm()
 
         try! realm.write {
             realm.add(SwiftObject())
-            return
         }
 
         XCTAssertEqual(realm.configuration.fileURL,
@@ -75,9 +73,11 @@ class ObjectiveCSupportTests: TestCase {
                        ObjectiveCSupport.convert(object: realm.configuration).inMemoryIdentifier,
                        "Configuration.inMemoryIdentifier must be equal to RLMConfiguration.inMemoryIdentifier")
 
+        #if !SWIFT_PACKAGE
         XCTAssertEqual(realm.configuration.syncConfiguration?.realmURL,
                        ObjectiveCSupport.convert(object: realm.configuration).syncConfiguration?.realmURL,
                        "Configuration.syncConfiguration must be equal to RLMConfiguration.syncConfiguration")
+        #endif
 
         XCTAssertEqual(realm.configuration.encryptionKey,
                        ObjectiveCSupport.convert(object: realm.configuration).encryptionKey,

+ 2 - 0
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmSwiftTests-BridgingHeader.h

@@ -17,3 +17,5 @@
 ////////////////////////////////////////////////////////////////////////////
 
 #import "TestUtils.h"
+#import "RLMAssertions.h"
+#import "RLMTestCase.h"

+ 10 - 10
Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/RealmTests.swift

@@ -107,14 +107,14 @@ class RealmTests: TestCase {
         try! fileManager.setAttributes([FileAttributeKey.posixPermissions: permissions], ofItemAtPath: testRealmURL().path)
     }
 
-    #if DEBUG
+    #if !SWIFT_PACKAGE && DEBUG
     func testFileFormatUpgradeRequiredButDisabled() {
         var config = Realm.Configuration()
-        var bundledRealmPath = NSBundle(forClass: RealmTests.self).pathForResource("fileformat-pre-null.realm",
-                                                                                   ofType: nil)!
-        try! NSFileManager.defaultManager.copyItemAtPath(bundledRealmPath, toPath: config.path)
+        let bundledRealmPath = Bundle(for: RealmTests.self).path(forResource: "fileformat-pre-null.realm",
+                                                                 ofType: nil)!
+        try! FileManager.default.copyItem(atPath: bundledRealmPath, toPath: config.fileURL!.path)
         config.disableFormatUpgrade = true
-        assertFails(Error.FileFormatUpgradeRequired) {
+        assertFails(Realm.Error.fileFormatUpgradeRequired) {
             try Realm(configuration: config)
         }
     }
@@ -317,16 +317,16 @@ class RealmTests: TestCase {
         var defaultRealmObject: SwiftPrimaryStringObject!
         try! realm.write {
             defaultRealmObject = SwiftPrimaryStringObject()
-            realm.add(defaultRealmObject, update: true)
+            realm.add(defaultRealmObject, update: .all)
             XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
-            realm.add(SwiftPrimaryStringObject(), update: true)
+            realm.add(SwiftPrimaryStringObject(), update: .all)
             XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
         }
         XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
 
         let testRealm = realmWithTestPath()
         try! testRealm.write {
-            self.assertThrows(_ = testRealm.add(defaultRealmObject, update: true))
+            self.assertThrows(_ = testRealm.add(defaultRealmObject, update: .all))
         }
     }
 
@@ -352,14 +352,14 @@ class RealmTests: TestCase {
         XCTAssertEqual(0, realm.objects(SwiftPrimaryStringObject.self).count)
         try! realm.write {
             let objs = [SwiftPrimaryStringObject(), SwiftPrimaryStringObject()]
-            realm.add(objs, update: true)
+            realm.add(objs, update: .all)
             XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
         }
         XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
 
         let testRealm = realmWithTestPath()
         try! testRealm.write {
-            self.assertThrows(_ = testRealm.add(realm.objects(SwiftPrimaryStringObject.self), update: true))
+            self.assertThrows(_ = testRealm.add(realm.objects(SwiftPrimaryStringObject.self), update: .all))
         }
     }
 

Some files were not shown because too many files changed in this diff