diff options
author | marinofaggiana <marino@marinofaggiana.com> | 2019-07-16 17:18:15 +0300 |
---|---|---|
committer | marinofaggiana <marino@marinofaggiana.com> | 2019-07-16 17:18:15 +0300 |
commit | 254330d7fd0453ab0265551641ce54884ffbc479 (patch) | |
tree | 249d872eca6a68161da95eef8348a34f78456daf /Carthage | |
parent | 2133ce602f1bf1a5387954957e02f82b6e3dfe46 (diff) |
update version library in Cartfile
Diffstat (limited to 'Carthage')
36 files changed, 566 insertions, 1951 deletions
diff --git a/Carthage/Checkouts/KTVHTTPCache/Framework/Info.plist b/Carthage/Checkouts/KTVHTTPCache/Framework/Info.plist index 724fe0e9a..7d615f172 100644 --- a/Carthage/Checkouts/KTVHTTPCache/Framework/Info.plist +++ b/Carthage/Checkouts/KTVHTTPCache/Framework/Info.plist @@ -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> diff --git a/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache.podspec b/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache.podspec index 4fa471ea9..02735d5ca 100644 --- a/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache.podspec +++ b/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache.podspec @@ -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" } diff --git a/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache/Classes/KTVHCHTTPServer/KTVHCHTTPServer.m b/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache/Classes/KTVHCHTTPServer/KTVHCHTTPServer.m index 0e19983e7..3849c3724 100644 --- a/Carthage/Checkouts/KTVHTTPCache/KTVHTTPCache/Classes/KTVHCHTTPServer/KTVHCHTTPServer.m +++ b/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 diff --git a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard index 6892fc013..b0eef3525 100644 --- a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard +++ b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard @@ -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"/> diff --git a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/CustomCameraCell.swift b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/CustomCameraCell.swift index 776f255c2..3dd8740c2 100644 --- a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/CustomCameraCell.swift +++ b/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 diff --git a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift index 74dbc133c..a1bb569e2 100644 --- a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift +++ b/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() diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker.podspec b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker.podspec index a7d342a1c..3af386e2a 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker.podspec +++ b/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.2' 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' diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLAlbumPopView.swift b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLAlbumPopView.swift index ee7664dfe..9fce3d13e 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLAlbumPopView.swift +++ b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLAlbumPopView.swift @@ -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() { diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLBundle.swift b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLBundle.swift index 0b4060b88..dca3da27a 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLBundle.swift +++ b/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 + } } diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.swift b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.swift index e37ce0b73..66639d40a 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLCollectionTableViewCell.swift +++ b/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 diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift index eea7a8fc7..6079f1dea 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift +++ b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift @@ -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,20 @@ open class TLPhotosPickerViewController: UIViewController { } } - open func maxCheck() -> Bool { - if self.configure.singleSelectedMode { + open func deselectWhenUsingSingleSelectedMode() { + if + self.configure.singleSelectedMode == true, + let selectedPHAsset = self.selectedAssets.first?.phAsset, + var index = self.focusedCollection?.fetchResult?.index(of: selectedPHAsset) + { + index += self.configure.usedCameraButton ? 1 : 0 self.selectedAssets.removeAll() - self.orderUpdateCells() + self.collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } + } + + 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 +302,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 +648,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 +689,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 +749,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 +869,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 +995,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)" diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib index 6dd465227..a754ded75 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib +++ b/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"/> diff --git a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md index 2fedc5265..d1d5c5cea 100644 --- a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md +++ b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md @@ -1,3 +1,30 @@ +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) ============================================================= diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm index 01dd590df..cbad7156b 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/RLMObjectServerTests.mm @@ -1379,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; @@ -1487,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; } @@ -1584,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"]; @@ -1598,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 { diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift b/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift index 311cf06e5..7c1115734 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectServerTests/SwiftObjectServerTests.swift +++ b/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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h index aa554177d..8fbad1310 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.h +++ b/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; diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm index 41e61001d..f92e17622 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm +++ b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm.mm @@ -48,6 +48,7 @@ #if REALM_ENABLE_SYNC #import "RLMSyncManager_Private.h" +#import "RLMSyncSession_Private.hpp" #import "RLMSyncUtil_Private.hpp" #import "sync/async_open_task.hpp" @@ -107,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; @@ -227,10 +235,15 @@ static void waitForPartialSyncSubscriptions(Realm::Config const& config) { #endif } -+ (void)asyncOpenWithConfiguration:(RLMRealmConfiguration *)configuration - callbackQueue:(dispatch_queue_t)callbackQueue - callback:(RLMAsyncOpenRealmCallback)callback { - static dispatch_queue_t queue = dispatch_queue_create("io.realm.asyncOpenDispatchQueue", DISPATCH_QUEUE_CONCURRENT); +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 (err) { @@ -263,7 +276,7 @@ static void waitForPartialSyncSubscriptions(Realm::Config const& config) { // 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(queue, ^{ + dispatch_async(s_async_open_queue, ^{ @autoreleasepool { waitForPartialSyncSubscriptions(realm->config()); complete(); @@ -276,12 +289,15 @@ static void waitForPartialSyncSubscriptions(Realm::Config const& config) { } }; - dispatch_async(queue, ^{ + RLMAsyncOpenTask *ret = [RLMAsyncOpenTask new]; + dispatch_async(s_async_open_queue, ^{ @autoreleasepool { Realm::Config& config = configuration.config; if (config.sync_config) { #if REALM_ENABLE_SYNC - realm::Realm::get_synchronized_realm(config)->start(openCompletion); + 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 @@ -296,6 +312,7 @@ static void waitForPartialSyncSubscriptions(Realm::Config const& config) { } } }); + return ret; } // ARC tries to eliminate calls to autorelease when the value is then immediately diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm_Private.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm_Private.h index a2368c303..ae13f1eb6 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMRealm_Private.h +++ b/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); diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.h b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.h index 1ea50758f..3b26184f5 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.h +++ b/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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.mm b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.mm index 74c938fc1..cddaade2f 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession.mm +++ b/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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession_Private.hpp b/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession_Private.hpp index 76a06ad18..b14d2f660 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/RLMSyncSession_Private.hpp +++ b/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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist index 06b920cd2..270ffda8d 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist +++ b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist @@ -17,11 +17,11 @@ <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> - <string>3.17.0</string> + <string>3.17.1</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>3.17.0</string> + <string>3.17.1</string> <key>NSHumanReadableCopyright</key> <string>Copyright © 2014 Realm. All rights reserved.</string> <key>NSPrincipalClass</key> diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMAssertions.h b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMAssertions.h deleted file mode 100644 index 59b386be3..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMAssertions.h +++ /dev/null @@ -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); \ -}) diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.h b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.h deleted file mode 100644 index 64bc2b0c3..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.h +++ /dev/null @@ -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") diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.m b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.m deleted file mode 100644 index 2161dedd7..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMMultiProcessTestCase.m +++ /dev/null @@ -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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.h b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.h deleted file mode 100644 index a2baab6aa..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.h +++ /dev/null @@ -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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.m b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.m deleted file mode 100644 index 3fee74123..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestCase.m +++ /dev/null @@ -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 - diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.h b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.h deleted file mode 100644 index 0f8981b00..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.h +++ /dev/null @@ -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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.m b/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.m deleted file mode 100644 index 93fffabdf..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/RLMTestObjects.m +++ /dev/null @@ -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 diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.h b/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.h deleted file mode 100644 index 42ebd4593..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.h +++ /dev/null @@ -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); diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.mm b/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.mm deleted file mode 100644 index 731b86d75..000000000 --- a/Carthage/Checkouts/realm-cocoa/Realm/Tests/TestUtils.mm +++ /dev/null @@ -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]; - } -} diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift b/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift index 960ab6194..bcd2afe46 100644 --- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Realm.swift +++ b/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)) + } } } diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.h b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.h deleted file mode 100644 index 82dd0a386..000000000 --- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.h +++ /dev/null @@ -1,41 +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 RLMAssertThrowsWithName(XCTestCase *self, __attribute__((noescape)) dispatch_block_t block, - NSString *name, NSString *message, NSString *fileName, - NSUInteger lineNumber); - - -FOUNDATION_EXTERN void RLMAssertThrowsWithReasonMatching(XCTestCase *self, - __attribute__((noescape)) dispatch_block_t block, - NSString *regexString, NSString *message, - NSString *fileName, NSUInteger lineNumber); - -FOUNDATION_EXTERN void RLMAssertMatches(XCTestCase *self, __attribute__((noescape)) NSString *(^block)(), - NSString *regexString, NSString *message, NSString *fileName, - NSUInteger lineNumber); - -FOUNDATION_EXTERN void RLMAssertThrowsWithReason(XCTestCase *self, - __attribute__((noescape)) dispatch_block_t block, - NSString *regexString, NSString *message, - NSString *fileName, NSUInteger lineNumber); - -FOUNDATION_EXTERN bool RLMHasCachedRealmForPath(NSString *path); diff --git a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.mm b/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.mm deleted file mode 100644 index 4a14c6110..000000000 --- a/Carthage/Checkouts/realm-cocoa/RealmSwift/Tests/TestUtils.mm +++ /dev/null @@ -1,100 +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" - -// 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 -__attribute((constructor)) -static void initializeSharedSchema() { - [RLMSchema sharedSchema]; -} - -static void assertThrows(XCTestCase *self, dispatch_block_t block, NSString *message, - NSString *fileName, NSUInteger lineNumber, - NSString *(^condition)(NSException *)) { - @try { - block(); - 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]; - } - @catch (NSException *e) { - if (NSString *failure = condition(e)) { - [self recordFailureWithDescription:failure inFile:fileName atLine:lineNumber expected:NO]; - } - } -} - -void RLMAssertThrowsWithName(XCTestCase *self, __attribute__((noescape)) dispatch_block_t block, - NSString *name, NSString *message, NSString *fileName, NSUInteger lineNumber) { - assertThrows(self, block, message, fileName, lineNumber, ^NSString *(NSException *e) { - if ([name isEqualToString:e.name]) { - return nil; - } - return [NSString stringWithFormat:@"The given expression threw an exception named '%@', but expected '%@'", - e.name, name]; - }); -} - -void RLMAssertThrowsWithReason(XCTestCase *self, __attribute__((noescape)) dispatch_block_t block, - NSString *expected, NSString *message, NSString *fileName, NSUInteger lineNumber) { - assertThrows(self, block, message, fileName, lineNumber, ^NSString *(NSException *e) { - if ([e.reason rangeOfString:expected].location != NSNotFound) { - return nil; - } - return [NSString stringWithFormat:@"The given expression threw an exception with reason '%@', but expected '%@'", - e.reason, expected]; - }); -} - -void RLMAssertThrowsWithReasonMatching(XCTestCase *self, __attribute__((noescape)) dispatch_block_t block, - NSString *regexString, NSString *message, - NSString *fileName, NSUInteger lineNumber) { - auto regex = [NSRegularExpression regularExpressionWithPattern:regexString - options:(NSRegularExpressionOptions)0 error:nil]; - assertThrows(self, block, message, fileName, lineNumber, ^NSString *(NSException *e) { - if ([regex numberOfMatchesInString:e.reason options:(NSMatchingOptions)0 range:{0, e.reason.length}] > 0) { - return nil; - } - return [NSString stringWithFormat:@"The given expression threw an exception with reason '%@', but expected to match '%@'", - e.reason, regexString]; - }); -} - - -void RLMAssertMatches(XCTestCase *self, __attribute__((noescape)) NSString *(^block)(), - NSString *regexString, NSString *message, NSString *fileName, NSUInteger lineNumber) { - NSString *result = block(); - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:(NSRegularExpressionOptions)0 error:nil]; - if ([regex numberOfMatchesInString:result options:(NSMatchingOptions)0 range:NSMakeRange(0, result.length)] == 0) { - NSString *msg = [NSString stringWithFormat:@"The given expression '%@' did not match '%@'%@", - result, regexString, message ? [NSString stringWithFormat:@": %@", message] : @""]; - [self recordFailureWithDescription:msg inFile:fileName atLine:lineNumber expected:NO]; - } -} - -bool RLMHasCachedRealmForPath(NSString *path) { - return RLMGetAnyCachedRealmForPath(path.UTF8String); -} diff --git a/Carthage/Checkouts/realm-cocoa/TestHost copy-Info.plist b/Carthage/Checkouts/realm-cocoa/TestHost copy-Info.plist deleted file mode 100644 index e8c29fb53..000000000 --- a/Carthage/Checkouts/realm-cocoa/TestHost copy-Info.plist +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> - <key>LSRequiresIPhoneOS</key> - <true/> - <key>UIRequiredDeviceCapabilities</key> - <array> - <string>armv7</string> - </array> - <key>NSPrincipalClass</key> - <string>$(PRINCIPAL_CLASS)</string> - <key>LSUIElement</key> - <true/> - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> - <key>NSAppTransportSecurity</key> - <dict> - <key>NSAllowsArbitraryLoads</key> - <true/> - </dict> -</dict> -</plist> diff --git a/Carthage/Checkouts/realm-cocoa/dependencies.list b/Carthage/Checkouts/realm-cocoa/dependencies.list index 41f0e736b..619c09a57 100644 --- a/Carthage/Checkouts/realm-cocoa/dependencies.list +++ b/Carthage/Checkouts/realm-cocoa/dependencies.list @@ -1,4 +1,4 @@ -VERSION=3.17.0 -REALM_CORE_VERSION=5.22.0 -REALM_SYNC_VERSION=4.6.1 +VERSION=3.17.1 +REALM_CORE_VERSION=5.23.1 +REALM_SYNC_VERSION=4.6.3 REALM_OBJECT_SERVER_VERSION=3.21.1 |