├── .gitignore ├── .ruby-gemset ├── .ruby-version ├── .swift-version ├── .swiftlint.yml ├── .travis.yml ├── Brewfile ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── PodTest ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── Podfile ├── Podfile.lock ├── README.md ├── RealmS.podspec ├── RealmS.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── PodTest.xcscheme │ ├── RealmS.xcscheme │ └── Tests.xcscheme ├── RealmS.xcworkspace └── contents.xcworkspacedata ├── Sources ├── CleanUp.swift ├── Info.plist ├── Mapping.swift ├── Operator.swift ├── RealmS.swift └── Transform.swift ├── Tests ├── Library │ ├── Utils.h │ └── Utils.m ├── Model │ ├── CleanUp.swift │ └── Model.swift ├── Resources │ └── users.json ├── Supports │ ├── Info.plist │ └── Tests-Bridging-Header.h └── Tests.swift └── scripts ├── ci ├── codecov ├── pr_number └── src_branch ├── git └── hooks │ └── commit-msg ├── install └── tests ├── branch ├── lint └── pod /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | ## Playgrounds 30 | timeline.xctimeline 31 | playground.xcworkspace 32 | 33 | # Swift Package Manager 34 | # 35 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 36 | # Packages/ 37 | .build/ 38 | 39 | # CocoaPods 40 | # 41 | # We recommend against adding the Pods directory to your .gitignore. However 42 | # you should judge for yourself, the pros and cons are mentioned at: 43 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 44 | Pods/ 45 | 46 | # Carthage 47 | # 48 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 49 | Carthage/Checkouts 50 | Carthage/Build 51 | 52 | # fastlane 53 | # 54 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 55 | # screenshots whenever they are needed. 56 | # For more information about the recommended setup visit: 57 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 58 | 59 | fastlane/report.xml 60 | fastlane/screenshots 61 | 62 | # Bundler 63 | vendor 64 | .bundle 65 | 66 | *.coverage.txt -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | ci 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.4.0 2 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | # reporter: xcode 2 | disabled_rules: 3 | - todo 4 | excluded: 5 | - Carthage 6 | - Pods 7 | - vendor 8 | line_length: 300 9 | file_length: 1000 10 | function_body_length: 11 | - 50 12 | - 100 13 | type_body_length: 14 | - 300 15 | - 500 16 | variable_name: 17 | excluded: 18 | - id 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode9.2 3 | cache: 4 | bundler: true 5 | cocoapods: true 6 | directories: 7 | - ~/.rvm 8 | - ~/.cocoapods 9 | - ~/Library/Caches/CocoaPods 10 | - .bundle 11 | - vendor 12 | env: 13 | global: 14 | - SDK='iphonesimulator11.2' 15 | - SCHEME='RealmS' 16 | - WORKSPACE='RealmS.xcworkspace' 17 | - DESTINATION='OS=11.2,name=iPhone 7' 18 | - CONFIGURATION='Debug' 19 | install: 20 | - set -o pipefail 21 | - ./scripts/install 22 | script: 23 | - export REPO_SLUG="$TRAVIS_REPO_SLUG" 24 | - export SRC_BRANCH="$(./scripts/src_branch)" 25 | - export PR_NUMBER="$(./scripts/pr_number)" 26 | - ./scripts/tests/lint 27 | - ./scripts/tests/pod 28 | notifications: 29 | email: false 30 | after_success: 31 | - ./scripts/codecov 32 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | brew 'jq' -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby '~> 2.4.0' 4 | 5 | gem 'cocoapods', '~> 1.4.0' 6 | gem 'linterbot', '~> 0.2.5' 7 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (2.3.6) 5 | activesupport (4.2.10) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.5.1) 11 | public_suffix (~> 2.0, >= 2.0.2) 12 | atomos (0.1.2) 13 | claide (1.0.2) 14 | cocoapods (1.4.0) 15 | activesupport (>= 4.0.2, < 5) 16 | claide (>= 1.0.2, < 2.0) 17 | cocoapods-core (= 1.4.0) 18 | cocoapods-deintegrate (>= 1.0.2, < 2.0) 19 | cocoapods-downloader (>= 1.1.3, < 2.0) 20 | cocoapods-plugins (>= 1.0.0, < 2.0) 21 | cocoapods-search (>= 1.0.0, < 2.0) 22 | cocoapods-stats (>= 1.0.0, < 2.0) 23 | cocoapods-trunk (>= 1.3.0, < 2.0) 24 | cocoapods-try (>= 1.1.0, < 2.0) 25 | colored2 (~> 3.1) 26 | escape (~> 0.0.4) 27 | fourflusher (~> 2.0.1) 28 | gh_inspector (~> 1.0) 29 | molinillo (~> 0.6.4) 30 | nap (~> 1.0) 31 | ruby-macho (~> 1.1) 32 | xcodeproj (>= 1.5.4, < 2.0) 33 | cocoapods-core (1.4.0) 34 | activesupport (>= 4.0.2, < 6) 35 | fuzzy_match (~> 2.0.4) 36 | nap (~> 1.0) 37 | cocoapods-deintegrate (1.0.2) 38 | cocoapods-downloader (1.1.3) 39 | cocoapods-plugins (1.0.0) 40 | nap 41 | cocoapods-search (1.0.0) 42 | cocoapods-stats (1.0.0) 43 | cocoapods-trunk (1.3.0) 44 | nap (>= 0.8, < 2.0) 45 | netrc (~> 0.11) 46 | cocoapods-try (1.1.0) 47 | colored2 (3.1.2) 48 | commander (4.4.3) 49 | highline (~> 1.7.2) 50 | concurrent-ruby (1.0.5) 51 | escape (0.0.4) 52 | faraday (0.11.0) 53 | multipart-post (>= 1.2, < 3) 54 | fourflusher (2.0.1) 55 | fuzzy_match (2.0.4) 56 | gh_inspector (1.1.2) 57 | highline (1.7.8) 58 | i18n (0.9.5) 59 | concurrent-ruby (~> 1.0) 60 | linterbot (0.2.6) 61 | commander (~> 4.3) 62 | octokit (~> 4.2) 63 | minitest (5.11.3) 64 | molinillo (0.6.4) 65 | multipart-post (2.0.0) 66 | nanaimo (0.2.3) 67 | nap (1.1.0) 68 | netrc (0.11.0) 69 | octokit (4.6.2) 70 | sawyer (~> 0.8.0, >= 0.5.3) 71 | public_suffix (2.0.5) 72 | ruby-macho (1.1.0) 73 | sawyer (0.8.1) 74 | addressable (>= 2.3.5, < 2.6) 75 | faraday (~> 0.8, < 1.0) 76 | thread_safe (0.3.6) 77 | tzinfo (1.2.5) 78 | thread_safe (~> 0.1) 79 | xcodeproj (1.5.6) 80 | CFPropertyList (~> 2.3.3) 81 | atomos (~> 0.1.2) 82 | claide (>= 1.0.2, < 2.0) 83 | colored2 (~> 3.1) 84 | nanaimo (~> 0.2.3) 85 | 86 | PLATFORMS 87 | ruby 88 | 89 | DEPENDENCIES 90 | cocoapods (~> 1.4.0) 91 | linterbot (~> 0.2.5) 92 | 93 | RUBY VERSION 94 | ruby 2.4.0p0 95 | 96 | BUNDLED WITH 97 | 1.16.1 98 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 zendobk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PodTest/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PodTest 4 | // 5 | // Created by DaoNV on 10/19/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import RealmS 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | RealmS.onError { (_, _, _) in 19 | // 20 | } 21 | return true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /PodTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /PodTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PodTest/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /PodTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /PodTest/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // PodTest 4 | // 5 | // Created by DaoNV on 10/19/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | inhibit_all_warnings! 3 | use_frameworks! 4 | platform :ios, '8.0' 5 | 6 | def shared_pods 7 | pod 'RealmSwift', '~> 3.0' 8 | pod 'ObjectMapper', '~> 3.0' 9 | end 10 | 11 | target 'RealmS' do 12 | shared_pods 13 | pod 'SwiftLint', '~> 0.25.0' 14 | target 'Tests' do 15 | inherit! :search_paths 16 | shared_pods 17 | end 18 | end 19 | 20 | target 'PodTest' do 21 | pod 'RealmS', :path => './' 22 | end 23 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ObjectMapper (3.1.0) 3 | - Realm (3.1.1): 4 | - Realm/Headers (= 3.1.1) 5 | - Realm/Headers (3.1.1) 6 | - RealmS (4.0.0): 7 | - ObjectMapper (~> 3.0) 8 | - RealmSwift (~> 3.0) 9 | - RealmSwift (3.1.1): 10 | - Realm (= 3.1.1) 11 | - SwiftLint (0.25.0) 12 | 13 | DEPENDENCIES: 14 | - ObjectMapper (~> 3.0) 15 | - RealmS (from `./`) 16 | - RealmSwift (~> 3.0) 17 | - SwiftLint (~> 0.25.0) 18 | 19 | EXTERNAL SOURCES: 20 | RealmS: 21 | :path: ./ 22 | 23 | SPEC CHECKSUMS: 24 | ObjectMapper: 20505058f54e5c3ca69e1d6de9897d152a5369a6 25 | Realm: 42d1c38a5b1bbcc828b48a7ce702cb86fc68adf4 26 | RealmS: 2f9e7bc9bf6dcfa4b6a0a21728dd6a4a3d9ea7b9 27 | RealmSwift: d31937ca6a6ee54acde64ec839523c0a3c04924b 28 | SwiftLint: e14651157288e9e01d6e1a71db7014fb5744a8ea 29 | 30 | PODFILE CHECKSUM: d2c97fdacc8b42e730b7789aa133dbad00eed529 31 | 32 | COCOAPODS: 1.4.0 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/tsrnd/realms-ios.svg?branch=master)](https://travis-ci.org/tsrnd/realms-ios) 2 | [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/RealmS.svg)](https://img.shields.io/cocoapods/v/RealmS.svg) 3 | [![Platform](https://img.shields.io/cocoapods/p/RealmS.svg?style=flat)](http://cocoadocs.org/docsets/RealmS) 4 | [![Coverage Status](https://codecov.io/github/tsrnd/realms-ios/coverage.svg?branch=master)](https://codecov.io/github/tsrnd/realms-ios?branch=master) 5 | 6 | [![RealmSwift](https://img.shields.io/badge/RealmSwift-~%3E%202.2-brightgreen.svg)](https://img.shields.io/badge/RealmSwift-~%3E%202.2-brightgreen.svg) 7 | [![ObjectMapper](https://img.shields.io/badge/ObjectMapper-~%3E%202.2-brightgreen.svg)](https://img.shields.io/badge/ObjectMapper-~%3E%202.2-brightgreen.svg) 8 | 9 | Realm + ObjectMapper 10 | ==================== 11 | 12 | ## Requirements 13 | 14 | - iOS 8.0+ 15 | - Xcode 9.2 (Swift 4.0+) 16 | 17 | ## Installation 18 | 19 | > Embedded frameworks require a minimum deployment target of iOS 8 20 | 21 | ### CocoaPods 22 | 23 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: 24 | 25 | ```bash 26 | $ gem install cocoapods 27 | ``` 28 | 29 | > CocoaPods 1.2+ is required to build RealmS 2.3+ 30 | 31 | To integrate RealmS into your Xcode project using CocoaPods, specify it in your `Podfile`: 32 | 33 | ```ruby 34 | source 'https://github.com/CocoaPods/Specs.git' 35 | platform :ios, '8.0' 36 | use_frameworks! 37 | 38 | pod 'RealmS', '~> 4.0.0' 39 | ``` 40 | 41 | Then, run the following command: 42 | 43 | ```bash 44 | $ pod install 45 | ``` 46 | 47 | ## Usage 48 | 49 | ### Mapping 50 | 51 | **Rule:** 52 | - Object has `primaryKey` must be StaticMappable (i) 53 | - Object has no `primaryKey` should be Mappable (ii) 54 | 55 | ```swift 56 | import RealmSwift 57 | import ObjectMapper 58 | import RealmS 59 | 60 | // (i) 61 | final class User: Object, StaticMappable { 62 | @objc dynamic var id: String! 63 | @objc dynamic var name: String? 64 | @objc dynamic var address: Address? 65 | let dogs = List() 66 | 67 | override class func primaryKey() -> String? { 68 | return "id" 69 | } 70 | 71 | func mapping(map: Map) { 72 | name <- map["name"] 73 | address <- map["address"] 74 | dogs <- map["dogs"] 75 | } 76 | 77 | static func objectForMapping(map: Map) -> BaseMappable? { 78 | return RealmS().object(ofType: self, forMapping: map) 79 | } 80 | } 81 | 82 | // (ii) 83 | final class Address: Object, Mappable { 84 | @objc dynamic var street = "" 85 | @objc dynamic var city = "" 86 | @objc dynamic var country = "" 87 | 88 | @objc dynamic var phone: Phone? 89 | 90 | let users = LinkingObjects(fromType: User.self, property: "address") 91 | 92 | convenience required init?(map: Map) { 93 | self.init() 94 | } 95 | 96 | func mapping(map: Map) { 97 | street <- map["street"] 98 | city <- map["city"] 99 | country <- map["country"] 100 | phone <- map["phone"] 101 | } 102 | } 103 | ``` 104 | 105 | ### Import JSON to Realm 106 | 107 | ```swift 108 | let realm = RealmS() 109 | realm.write { 110 | realm.map(User.self, jsUser) // map JSON object 111 | realm.map(Shop.self, jsShops) // map JSON array 112 | } 113 | ``` 114 | 115 | > - `nil` value will be bypass, if you want set `nil` please use `NSNull()` instead. 116 | 117 | ### Clean Up 118 | 119 | ```swift 120 | extension User { 121 | override public class func relativedTypes() -> [Object.Type] { 122 | return [Address.self, Pet.self] 123 | } 124 | 125 | override public class func clean() { } 126 | } 127 | 128 | extension Address { 129 | override class func relativedTypes() -> [Object.Type] { 130 | return [Phone.self] 131 | } 132 | 133 | override class func clean() { 134 | let realm = RealmS() 135 | let objs = realm.objects(self).filter("users.@count = 0") 136 | realm.write { 137 | realm.delete(objs) 138 | } 139 | } 140 | } 141 | ``` 142 | 143 | `Address` table will be clean-up after a `User` is deleted from Realm. 144 | -------------------------------------------------------------------------------- /RealmS.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'RealmS' 3 | s.version = '4.0.1' 4 | s.license = 'MIT' 5 | s.summary = 'RealmS' 6 | s.homepage = 'https://github.com/tsrnd/realms-ios' 7 | s.authors = { 'Dao Nguyen' => 'zendobk' } 8 | s.source = { :git => 'https://github.com/tsrnd/realms-ios', :tag => s.version} 9 | s.requires_arc = true 10 | s.ios.deployment_target = '8.0' 11 | s.ios.frameworks = 'Foundation', 'UIKit' 12 | s.dependency 'RealmSwift', '~> 3.0' 13 | s.dependency 'ObjectMapper', '~> 3.0' 14 | s.source_files = 'Sources/*.swift' 15 | end 16 | -------------------------------------------------------------------------------- /RealmS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 046A1F2BE6907B3C4537C761 /* Pods_RealmS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18F16AF5D32A50AA0238750C /* Pods_RealmS.framework */; }; 11 | EC11DD0E1DB0BA340008E58B /* RealmS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F401DF401C42A8F800870925 /* RealmS.framework */; }; 12 | EC90912F1ECC296900FEC9BE /* users.json in Resources */ = {isa = PBXBuildFile; fileRef = EC90912E1ECC296900FEC9BE /* users.json */; }; 13 | EC9091361ECC299900FEC9BE /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = EC9091321ECC299900FEC9BE /* Utils.m */; }; 14 | ECB592931EB03BC600ACB99F /* Operator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB592921EB03BC600ACB99F /* Operator.swift */; }; 15 | ECB592951EB03C0000ACB99F /* Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB592941EB03C0000ACB99F /* Transform.swift */; }; 16 | ECBAE7BC1DB7796400E520CE /* CleanUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBAE7B81DB7796400E520CE /* CleanUp.swift */; }; 17 | ECBAE7BE1DB7796400E520CE /* Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBAE7BA1DB7796400E520CE /* Mapping.swift */; }; 18 | ECBAE7BF1DB7796400E520CE /* RealmS.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBAE7BB1DB7796400E520CE /* RealmS.swift */; }; 19 | ECBAE7C71DB779CD00E520CE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBAE7C61DB779CD00E520CE /* AppDelegate.swift */; }; 20 | ECBAE7C91DB779CD00E520CE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBAE7C81DB779CD00E520CE /* ViewController.swift */; }; 21 | ECBAE7CC1DB779CD00E520CE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ECBAE7CA1DB779CD00E520CE /* Main.storyboard */; }; 22 | ECBAE7CE1DB779CD00E520CE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECBAE7CD1DB779CD00E520CE /* Assets.xcassets */; }; 23 | ECBAE7D11DB779CD00E520CE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ECBAE7CF1DB779CD00E520CE /* LaunchScreen.storyboard */; }; 24 | ECD21E351DB12028009757A6 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC287A5B1C96B80600FE7106 /* Tests.swift */; }; 25 | ECD21E361DB12B65009757A6 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC287A611C96BE0100FE7106 /* Model.swift */; }; 26 | ECD21E371DB12B68009757A6 /* CleanUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB925831CF408AC00716E8E /* CleanUp.swift */; }; 27 | F4095A101C68E3CB0077F92E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4095A0F1C68E3CB0077F92E /* UIKit.framework */; }; 28 | F4095A121C68E3D30077F92E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4095A111C68E3D30077F92E /* Foundation.framework */; }; 29 | FA69D86E4BE63BED32F3BD80 /* Pods_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 11200FAB505E4C830826843F /* Pods_Tests.framework */; }; 30 | FE2DFCA28EBE32D0A9BF1A0A /* Pods_PodTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D7B9C7E7975A8B3BE7D344D7 /* Pods_PodTest.framework */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | EC11DD0F1DB0BA340008E58B /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = F401DF371C42A8F800870925 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = F401DF3F1C42A8F800870925; 39 | remoteInfo = RealmS; 40 | }; 41 | ECE5D8A41DB875E400193DD5 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = F401DF371C42A8F800870925 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = F401DF3F1C42A8F800870925; 46 | remoteInfo = RealmS; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 11200FAB505E4C830826843F /* Pods_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 18F16AF5D32A50AA0238750C /* Pods_RealmS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RealmS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 231EE0BCCC5BD965713E1CE6 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; 54 | 358FDA7A52E35590DE467242 /* Pods-PodTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PodTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-PodTest/Pods-PodTest.release.xcconfig"; sourceTree = ""; }; 55 | 363EEB1CDB9D9D2D071DAE30 /* Pods-PodTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PodTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PodTest/Pods-PodTest.debug.xcconfig"; sourceTree = ""; }; 56 | 3E4385BDC9CA20D8FBF7C965 /* Pods-RealmS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RealmS/Pods-RealmS.debug.xcconfig"; sourceTree = ""; }; 57 | BC763CD81CE6CE556D690C9F /* Pods-RealmS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmS.release.xcconfig"; path = "Pods/Target Support Files/Pods-RealmS/Pods-RealmS.release.xcconfig"; sourceTree = ""; }; 58 | C6307F11B2CE078533D25E6F /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 59 | D7B9C7E7975A8B3BE7D344D7 /* Pods_PodTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PodTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | EC11DD091DB0BA330008E58B /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | EC287A5B1C96B80600FE7106 /* Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 62 | EC287A611C96BE0100FE7106 /* Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; 63 | EC90912E1ECC296900FEC9BE /* users.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = users.json; sourceTree = ""; }; 64 | EC9091311ECC299900FEC9BE /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; 65 | EC9091321ECC299900FEC9BE /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utils.m; sourceTree = ""; }; 66 | EC9091341ECC299900FEC9BE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | EC9091351ECC299900FEC9BE /* Tests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Tests-Bridging-Header.h"; sourceTree = ""; }; 68 | ECB592921EB03BC600ACB99F /* Operator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operator.swift; sourceTree = ""; }; 69 | ECB592941EB03C0000ACB99F /* Transform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Transform.swift; sourceTree = ""; }; 70 | ECB925831CF408AC00716E8E /* CleanUp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanUp.swift; sourceTree = ""; }; 71 | ECBAE7B81DB7796400E520CE /* CleanUp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanUp.swift; sourceTree = ""; }; 72 | ECBAE7B91DB7796400E520CE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | ECBAE7BA1DB7796400E520CE /* Mapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mapping.swift; sourceTree = ""; }; 74 | ECBAE7BB1DB7796400E520CE /* RealmS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmS.swift; sourceTree = ""; }; 75 | ECBAE7C41DB779CD00E520CE /* PodTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PodTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | ECBAE7C61DB779CD00E520CE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 77 | ECBAE7C81DB779CD00E520CE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 78 | ECBAE7CB1DB779CD00E520CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 79 | ECBAE7CD1DB779CD00E520CE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 80 | ECBAE7D01DB779CD00E520CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 81 | ECBAE7D21DB779CD00E520CE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 82 | F401DF401C42A8F800870925 /* RealmS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RealmS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | F4095A0F1C68E3CB0077F92E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 84 | F4095A111C68E3D30077F92E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | EC11DD061DB0BA330008E58B /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | EC11DD0E1DB0BA340008E58B /* RealmS.framework in Frameworks */, 93 | FA69D86E4BE63BED32F3BD80 /* Pods_Tests.framework in Frameworks */, 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | ECBAE7C11DB779CD00E520CE /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | FE2DFCA28EBE32D0A9BF1A0A /* Pods_PodTest.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | F401DF3C1C42A8F800870925 /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | F4095A121C68E3D30077F92E /* Foundation.framework in Frameworks */, 110 | F4095A101C68E3CB0077F92E /* UIKit.framework in Frameworks */, 111 | 046A1F2BE6907B3C4537C761 /* Pods_RealmS.framework in Frameworks */, 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | /* End PBXFrameworksBuildPhase section */ 116 | 117 | /* Begin PBXGroup section */ 118 | 514C9BD87075020B9C4459A9 /* Frameworks */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | F4095A111C68E3D30077F92E /* Foundation.framework */, 122 | F4095A0F1C68E3CB0077F92E /* UIKit.framework */, 123 | 18F16AF5D32A50AA0238750C /* Pods_RealmS.framework */, 124 | 11200FAB505E4C830826843F /* Pods_Tests.framework */, 125 | D7B9C7E7975A8B3BE7D344D7 /* Pods_PodTest.framework */, 126 | ); 127 | name = Frameworks; 128 | sourceTree = ""; 129 | }; 130 | 9C8D2FD9C0E54C27CF9E68D2 /* Pods */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 3E4385BDC9CA20D8FBF7C965 /* Pods-RealmS.debug.xcconfig */, 134 | BC763CD81CE6CE556D690C9F /* Pods-RealmS.release.xcconfig */, 135 | C6307F11B2CE078533D25E6F /* Pods-Tests.debug.xcconfig */, 136 | 231EE0BCCC5BD965713E1CE6 /* Pods-Tests.release.xcconfig */, 137 | 363EEB1CDB9D9D2D071DAE30 /* Pods-PodTest.debug.xcconfig */, 138 | 358FDA7A52E35590DE467242 /* Pods-PodTest.release.xcconfig */, 139 | ); 140 | name = Pods; 141 | sourceTree = ""; 142 | }; 143 | EC287A601C96BDE600FE7106 /* Model */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | EC287A611C96BE0100FE7106 /* Model.swift */, 147 | ECB925831CF408AC00716E8E /* CleanUp.swift */, 148 | ); 149 | path = Model; 150 | sourceTree = ""; 151 | }; 152 | EC90912D1ECC296900FEC9BE /* Resources */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | EC90912E1ECC296900FEC9BE /* users.json */, 156 | ); 157 | path = Resources; 158 | sourceTree = ""; 159 | }; 160 | EC9091301ECC299900FEC9BE /* Library */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | EC9091311ECC299900FEC9BE /* Utils.h */, 164 | EC9091321ECC299900FEC9BE /* Utils.m */, 165 | ); 166 | path = Library; 167 | sourceTree = ""; 168 | }; 169 | EC9091331ECC299900FEC9BE /* Supports */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | EC9091341ECC299900FEC9BE /* Info.plist */, 173 | EC9091351ECC299900FEC9BE /* Tests-Bridging-Header.h */, 174 | ); 175 | path = Supports; 176 | sourceTree = ""; 177 | }; 178 | ECBAE7B71DB7796400E520CE /* Sources */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | ECBAE7B91DB7796400E520CE /* Info.plist */, 182 | ECBAE7BB1DB7796400E520CE /* RealmS.swift */, 183 | ECBAE7B81DB7796400E520CE /* CleanUp.swift */, 184 | ECBAE7BA1DB7796400E520CE /* Mapping.swift */, 185 | ECB592921EB03BC600ACB99F /* Operator.swift */, 186 | ECB592941EB03C0000ACB99F /* Transform.swift */, 187 | ); 188 | path = Sources; 189 | sourceTree = ""; 190 | }; 191 | ECBAE7C51DB779CD00E520CE /* PodTest */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | ECBAE7C61DB779CD00E520CE /* AppDelegate.swift */, 195 | ECBAE7C81DB779CD00E520CE /* ViewController.swift */, 196 | ECBAE7CA1DB779CD00E520CE /* Main.storyboard */, 197 | ECBAE7CD1DB779CD00E520CE /* Assets.xcassets */, 198 | ECBAE7CF1DB779CD00E520CE /* LaunchScreen.storyboard */, 199 | ECBAE7D21DB779CD00E520CE /* Info.plist */, 200 | ); 201 | path = PodTest; 202 | sourceTree = ""; 203 | }; 204 | F401DF361C42A8F800870925 = { 205 | isa = PBXGroup; 206 | children = ( 207 | ECBAE7B71DB7796400E520CE /* Sources */, 208 | F4E9AF8D1C6639C6001559A1 /* Tests */, 209 | ECBAE7C51DB779CD00E520CE /* PodTest */, 210 | F401DF411C42A8F800870925 /* Products */, 211 | 514C9BD87075020B9C4459A9 /* Frameworks */, 212 | 9C8D2FD9C0E54C27CF9E68D2 /* Pods */, 213 | ); 214 | indentWidth = 4; 215 | sourceTree = ""; 216 | tabWidth = 4; 217 | }; 218 | F401DF411C42A8F800870925 /* Products */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | F401DF401C42A8F800870925 /* RealmS.framework */, 222 | EC11DD091DB0BA330008E58B /* Tests.xctest */, 223 | ECBAE7C41DB779CD00E520CE /* PodTest.app */, 224 | ); 225 | name = Products; 226 | sourceTree = ""; 227 | }; 228 | F4E9AF8D1C6639C6001559A1 /* Tests */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | EC287A5B1C96B80600FE7106 /* Tests.swift */, 232 | EC9091301ECC299900FEC9BE /* Library */, 233 | EC287A601C96BDE600FE7106 /* Model */, 234 | EC90912D1ECC296900FEC9BE /* Resources */, 235 | EC9091331ECC299900FEC9BE /* Supports */, 236 | ); 237 | path = Tests; 238 | sourceTree = ""; 239 | }; 240 | /* End PBXGroup section */ 241 | 242 | /* Begin PBXHeadersBuildPhase section */ 243 | F401DF3D1C42A8F800870925 /* Headers */ = { 244 | isa = PBXHeadersBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXHeadersBuildPhase section */ 251 | 252 | /* Begin PBXNativeTarget section */ 253 | EC11DD081DB0BA330008E58B /* Tests */ = { 254 | isa = PBXNativeTarget; 255 | buildConfigurationList = EC11DD111DB0BA340008E58B /* Build configuration list for PBXNativeTarget "Tests" */; 256 | buildPhases = ( 257 | 9040D4B90C07C73F843479D9 /* [CP] Check Pods Manifest.lock */, 258 | EC11DD051DB0BA330008E58B /* Sources */, 259 | EC11DD061DB0BA330008E58B /* Frameworks */, 260 | EC11DD071DB0BA330008E58B /* Resources */, 261 | 3A5901E2F4ACE543FB3AC92D /* [CP] Embed Pods Frameworks */, 262 | CC1B497784E5F23784E71835 /* [CP] Copy Pods Resources */, 263 | ); 264 | buildRules = ( 265 | ); 266 | dependencies = ( 267 | EC11DD101DB0BA340008E58B /* PBXTargetDependency */, 268 | ); 269 | name = Tests; 270 | productName = Tests; 271 | productReference = EC11DD091DB0BA330008E58B /* Tests.xctest */; 272 | productType = "com.apple.product-type.bundle.unit-test"; 273 | }; 274 | ECBAE7C31DB779CD00E520CE /* PodTest */ = { 275 | isa = PBXNativeTarget; 276 | buildConfigurationList = ECBAE7D31DB779CD00E520CE /* Build configuration list for PBXNativeTarget "PodTest" */; 277 | buildPhases = ( 278 | 126C3409CBB81FF403F78022 /* [CP] Check Pods Manifest.lock */, 279 | ECBAE7C01DB779CD00E520CE /* Sources */, 280 | ECBAE7C11DB779CD00E520CE /* Frameworks */, 281 | ECBAE7C21DB779CD00E520CE /* Resources */, 282 | B2458F19756614F90428111E /* [CP] Embed Pods Frameworks */, 283 | 50CA0C6940FA0848EDDC3020 /* [CP] Copy Pods Resources */, 284 | ); 285 | buildRules = ( 286 | ); 287 | dependencies = ( 288 | ECE5D8A51DB875E400193DD5 /* PBXTargetDependency */, 289 | ); 290 | name = PodTest; 291 | productName = PodTest; 292 | productReference = ECBAE7C41DB779CD00E520CE /* PodTest.app */; 293 | productType = "com.apple.product-type.application"; 294 | }; 295 | F401DF3F1C42A8F800870925 /* RealmS */ = { 296 | isa = PBXNativeTarget; 297 | buildConfigurationList = F401DF481C42A8F800870925 /* Build configuration list for PBXNativeTarget "RealmS" */; 298 | buildPhases = ( 299 | 1E42091115F348638CF8FC54 /* [CP] Check Pods Manifest.lock */, 300 | F401DF3B1C42A8F800870925 /* Sources */, 301 | F401DF3C1C42A8F800870925 /* Frameworks */, 302 | F401DF3D1C42A8F800870925 /* Headers */, 303 | F401DF3E1C42A8F800870925 /* Resources */, 304 | ECEBF5821CA285D90025CB91 /* SwiftLint */, 305 | 81752033136F7B506FBEE77B /* [CP] Copy Pods Resources */, 306 | ); 307 | buildRules = ( 308 | ); 309 | dependencies = ( 310 | ); 311 | name = RealmS; 312 | productName = RealmS; 313 | productReference = F401DF401C42A8F800870925 /* RealmS.framework */; 314 | productType = "com.apple.product-type.framework"; 315 | }; 316 | /* End PBXNativeTarget section */ 317 | 318 | /* Begin PBXProject section */ 319 | F401DF371C42A8F800870925 /* Project object */ = { 320 | isa = PBXProject; 321 | attributes = { 322 | LastSwiftUpdateCheck = 0800; 323 | LastUpgradeCheck = 0920; 324 | ORGANIZATIONNAME = "Apple Inc"; 325 | TargetAttributes = { 326 | EC11DD081DB0BA330008E58B = { 327 | CreatedOnToolsVersion = 8.0; 328 | LastSwiftMigration = 0830; 329 | ProvisioningStyle = Automatic; 330 | }; 331 | ECBAE7C31DB779CD00E520CE = { 332 | CreatedOnToolsVersion = 8.0; 333 | ProvisioningStyle = Automatic; 334 | }; 335 | F401DF3F1C42A8F800870925 = { 336 | CreatedOnToolsVersion = 7.2; 337 | LastSwiftMigration = 0830; 338 | }; 339 | }; 340 | }; 341 | buildConfigurationList = F401DF3A1C42A8F800870925 /* Build configuration list for PBXProject "RealmS" */; 342 | compatibilityVersion = "Xcode 3.2"; 343 | developmentRegion = English; 344 | hasScannedForEncodings = 0; 345 | knownRegions = ( 346 | en, 347 | Base, 348 | ); 349 | mainGroup = F401DF361C42A8F800870925; 350 | productRefGroup = F401DF411C42A8F800870925 /* Products */; 351 | projectDirPath = ""; 352 | projectRoot = ""; 353 | targets = ( 354 | F401DF3F1C42A8F800870925 /* RealmS */, 355 | EC11DD081DB0BA330008E58B /* Tests */, 356 | ECBAE7C31DB779CD00E520CE /* PodTest */, 357 | ); 358 | }; 359 | /* End PBXProject section */ 360 | 361 | /* Begin PBXResourcesBuildPhase section */ 362 | EC11DD071DB0BA330008E58B /* Resources */ = { 363 | isa = PBXResourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | EC90912F1ECC296900FEC9BE /* users.json in Resources */, 367 | ); 368 | runOnlyForDeploymentPostprocessing = 0; 369 | }; 370 | ECBAE7C21DB779CD00E520CE /* Resources */ = { 371 | isa = PBXResourcesBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | ECBAE7D11DB779CD00E520CE /* LaunchScreen.storyboard in Resources */, 375 | ECBAE7CE1DB779CD00E520CE /* Assets.xcassets in Resources */, 376 | ECBAE7CC1DB779CD00E520CE /* Main.storyboard in Resources */, 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | F401DF3E1C42A8F800870925 /* Resources */ = { 381 | isa = PBXResourcesBuildPhase; 382 | buildActionMask = 2147483647; 383 | files = ( 384 | ); 385 | runOnlyForDeploymentPostprocessing = 0; 386 | }; 387 | /* End PBXResourcesBuildPhase section */ 388 | 389 | /* Begin PBXShellScriptBuildPhase section */ 390 | 126C3409CBB81FF403F78022 /* [CP] Check Pods Manifest.lock */ = { 391 | isa = PBXShellScriptBuildPhase; 392 | buildActionMask = 2147483647; 393 | files = ( 394 | ); 395 | inputPaths = ( 396 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 397 | "${PODS_ROOT}/Manifest.lock", 398 | ); 399 | name = "[CP] Check Pods Manifest.lock"; 400 | outputPaths = ( 401 | "$(DERIVED_FILE_DIR)/Pods-PodTest-checkManifestLockResult.txt", 402 | ); 403 | runOnlyForDeploymentPostprocessing = 0; 404 | shellPath = /bin/sh; 405 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 406 | showEnvVarsInLog = 0; 407 | }; 408 | 1E42091115F348638CF8FC54 /* [CP] Check Pods Manifest.lock */ = { 409 | isa = PBXShellScriptBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | ); 413 | inputPaths = ( 414 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 415 | "${PODS_ROOT}/Manifest.lock", 416 | ); 417 | name = "[CP] Check Pods Manifest.lock"; 418 | outputPaths = ( 419 | "$(DERIVED_FILE_DIR)/Pods-RealmS-checkManifestLockResult.txt", 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | shellPath = /bin/sh; 423 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 424 | showEnvVarsInLog = 0; 425 | }; 426 | 3A5901E2F4ACE543FB3AC92D /* [CP] Embed Pods Frameworks */ = { 427 | isa = PBXShellScriptBuildPhase; 428 | buildActionMask = 2147483647; 429 | files = ( 430 | ); 431 | inputPaths = ( 432 | "${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh", 433 | "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", 434 | "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", 435 | "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", 436 | ); 437 | name = "[CP] Embed Pods Frameworks"; 438 | outputPaths = ( 439 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", 440 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", 441 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", 442 | ); 443 | runOnlyForDeploymentPostprocessing = 0; 444 | shellPath = /bin/sh; 445 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; 446 | showEnvVarsInLog = 0; 447 | }; 448 | 50CA0C6940FA0848EDDC3020 /* [CP] Copy Pods Resources */ = { 449 | isa = PBXShellScriptBuildPhase; 450 | buildActionMask = 2147483647; 451 | files = ( 452 | ); 453 | inputPaths = ( 454 | ); 455 | name = "[CP] Copy Pods Resources"; 456 | outputPaths = ( 457 | ); 458 | runOnlyForDeploymentPostprocessing = 0; 459 | shellPath = /bin/sh; 460 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PodTest/Pods-PodTest-resources.sh\"\n"; 461 | showEnvVarsInLog = 0; 462 | }; 463 | 81752033136F7B506FBEE77B /* [CP] Copy Pods Resources */ = { 464 | isa = PBXShellScriptBuildPhase; 465 | buildActionMask = 2147483647; 466 | files = ( 467 | ); 468 | inputPaths = ( 469 | ); 470 | name = "[CP] Copy Pods Resources"; 471 | outputPaths = ( 472 | ); 473 | runOnlyForDeploymentPostprocessing = 0; 474 | shellPath = /bin/sh; 475 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RealmS/Pods-RealmS-resources.sh\"\n"; 476 | showEnvVarsInLog = 0; 477 | }; 478 | 9040D4B90C07C73F843479D9 /* [CP] Check Pods Manifest.lock */ = { 479 | isa = PBXShellScriptBuildPhase; 480 | buildActionMask = 2147483647; 481 | files = ( 482 | ); 483 | inputPaths = ( 484 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 485 | "${PODS_ROOT}/Manifest.lock", 486 | ); 487 | name = "[CP] Check Pods Manifest.lock"; 488 | outputPaths = ( 489 | "$(DERIVED_FILE_DIR)/Pods-Tests-checkManifestLockResult.txt", 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | shellPath = /bin/sh; 493 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 494 | showEnvVarsInLog = 0; 495 | }; 496 | B2458F19756614F90428111E /* [CP] Embed Pods Frameworks */ = { 497 | isa = PBXShellScriptBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | ); 501 | inputPaths = ( 502 | "${SRCROOT}/Pods/Target Support Files/Pods-PodTest/Pods-PodTest-frameworks.sh", 503 | "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", 504 | "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", 505 | "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", 506 | "${BUILT_PRODUCTS_DIR}/RealmS/RealmS.framework", 507 | ); 508 | name = "[CP] Embed Pods Frameworks"; 509 | outputPaths = ( 510 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", 511 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", 512 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", 513 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmS.framework", 514 | ); 515 | runOnlyForDeploymentPostprocessing = 0; 516 | shellPath = /bin/sh; 517 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PodTest/Pods-PodTest-frameworks.sh\"\n"; 518 | showEnvVarsInLog = 0; 519 | }; 520 | CC1B497784E5F23784E71835 /* [CP] Copy Pods Resources */ = { 521 | isa = PBXShellScriptBuildPhase; 522 | buildActionMask = 2147483647; 523 | files = ( 524 | ); 525 | inputPaths = ( 526 | ); 527 | name = "[CP] Copy Pods Resources"; 528 | outputPaths = ( 529 | ); 530 | runOnlyForDeploymentPostprocessing = 0; 531 | shellPath = /bin/sh; 532 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n"; 533 | showEnvVarsInLog = 0; 534 | }; 535 | ECEBF5821CA285D90025CB91 /* SwiftLint */ = { 536 | isa = PBXShellScriptBuildPhase; 537 | buildActionMask = 2147483647; 538 | files = ( 539 | ); 540 | inputPaths = ( 541 | ); 542 | name = SwiftLint; 543 | outputPaths = ( 544 | ); 545 | runOnlyForDeploymentPostprocessing = 0; 546 | shellPath = /bin/sh; 547 | shellScript = "if [[ \"$CI\" == 'true' ]]; then\n exit 0\nfi\n\nif [[ -s \"${PODS_ROOT}/SwiftLint/swiftlint\" ]]; then\n echo 'Linting...'\n \"${PODS_ROOT}/SwiftLint/swiftlint\"\nelse\n echo 'error: SwiftLint not installed, please read README first.'\n exit 1\nfi\n"; 548 | }; 549 | /* End PBXShellScriptBuildPhase section */ 550 | 551 | /* Begin PBXSourcesBuildPhase section */ 552 | EC11DD051DB0BA330008E58B /* Sources */ = { 553 | isa = PBXSourcesBuildPhase; 554 | buildActionMask = 2147483647; 555 | files = ( 556 | ECD21E351DB12028009757A6 /* Tests.swift in Sources */, 557 | ECD21E371DB12B68009757A6 /* CleanUp.swift in Sources */, 558 | ECD21E361DB12B65009757A6 /* Model.swift in Sources */, 559 | EC9091361ECC299900FEC9BE /* Utils.m in Sources */, 560 | ); 561 | runOnlyForDeploymentPostprocessing = 0; 562 | }; 563 | ECBAE7C01DB779CD00E520CE /* Sources */ = { 564 | isa = PBXSourcesBuildPhase; 565 | buildActionMask = 2147483647; 566 | files = ( 567 | ECBAE7C91DB779CD00E520CE /* ViewController.swift in Sources */, 568 | ECBAE7C71DB779CD00E520CE /* AppDelegate.swift in Sources */, 569 | ); 570 | runOnlyForDeploymentPostprocessing = 0; 571 | }; 572 | F401DF3B1C42A8F800870925 /* Sources */ = { 573 | isa = PBXSourcesBuildPhase; 574 | buildActionMask = 2147483647; 575 | files = ( 576 | ECBAE7BC1DB7796400E520CE /* CleanUp.swift in Sources */, 577 | ECB592931EB03BC600ACB99F /* Operator.swift in Sources */, 578 | ECBAE7BF1DB7796400E520CE /* RealmS.swift in Sources */, 579 | ECB592951EB03C0000ACB99F /* Transform.swift in Sources */, 580 | ECBAE7BE1DB7796400E520CE /* Mapping.swift in Sources */, 581 | ); 582 | runOnlyForDeploymentPostprocessing = 0; 583 | }; 584 | /* End PBXSourcesBuildPhase section */ 585 | 586 | /* Begin PBXTargetDependency section */ 587 | EC11DD101DB0BA340008E58B /* PBXTargetDependency */ = { 588 | isa = PBXTargetDependency; 589 | target = F401DF3F1C42A8F800870925 /* RealmS */; 590 | targetProxy = EC11DD0F1DB0BA340008E58B /* PBXContainerItemProxy */; 591 | }; 592 | ECE5D8A51DB875E400193DD5 /* PBXTargetDependency */ = { 593 | isa = PBXTargetDependency; 594 | target = F401DF3F1C42A8F800870925 /* RealmS */; 595 | targetProxy = ECE5D8A41DB875E400193DD5 /* PBXContainerItemProxy */; 596 | }; 597 | /* End PBXTargetDependency section */ 598 | 599 | /* Begin PBXVariantGroup section */ 600 | ECBAE7CA1DB779CD00E520CE /* Main.storyboard */ = { 601 | isa = PBXVariantGroup; 602 | children = ( 603 | ECBAE7CB1DB779CD00E520CE /* Base */, 604 | ); 605 | name = Main.storyboard; 606 | sourceTree = ""; 607 | }; 608 | ECBAE7CF1DB779CD00E520CE /* LaunchScreen.storyboard */ = { 609 | isa = PBXVariantGroup; 610 | children = ( 611 | ECBAE7D01DB779CD00E520CE /* Base */, 612 | ); 613 | name = LaunchScreen.storyboard; 614 | sourceTree = ""; 615 | }; 616 | /* End PBXVariantGroup section */ 617 | 618 | /* Begin XCBuildConfiguration section */ 619 | EC11DD121DB0BA340008E58B /* Debug */ = { 620 | isa = XCBuildConfiguration; 621 | baseConfigurationReference = C6307F11B2CE078533D25E6F /* Pods-Tests.debug.xcconfig */; 622 | buildSettings = { 623 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 624 | CLANG_ANALYZER_NONNULL = YES; 625 | CLANG_ENABLE_MODULES = YES; 626 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 627 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 628 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 629 | INFOPLIST_FILE = Tests/Supports/Info.plist; 630 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 631 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 632 | PRODUCT_BUNDLE_IDENTIFIER = vn.asiantech.Tests; 633 | PRODUCT_NAME = "$(TARGET_NAME)"; 634 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 635 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/Supports/Tests-Bridging-Header.h"; 636 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 637 | SWIFT_VERSION = 4.0; 638 | }; 639 | name = Debug; 640 | }; 641 | EC11DD131DB0BA340008E58B /* Release */ = { 642 | isa = XCBuildConfiguration; 643 | baseConfigurationReference = 231EE0BCCC5BD965713E1CE6 /* Pods-Tests.release.xcconfig */; 644 | buildSettings = { 645 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 646 | CLANG_ANALYZER_NONNULL = YES; 647 | CLANG_ENABLE_MODULES = YES; 648 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 649 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 650 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 651 | INFOPLIST_FILE = Tests/Supports/Info.plist; 652 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 653 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 654 | PRODUCT_BUNDLE_IDENTIFIER = vn.asiantech.Tests; 655 | PRODUCT_NAME = "$(TARGET_NAME)"; 656 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/Supports/Tests-Bridging-Header.h"; 657 | SWIFT_VERSION = 4.0; 658 | }; 659 | name = Release; 660 | }; 661 | ECBAE7D41DB779CD00E520CE /* Debug */ = { 662 | isa = XCBuildConfiguration; 663 | baseConfigurationReference = 363EEB1CDB9D9D2D071DAE30 /* Pods-PodTest.debug.xcconfig */; 664 | buildSettings = { 665 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 666 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 667 | CLANG_ANALYZER_NONNULL = YES; 668 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 669 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 670 | INFOPLIST_FILE = PodTest/Info.plist; 671 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 672 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 673 | PRODUCT_BUNDLE_IDENTIFIER = vn.asiantech.PodTest; 674 | PRODUCT_NAME = "$(TARGET_NAME)"; 675 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 676 | SWIFT_VERSION = 4.0; 677 | }; 678 | name = Debug; 679 | }; 680 | ECBAE7D51DB779CD00E520CE /* Release */ = { 681 | isa = XCBuildConfiguration; 682 | baseConfigurationReference = 358FDA7A52E35590DE467242 /* Pods-PodTest.release.xcconfig */; 683 | buildSettings = { 684 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 685 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 686 | CLANG_ANALYZER_NONNULL = YES; 687 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 688 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 689 | INFOPLIST_FILE = PodTest/Info.plist; 690 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 691 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 692 | PRODUCT_BUNDLE_IDENTIFIER = vn.asiantech.PodTest; 693 | PRODUCT_NAME = "$(TARGET_NAME)"; 694 | SWIFT_VERSION = 4.0; 695 | }; 696 | name = Release; 697 | }; 698 | F401DF461C42A8F800870925 /* Debug */ = { 699 | isa = XCBuildConfiguration; 700 | buildSettings = { 701 | ALWAYS_SEARCH_USER_PATHS = NO; 702 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 703 | CLANG_CXX_LIBRARY = "libc++"; 704 | CLANG_ENABLE_CODE_COVERAGE = YES; 705 | CLANG_ENABLE_MODULES = YES; 706 | CLANG_ENABLE_OBJC_ARC = YES; 707 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 708 | CLANG_WARN_BOOL_CONVERSION = YES; 709 | CLANG_WARN_COMMA = YES; 710 | CLANG_WARN_CONSTANT_CONVERSION = YES; 711 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 712 | CLANG_WARN_EMPTY_BODY = YES; 713 | CLANG_WARN_ENUM_CONVERSION = YES; 714 | CLANG_WARN_INFINITE_RECURSION = YES; 715 | CLANG_WARN_INT_CONVERSION = YES; 716 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 717 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 718 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 719 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 720 | CLANG_WARN_STRICT_PROTOTYPES = YES; 721 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 722 | CLANG_WARN_UNREACHABLE_CODE = YES; 723 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 724 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 725 | COPY_PHASE_STRIP = NO; 726 | CURRENT_PROJECT_VERSION = 1; 727 | DEBUG_INFORMATION_FORMAT = dwarf; 728 | ENABLE_STRICT_OBJC_MSGSEND = YES; 729 | ENABLE_TESTABILITY = YES; 730 | GCC_C_LANGUAGE_STANDARD = gnu99; 731 | GCC_DYNAMIC_NO_PIC = NO; 732 | GCC_NO_COMMON_BLOCKS = YES; 733 | GCC_OPTIMIZATION_LEVEL = 0; 734 | GCC_PREPROCESSOR_DEFINITIONS = ( 735 | "DEBUG=1", 736 | "$(inherited)", 737 | ); 738 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 739 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 740 | GCC_WARN_UNDECLARED_SELECTOR = YES; 741 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 742 | GCC_WARN_UNUSED_FUNCTION = YES; 743 | GCC_WARN_UNUSED_VARIABLE = YES; 744 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 745 | MTL_ENABLE_DEBUG_INFO = YES; 746 | ONLY_ACTIVE_ARCH = YES; 747 | SDKROOT = iphoneos; 748 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 749 | SWIFT_VERSION = 3.0; 750 | TARGETED_DEVICE_FAMILY = "1,2"; 751 | VERSIONING_SYSTEM = "apple-generic"; 752 | VERSION_INFO_PREFIX = ""; 753 | }; 754 | name = Debug; 755 | }; 756 | F401DF471C42A8F800870925 /* Release */ = { 757 | isa = XCBuildConfiguration; 758 | buildSettings = { 759 | ALWAYS_SEARCH_USER_PATHS = NO; 760 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 761 | CLANG_CXX_LIBRARY = "libc++"; 762 | CLANG_ENABLE_CODE_COVERAGE = YES; 763 | CLANG_ENABLE_MODULES = YES; 764 | CLANG_ENABLE_OBJC_ARC = YES; 765 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 766 | CLANG_WARN_BOOL_CONVERSION = YES; 767 | CLANG_WARN_COMMA = YES; 768 | CLANG_WARN_CONSTANT_CONVERSION = YES; 769 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 770 | CLANG_WARN_EMPTY_BODY = YES; 771 | CLANG_WARN_ENUM_CONVERSION = YES; 772 | CLANG_WARN_INFINITE_RECURSION = YES; 773 | CLANG_WARN_INT_CONVERSION = YES; 774 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 775 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 776 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 777 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 778 | CLANG_WARN_STRICT_PROTOTYPES = YES; 779 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 780 | CLANG_WARN_UNREACHABLE_CODE = YES; 781 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 782 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 783 | COPY_PHASE_STRIP = NO; 784 | CURRENT_PROJECT_VERSION = 1; 785 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 786 | ENABLE_NS_ASSERTIONS = NO; 787 | ENABLE_STRICT_OBJC_MSGSEND = YES; 788 | GCC_C_LANGUAGE_STANDARD = gnu99; 789 | GCC_NO_COMMON_BLOCKS = YES; 790 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 791 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 792 | GCC_WARN_UNDECLARED_SELECTOR = YES; 793 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 794 | GCC_WARN_UNUSED_FUNCTION = YES; 795 | GCC_WARN_UNUSED_VARIABLE = YES; 796 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 797 | MTL_ENABLE_DEBUG_INFO = NO; 798 | SDKROOT = iphoneos; 799 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 800 | SWIFT_VERSION = 3.0; 801 | TARGETED_DEVICE_FAMILY = "1,2"; 802 | VALIDATE_PRODUCT = YES; 803 | VERSIONING_SYSTEM = "apple-generic"; 804 | VERSION_INFO_PREFIX = ""; 805 | }; 806 | name = Release; 807 | }; 808 | F401DF491C42A8F800870925 /* Debug */ = { 809 | isa = XCBuildConfiguration; 810 | baseConfigurationReference = 3E4385BDC9CA20D8FBF7C965 /* Pods-RealmS.debug.xcconfig */; 811 | buildSettings = { 812 | CLANG_ENABLE_MODULES = YES; 813 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 814 | DEFINES_MODULE = YES; 815 | DYLIB_COMPATIBILITY_VERSION = 1; 816 | DYLIB_CURRENT_VERSION = 1; 817 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 818 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 819 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 820 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 821 | PRODUCT_BUNDLE_IDENTIFIER = com.zendobk.RealmS; 822 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 823 | PRODUCT_NAME = "$(TARGET_NAME)"; 824 | SKIP_INSTALL = YES; 825 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 826 | SWIFT_VERSION = 4.0; 827 | }; 828 | name = Debug; 829 | }; 830 | F401DF4A1C42A8F800870925 /* Release */ = { 831 | isa = XCBuildConfiguration; 832 | baseConfigurationReference = BC763CD81CE6CE556D690C9F /* Pods-RealmS.release.xcconfig */; 833 | buildSettings = { 834 | CLANG_ENABLE_MODULES = YES; 835 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 836 | DEFINES_MODULE = YES; 837 | DYLIB_COMPATIBILITY_VERSION = 1; 838 | DYLIB_CURRENT_VERSION = 1; 839 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 840 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; 841 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 842 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 843 | PRODUCT_BUNDLE_IDENTIFIER = com.zendobk.RealmS; 844 | PRODUCT_MODULE_NAME = "$(PRODUCT_NAME:c99extidentifier)"; 845 | PRODUCT_NAME = "$(TARGET_NAME)"; 846 | SKIP_INSTALL = YES; 847 | SWIFT_VERSION = 4.0; 848 | }; 849 | name = Release; 850 | }; 851 | /* End XCBuildConfiguration section */ 852 | 853 | /* Begin XCConfigurationList section */ 854 | EC11DD111DB0BA340008E58B /* Build configuration list for PBXNativeTarget "Tests" */ = { 855 | isa = XCConfigurationList; 856 | buildConfigurations = ( 857 | EC11DD121DB0BA340008E58B /* Debug */, 858 | EC11DD131DB0BA340008E58B /* Release */, 859 | ); 860 | defaultConfigurationIsVisible = 0; 861 | defaultConfigurationName = Release; 862 | }; 863 | ECBAE7D31DB779CD00E520CE /* Build configuration list for PBXNativeTarget "PodTest" */ = { 864 | isa = XCConfigurationList; 865 | buildConfigurations = ( 866 | ECBAE7D41DB779CD00E520CE /* Debug */, 867 | ECBAE7D51DB779CD00E520CE /* Release */, 868 | ); 869 | defaultConfigurationIsVisible = 0; 870 | defaultConfigurationName = Release; 871 | }; 872 | F401DF3A1C42A8F800870925 /* Build configuration list for PBXProject "RealmS" */ = { 873 | isa = XCConfigurationList; 874 | buildConfigurations = ( 875 | F401DF461C42A8F800870925 /* Debug */, 876 | F401DF471C42A8F800870925 /* Release */, 877 | ); 878 | defaultConfigurationIsVisible = 0; 879 | defaultConfigurationName = Release; 880 | }; 881 | F401DF481C42A8F800870925 /* Build configuration list for PBXNativeTarget "RealmS" */ = { 882 | isa = XCConfigurationList; 883 | buildConfigurations = ( 884 | F401DF491C42A8F800870925 /* Debug */, 885 | F401DF4A1C42A8F800870925 /* Release */, 886 | ); 887 | defaultConfigurationIsVisible = 0; 888 | defaultConfigurationName = Release; 889 | }; 890 | /* End XCConfigurationList section */ 891 | }; 892 | rootObject = F401DF371C42A8F800870925 /* Project object */; 893 | } 894 | -------------------------------------------------------------------------------- /RealmS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RealmS.xcodeproj/xcshareddata/xcschemes/PodTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 68 | 74 | 75 | 76 | 77 | 81 | 82 | 83 | 84 | 85 | 86 | 92 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /RealmS.xcodeproj/xcshareddata/xcschemes/RealmS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 49 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 81 | 82 | 88 | 89 | 90 | 91 | 95 | 96 | 97 | 98 | 99 | 100 | 106 | 107 | 113 | 114 | 115 | 116 | 118 | 119 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /RealmS.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 16 | 17 | 19 | 25 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 38 | 39 | 40 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 67 | 68 | 70 | 71 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /RealmS.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sources/CleanUp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CleanUp.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 5/24/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | 11 | extension Object { 12 | /** 13 | The relatived types need to perform the cleanup after this type commit a deletion. 14 | - returns: relatived types need to perform the cleanup. 15 | */ 16 | @objc open class func relativedTypes() -> [Object.Type] { return [] } 17 | 18 | /// Delete unnecessary, invalid objects... This function will be invoked after the commitWrite() called. 19 | @objc open class func clean() { } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 4.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Sources/Mapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealmMapper.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 1/12/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | import ObjectMapper 11 | 12 | // MARK: - Main 13 | extension RealmS { 14 | 15 | // MARK: Map 16 | 17 | /** 18 | Import JSON as BaseMappable Object. 19 | - parammeter T: BaseMappable Object. 20 | - parameter type: mapped type. 21 | - parameter json: JSON type is `[String: Any]`. 22 | - returns: mapped object. 23 | */ 24 | @discardableResult 25 | public func map(_ type: T.Type, json: [String: Any]) -> T? where T: BaseMappable { 26 | guard let obj = Mapper().map(JSON: json) else { 27 | return nil 28 | } 29 | if obj.realm == nil { 30 | add(obj) 31 | } 32 | return obj 33 | } 34 | 35 | /** 36 | Import JSON as array of BaseMappable Object. 37 | - parammeter T: BaseMappable Object. 38 | - parameter type: mapped type. 39 | - parameter json: JSON type is `[[String: Any]]`. 40 | - returns: mapped objects. 41 | */ 42 | @discardableResult 43 | public func map(_ type: T.Type, json: [[String: Any]]) -> [T] where T: BaseMappable { 44 | var objs = [T]() 45 | for js in json { 46 | if let obj = map(type, json: js) { 47 | objs.append(obj) 48 | } 49 | } 50 | return objs 51 | } 52 | } 53 | 54 | // MARK: - StaticMappable pre-implement 55 | extension RealmS { 56 | /** 57 | Find cached BaseMappable Object. 58 | - parammeter T: BaseMappable Object. 59 | - parameter type: object type. 60 | - parameter map: Map object contains JSON. 61 | - parameter jsPk: primary key of JSON, default is equal to `primaryKey`. 62 | - returns: cached object. 63 | */ 64 | public func object(ofType type: T.Type, forMapping map: Map, jsonPrimaryKey jsPk: String? = T.primaryKey()) -> T? where T: BaseMappable { 65 | guard let pk = T.primaryKey(), let jsPk = jsPk else { 66 | return T() 67 | } 68 | guard let id: Any = map[jsPk].value() else { return nil } 69 | if let exist = object(ofType: T.self, forPrimaryKey: id) { 70 | return exist 71 | } 72 | let new = T() 73 | new.setValue(id, forKey: pk) 74 | return new 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Sources/Operator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Operator.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 4/26/17. 6 | // Copyright © 2017 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | import ObjectMapper 11 | 12 | // MARK: - Operators 13 | 14 | /** 15 | Map to optional BaseMappable Object. 16 | - parammeter T: BaseMappable Object. 17 | - parameter left: Optional variable. 18 | - parameter right: Map object. 19 | */ 20 | public func <- (left: inout T?, right: Map) where T: BaseMappable { 21 | if right.mappingType == MappingType.fromJSON { 22 | if !right.isKeyPresent { return } 23 | guard let value = right.currentValue else { 24 | left = nil 25 | return 26 | } 27 | guard let json = value as? [String: Any], 28 | let obj = Mapper().map(JSON: json) else { return } 29 | left = obj 30 | } else { 31 | left <- (right, ObjectTransform()) 32 | } 33 | } 34 | 35 | #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0))) 36 | /** 37 | Map to implicitly unwrapped optional BaseMappable Object. 38 | - parammeter T: BaseMappable Object. 39 | - parameter left: Implicitly unwrapped optional variable. 40 | - parameter right: Map object. 41 | */ 42 | public func <- (left: inout T!, right: Map) where T: BaseMappable { 43 | var object: T? = left 44 | object <- right 45 | } 46 | #endif 47 | 48 | /** 49 | Map to List of BaseMappable Object. 50 | - parammeter T: BaseMappable Object. 51 | - parameter left: mapped variable. 52 | - parameter right: Map object. 53 | */ 54 | public func <- (left: List, right: Map) where T: BaseMappable { 55 | if right.mappingType == MappingType.fromJSON { 56 | if !right.isKeyPresent { return } 57 | left.removeAll() 58 | guard let json = right.currentValue as? [[String: Any]] else { return } 59 | let objects: [T]? = Mapper().mapArray(JSONArray: json) 60 | guard let objs = objects else { return } 61 | left.append(objectsIn: objs) 62 | } else { 63 | var _left = left 64 | _left <- (right, ListTransform()) 65 | } 66 | } 67 | 68 | // MARK: - Deprecated 69 | 70 | /** 71 | Relation must be marked as being optional or implicitly unwrapped optional. 72 | - parammeter T: BaseMappable Object. 73 | - parameter left: mapped variable. 74 | - parameter right: Map object. 75 | */ 76 | @available( *, deprecated: 1, message: "Relation must be marked as being optional or implicitly unwrapped optional.") 77 | public func <- (left: inout T, right: Map) where T: BaseMappable { 78 | assertionFailure("Deprecated: Relation must be marked as being optional or implicitly unwrapped optional.") 79 | } 80 | -------------------------------------------------------------------------------- /Sources/RealmS.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealmS.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 1/10/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | 11 | /** 12 | A `Realm` instance (also referred to as "a Realm") represents a Realm database. 13 | 14 | Realms can either be stored on disk (see `init(path:)`) or in memory (see `Configuration`). 15 | 16 | `Realm` instances are cached internally, and constructing equivalent `Realm` objects (for example, by using the same 17 | path or identifier) produces limited overhead. 18 | 19 | If you specifically want to ensure a `Realm` instance is destroyed (for example, if you wish to open a Realm, check 20 | some property, and then possibly delete the Realm file and re-open it), place the code which uses the Realm within an 21 | `autoreleasepool {}` and ensure you have no other strong references to it. 22 | 23 | - warning: `Realm` instances are not thread safe and cannot be shared across threads or dispatch queues. You must 24 | construct a new instance for each thread in which a Realm will be accessed. For dispatch queues, this means 25 | that you must construct a new instance in each block which is dispatched, as a queue is not guaranteed to 26 | run all of its blocks on the same thread. 27 | */ 28 | public final class RealmS { 29 | 30 | // MARK: Additional 31 | 32 | public enum ErrorType: Error { 33 | case write /// throwed while commit write transaction. 34 | case encrypt /// throwed by `writeCopyToURL(_:, encryptionKey:)` 35 | } 36 | 37 | public typealias ErrorHandler = (_ realm: RealmS, _ error: NSError, _ type: ErrorType) -> Void 38 | 39 | private static var handleError: ErrorHandler? 40 | 41 | /** 42 | Invoked after RealmS catched an exception. 43 | - parameter handler: Error handler block. 44 | */ 45 | public static func onError(_ handler: @escaping ErrorHandler) { 46 | handleError = handler 47 | } 48 | 49 | private var deletedTypes: [Object.Type] = [] 50 | private func clean() { 51 | while deletedTypes.count > 0 { 52 | let type = deletedTypes.removeFirst() 53 | for relatived in type.relativedTypes() { 54 | relatived.clean() 55 | } 56 | } 57 | } 58 | 59 | // MARK: Properties 60 | 61 | /// The `Schema` used by the Realm. 62 | public var schema: Schema { return realm.schema } 63 | 64 | /// The `Configuration` value that was used to create the `Realm` instance. 65 | public var configuration: Realm.Configuration { return realm.configuration } 66 | 67 | /// Indicates if the Realm contains any objects. 68 | public var isEmpty: Bool { return realm.isEmpty } 69 | 70 | // MARK: Initializers 71 | 72 | /** 73 | Obtains an instance of the default Realm. 74 | 75 | The default Realm is persisted as *default.realm* under the *Documents* directory of your Application on iOS, and 76 | in your application's *Application Support* directory on OS X. 77 | 78 | The default Realm is created using the default `Configuration`, which can be changed by setting the 79 | `Realm.Configuration.defaultConfiguration` property to a new value. 80 | 81 | - throws: An `NSError` if the Realm could not be initialized. 82 | */ 83 | public convenience init() { 84 | do { 85 | let realm = try Realm() 86 | self.init(realm) 87 | } catch { 88 | fatalError(error.localizedDescription) 89 | } 90 | } 91 | 92 | /** 93 | Obtains a `Realm` instance with the given configuration. 94 | 95 | - parameter configuration: A configuration value to use when creating the Realm. 96 | 97 | - throws: An `NSError` if the Realm could not be initialized. 98 | */ 99 | public convenience init(configuration: Realm.Configuration) { 100 | do { 101 | let realm = try Realm(configuration: configuration) 102 | self.init(realm) 103 | } catch { 104 | fatalError(error.localizedDescription) 105 | } 106 | } 107 | 108 | /** 109 | Obtains a `Realm` instance persisted at a specified file URL. 110 | 111 | - parameter fileURL: The local URL of the file the Realm should be saved at. 112 | 113 | - throws: An `NSError` if the Realm could not be initialized. 114 | */ 115 | public convenience init!(fileURL: URL) { 116 | var configuration = Realm.Configuration.defaultConfiguration 117 | configuration.fileURL = fileURL 118 | self.init(configuration: configuration) 119 | } 120 | 121 | // MARK: Transactions 122 | 123 | /** 124 | Performs actions contained within the given block inside a write transaction. 125 | 126 | If the block throws an error, the transaction will be canceled, reverting any writes made in the block before the 127 | error was thrown. 128 | 129 | Write transactions cannot be nested, and trying to execute a write transaction on a Realm which is already 130 | participating in a write transaction will throw an error. Calls to `write` from `Realm` instances in other threads 131 | will block until the current write transaction completes. 132 | 133 | Before executing the write transaction, `write` updates the `Realm` instance to the latest Realm version, as if 134 | `refresh()` had been called, and generates notifications if applicable. This has no effect if the Realm was already 135 | up to date. 136 | 137 | - parameter block: The block containing actions to perform. 138 | 139 | - throws: An `NSError` if the transaction could not be completed successfully. 140 | If `block` throws, the function throws the propagated `ErrorType` instead. 141 | */ 142 | public func write(_ block: (() throws -> Void)) { 143 | do { 144 | try realm.write(block) 145 | clean() 146 | } catch { 147 | RealmS.handleError?(self, error as NSError, .write) 148 | } 149 | } 150 | 151 | /** 152 | Begins a write transaction on the Realm. 153 | 154 | Only one write transaction can be open at a time. Write transactions cannot be nested, and trying to begin a write 155 | transaction on a Realm which is already in a write transaction will throw an error. Calls to `beginWrite` from 156 | `Realm` instances in other threads will block until the current write transaction completes. 157 | 158 | Before beginning the write transaction, `beginWrite` updates the `Realm` instance to the latest Realm version, as 159 | if `refresh()` had been called, and generates notifications if applicable. This has no effect if the Realm was 160 | already up to date. 161 | 162 | It is rarely a good idea to have write transactions span multiple cycles of the run loop, but if you do wish to do 163 | so you will need to ensure that the Realm in the write transaction is kept alive until the write transaction is 164 | committed. 165 | */ 166 | public func beginWrite() { 167 | realm.beginWrite() 168 | } 169 | 170 | /** 171 | Commits all write operations in the current write transaction, and ends the transaction. 172 | 173 | - warning: This method may only be called during a write transaction. 174 | 175 | - throws: An `NSError` if the transaction could not be written. 176 | */ 177 | public func commitWrite() { 178 | do { 179 | try realm.commitWrite() 180 | clean() 181 | } catch { 182 | RealmS.handleError?(self, error as NSError, .write) 183 | } 184 | } 185 | 186 | /** 187 | Reverts all writes made in the current write transaction and ends the transaction. 188 | 189 | This rolls back all objects in the Realm to the state they were in at the beginning of the write transaction, and 190 | then ends the transaction. 191 | 192 | This restores the data for deleted objects, but does not revive invalidated object instances. Any `Object`s which 193 | were added to the Realm will be invalidated rather than becoming unmanaged. 194 | 195 | Given the following code: 196 | 197 | ```swift 198 | let oldObject = objects(ObjectType).first! 199 | let newObject = ObjectType() 200 | 201 | realm.beginWrite() 202 | realm.add(newObject) 203 | realm.delete(oldObject) 204 | realm.cancelWrite() 205 | ``` 206 | 207 | Both `oldObject` and `newObject` will return `true` for `isInvalidated`, but re-running the query which provided 208 | `oldObject` will once again return the valid object. 209 | 210 | - warning: This method may only be called during a write transaction. 211 | */ 212 | public func cancelWrite() { 213 | realm.cancelWrite() 214 | } 215 | 216 | /** 217 | Indicates whether the Realm is currently in a write transaction. 218 | 219 | - warning: Do not simply check this property and then start a write transaction whenever an object needs to be 220 | created, updated, or removed. Doing so might cause a large number of write transactions to be created, 221 | degrading performance. Instead, always prefer performing multiple updates during a single transaction. 222 | */ 223 | public var isInWriteTransaction: Bool { 224 | return realm.isInWriteTransaction 225 | } 226 | 227 | // MARK: Adding and Creating objects 228 | 229 | /** 230 | Adds or updates an existing object into the Realm. 231 | 232 | Only pass `true` to `update` if the object has a primary key. If no objects exist in the Realm with the same 233 | primary key value, the object is inserted. Otherwise, the existing object is updated with any changed values. 234 | 235 | When added, all child relationships referenced by this object will also be added to the Realm if they are not 236 | already in it. If the object or any related objects are already being managed by a different Realm an error will be 237 | thrown. Instead, use one of the `create` functions to insert a copy of a managed object into a different Realm. 238 | 239 | The object to be added must be valid and cannot have been previously deleted from a Realm (i.e. `isInvalidated` 240 | must be `false`). 241 | 242 | - parameter object: The object to be added to this Realm. 243 | - parameter update: If `true`, the Realm will try to find an existing copy of the object (with the same primary 244 | key), and update it. Otherwise, the object will be added. 245 | */ 246 | public func add(_ object: T) { 247 | let update = T.primaryKey() != nil 248 | realm.add(object, update: update) 249 | } 250 | 251 | /** 252 | Adds or updates all the objects in a collection into the Realm. 253 | 254 | - see: `add(_:update:)` 255 | 256 | - warning: This method may only be called during a write transaction. 257 | 258 | - parameter objects: A sequence which contains objects to be added to the Realm. 259 | - parameter update: If `true`, objects that are already in the Realm will be updated instead of added anew. 260 | */ 261 | public func add(_ objects: S) where S.Iterator.Element: Object { 262 | typealias Element = S.Iterator.Element 263 | let update = Element.primaryKey() != nil 264 | for obj in objects { 265 | realm.add(obj, update: update) 266 | } 267 | } 268 | 269 | /** 270 | Creates or updates a Realm object with a given value, adding it to the Realm and returning it. 271 | 272 | Only pass `true` to `update` if the object has a primary key. If no objects exist in 273 | the Realm with the same primary key value, the object is inserted. Otherwise, 274 | the existing object is updated with any changed values. 275 | 276 | The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods 277 | in `NSJSONSerialization`, or an `Array` containing one element for each managed property. An exception will be 278 | thrown if any required properties are not present and those properties were not defined with default values. Do not 279 | pass in a `LinkingObjects` instance, either by itself or as a member of a collection. 280 | 281 | When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as 282 | the properties defined in the model. 283 | 284 | - warning: This method may only be called during a write transaction. 285 | 286 | - parameter type: The type of the object to create. 287 | - parameter value: The value used to populate the object. 288 | - parameter update: If `true`, the Realm will try to find an existing copy of the object (with the same primary 289 | key), and update it. Otherwise, the object will be added. 290 | 291 | - returns: The newly created object. 292 | */ 293 | @discardableResult 294 | public func create(_ type: T.Type, value: Any = [:]) -> T { 295 | let typeName = (type as Object.Type).className() 296 | let update = schema[typeName]?.primaryKeyProperty != nil 297 | return realm.create(type, value: value, update: update) 298 | } 299 | 300 | /** 301 | This method is useful only in specialized circumstances, for example, when building 302 | components that integrate with Realm. If you are simply building an app on Realm, it is 303 | recommended to use the typed method `create(_:value:update:)`. 304 | 305 | Creates or updates an object with the given class name and adds it to the `Realm`, populating 306 | the object with the given value. 307 | 308 | When 'update' is 'true', the object must have a primary key. If no objects exist in 309 | the Realm instance with the same primary key value, the object is inserted. Otherwise, 310 | the existing object is updated with any changed values. 311 | 312 | The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or 313 | dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing one element for each 314 | managed property. An exception will be thrown if any required properties are not present and those properties were 315 | not defined with default values. 316 | 317 | When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as 318 | the properties defined in the model. 319 | 320 | - warning: This method can only be called during a write transaction. 321 | 322 | - parameter className: The class name of the object to create. 323 | - parameter value: The value used to populate the object. 324 | - parameter update: If true will try to update existing objects with the same primary key. 325 | 326 | - returns: The created object. 327 | 328 | :nodoc: 329 | */ 330 | @discardableResult 331 | public func dynamicCreate(_ typeName: String, value: Any = [:]) -> DynamicObject! { 332 | let update = schema[typeName]?.primaryKeyProperty != nil 333 | return realm.dynamicCreate(typeName, value: value, update: update) 334 | } 335 | 336 | // MARK: Deleting objects 337 | 338 | /** 339 | Deletes an object from the Realm. Once the object is deleted it is considered invalidated. 340 | 341 | - warning: This method may only be called during a write transaction. 342 | 343 | - parameter object: The object to be deleted. 344 | */ 345 | public func delete(_ object: T) { 346 | realm.delete(object) 347 | deletedTypes.append(T.self) 348 | } 349 | 350 | /** 351 | Deletes zero or more objects from the Realm. 352 | 353 | - warning: This method may only be called during a write transaction. 354 | 355 | - parameter objects: The objects to be deleted. This can be a `List`, `Results`, or any other 356 | Swift `Sequence` whose elements are `Object`s. 357 | */ 358 | public func delete(_ objects: S) where S.Iterator.Element: Object { 359 | realm.delete(objects) 360 | let type = S.Iterator.Element.self 361 | deletedTypes.append(type) 362 | } 363 | 364 | /** 365 | Deletes zero or more objects from the Realm. 366 | 367 | - warning: This method may only be called during a write transaction. 368 | 369 | - parameter objects: A list of objects to delete. 370 | 371 | :nodoc: 372 | */ 373 | public func delete(_ objects: List) { 374 | realm.delete(objects) 375 | deletedTypes.append(T.self) 376 | } 377 | 378 | /** 379 | Deletes zero or more objects from the Realm. 380 | 381 | - warning: This method may only be called during a write transaction. 382 | 383 | - parameter objects: A `Results` containing the objects to be deleted. 384 | 385 | :nodoc: 386 | */ 387 | public func delete(_ objects: Results) { 388 | realm.delete(objects) 389 | deletedTypes.append(T.self) 390 | } 391 | 392 | /** 393 | Returns all objects of the given type stored in the Realm. 394 | 395 | - parameter type: The type of the objects to be returned. 396 | 397 | - returns: A `Results` containing the objects. 398 | */ 399 | public func deleteAll() { 400 | realm.deleteAll() 401 | } 402 | 403 | // MARK: Object Retrieval 404 | 405 | /** 406 | Returns all objects of the given type stored in the Realm. 407 | 408 | - parameter type: The type of the objects to be returned. 409 | 410 | - returns: A `Results` containing the objects. 411 | */ 412 | public func objects(_ type: T.Type) -> Results { 413 | return realm.objects(type) 414 | } 415 | 416 | /** 417 | This method is useful only in specialized circumstances, for example, when building 418 | components that integrate with Realm. If you are simply building an app on Realm, it is 419 | recommended to use the typed method `objects(type:)`. 420 | 421 | Returns all objects for a given class name in the Realm. 422 | 423 | - parameter typeName: The class name of the objects to be returned. 424 | - returns: All objects for the given class name as dynamic objects 425 | 426 | :nodoc: 427 | */ 428 | public func dynamicObjects(_ typeName: String) -> Results { 429 | return realm.dynamicObjects(typeName) 430 | } 431 | 432 | /** 433 | Retrieves the single instance of a given object type with the given primary key from the Realm. 434 | 435 | This method requires that `primaryKey()` be overridden on the given object class. 436 | 437 | - see: `Object.primaryKey()` 438 | 439 | - parameter type: The type of the object to be returned. 440 | - parameter key: The primary key of the desired object. 441 | 442 | - returns: An object of type `type`, or `nil` if no instance with the given primary key exists. 443 | */ 444 | public func object(ofType type: T.Type, forPrimaryKey key: K) -> T? { 445 | return realm.object(ofType: type, forPrimaryKey: key) 446 | } 447 | 448 | /** 449 | This method is useful only in specialized circumstances, for example, when building 450 | components that integrate with Realm. If you are simply building an app on Realm, it is 451 | recommended to use the typed method `objectForPrimaryKey(_:key:)`. 452 | 453 | Get a dynamic object with the given class name and primary key. 454 | 455 | Returns `nil` if no object exists with the given class name and primary key. 456 | 457 | This method requires that `primaryKey()` be overridden on the given subclass. 458 | 459 | - see: Object.primaryKey() 460 | 461 | - warning: This method is useful only in specialized circumstances. 462 | 463 | - parameter className: The class name of the object to be returned. 464 | - parameter key: The primary key of the desired object. 465 | 466 | - returns: An object of type `DynamicObject` or `nil` if an object with the given primary key does not exist. 467 | 468 | :nodoc: 469 | */ 470 | public func dynamicObject(ofType typeName: String, forPrimaryKey key: Any) -> RealmSwift.DynamicObject? { 471 | return realm.dynamicObject(ofType: typeName, forPrimaryKey: key) 472 | } 473 | 474 | // MARK: Notifications 475 | 476 | /** 477 | Adds a notification handler for changes made to this Realm, and returns a notification token. 478 | 479 | Notification handlers are called after each write transaction is committed, independent of the thread or process. 480 | 481 | Handler blocks are called on the same thread that they were added on, and may only be added on threads which are 482 | currently within a run loop. Unless you are specifically creating and running a run loop on a background thread, 483 | this will normally only be the main thread. 484 | 485 | Notifications can't be delivered as long as the run loop is blocked by other activity. When notifications can't be 486 | delivered instantly, multiple notifications may be coalesced. 487 | 488 | You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving 489 | updates, call `invalidate()` on the token. 490 | 491 | - parameter block: A block which is called to process Realm notifications. It receives the following parameters: 492 | `notification`: the incoming notification; `realm`: the Realm for which the notification 493 | occurred. 494 | 495 | - returns: A token which must be held for as long as you wish to continue receiving change notifications. 496 | */ 497 | public func observe(_ block: @escaping NotificationBlock) -> NotificationToken { 498 | return realm.observe({ notif, _ in 499 | block(notif, self) 500 | }) 501 | } 502 | 503 | // MARK: Autorefresh and Refresh 504 | 505 | /** 506 | Set this property to `true` to automatically update this Realm when changes happen in other threads. 507 | 508 | If set to `true` (the default), changes made on other threads will be reflected in this Realm on the next cycle of 509 | the run loop after the changes are committed. If set to `false`, you must manually call `refresh()` on the Realm 510 | to update it to get the latest data. 511 | 512 | Note that by default, background threads do not have an active run loop and you will need to manually call 513 | `refresh()` in order to update to the latest version, even if `autorefresh` is set to `true`. 514 | 515 | Even with this property enabled, you can still call `refresh()` at any time to update the Realm before the 516 | automatic refresh would occur. 517 | 518 | Notifications are sent when a write transaction is committed whether or not automatic refreshing is enabled. 519 | 520 | Disabling `autorefresh` on a `Realm` without any strong references to it will not have any effect, and 521 | `autorefresh` will revert back to `true` the next time the Realm is created. This is normally irrelevant as it 522 | means that there is nothing to refresh (as managed `Object`s, `List`s, and `Results` have strong references to the 523 | `Realm` that manages them), but it means that setting `autorefresh = false` in 524 | `application(_:didFinishLaunchingWithOptions:)` and only later storing Realm objects will not work. 525 | 526 | Defaults to `true`. 527 | */ 528 | public var autorefresh: Bool { 529 | get { 530 | return realm.autorefresh 531 | } 532 | set { 533 | realm.autorefresh = newValue 534 | } 535 | } 536 | 537 | /** 538 | Updates the Realm and outstanding objects managed by the Realm to point to the most recent data. 539 | 540 | - returns: Whether there were any updates for the Realm. Note that `true` may be returned even if no data actually 541 | changed. 542 | */ 543 | @discardableResult 544 | public func refresh() -> Bool { 545 | return realm.refresh() 546 | } 547 | 548 | // MARK: Invalidation 549 | 550 | /** 551 | Invalidates all `Object`s, `Results`, `LinkingObjects`, and `List`s managed by the Realm. 552 | 553 | A Realm holds a read lock on the version of the data accessed by it, so 554 | that changes made to the Realm on different threads do not modify or delete the 555 | data seen by this Realm. Calling this method releases the read lock, 556 | allowing the space used on disk to be reused by later write transactions rather 557 | than growing the file. This method should be called before performing long 558 | blocking operations on a background thread on which you previously read data 559 | from the Realm which you no longer need. 560 | 561 | All `Object`, `Results` and `List` instances obtained from this `Realm` instance on the current thread are 562 | invalidated. `Object`s and `Array`s cannot be used. `Results` will become empty. The Realm itself remains valid, 563 | and a new read transaction is implicitly begun the next time data is read from the Realm. 564 | 565 | Calling this method multiple times in a row without reading any data from the 566 | Realm, or before ever reading any data from the Realm, is a no-op. This method 567 | may not be called on a read-only Realm. 568 | */ 569 | public func invalidate() { 570 | realm.invalidate() 571 | } 572 | 573 | // MARK: Writing a Copy 574 | 575 | /** 576 | Writes a compacted and optionally encrypted copy of the Realm to the given local URL. 577 | 578 | The destination file cannot already exist. 579 | 580 | Note that if this method is called from within a write transaction, the *current* data is written, not the data 581 | from the point when the previous write transaction was committed. 582 | 583 | - parameter fileURL: Local URL to save the Realm to. 584 | - parameter encryptionKey: Optional 64-byte encryption key to encrypt the new file with. 585 | 586 | - throws: An `NSError` if the copy could not be written. 587 | */ 588 | public func writeCopy(toFile fileURL: URL, encryptionKey: Data? = nil) { 589 | do { 590 | try realm.writeCopy(toFile: fileURL, encryptionKey: encryptionKey) 591 | } catch { 592 | RealmS.handleError?(self, error as NSError, .encrypt) 593 | } 594 | } 595 | 596 | // MARK: Internal 597 | internal var realm: Realm 598 | 599 | internal init(_ realm: Realm) { 600 | self.realm = realm 601 | } 602 | } 603 | 604 | // MARK: Equatable 605 | 606 | extension RealmS: Equatable { } 607 | 608 | /// Returns whether the two realms are equal. 609 | public func == (lhs: RealmS, rhs: RealmS) -> Bool { // swiftlint:disable:this valid_docs 610 | return lhs.realm == rhs.realm 611 | } 612 | 613 | // MARK: Notifications 614 | 615 | /// Closure to run when the data in a Realm was modified. 616 | public typealias NotificationBlock = (_ notification: Realm.Notification, _ realm: RealmS) -> Void 617 | 618 | // MARK: Unavailable 619 | 620 | extension RealmS { 621 | 622 | @available( *, unavailable, renamed: "isInWriteTransaction") 623 | public var inWriteTransaction: Bool { fatalError() } 624 | 625 | @available( *, unavailable, renamed: "object(ofType:forPrimaryKey:)") 626 | public func objectForPrimaryKey(_ type: T.Type, key: Any) -> T? { fatalError() } 627 | 628 | @available( *, unavailable, renamed: "dynamicObject(ofType:forPrimaryKey:)") 629 | public func dynamicObjectForPrimaryKey(_ className: String, key: Any) -> DynamicObject? { fatalError() } 630 | 631 | @available( *, unavailable, renamed: "writeCopy(toFile:encryptionKey:)") 632 | public func writeCopyToURL(_ fileURL: NSURL, encryptionKey: Data? = nil) throws { fatalError() } 633 | } 634 | -------------------------------------------------------------------------------- /Sources/Transform.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Transform.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 4/26/17. 6 | // Copyright © 2017 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | import ObjectMapper 11 | 12 | // MARK: - Internal 13 | 14 | /** 15 | Transform for Object, only support transform to JSON. 16 | */ 17 | internal final class ObjectTransform: TransformType where T: BaseMappable { 18 | @available( *, deprecated: 1, message: "Please use direct mapping without transform.") 19 | func transformFromJSON(_ value: Any?) -> T? { 20 | assertionFailure("Deprecated: Please use direct mapping without transform.") 21 | return nil 22 | } 23 | 24 | func transformToJSON(_ value: T?) -> Any? { 25 | guard let obj = value else { return NSNull() } 26 | var json = Mapper().toJSON(obj) 27 | if let key = T.primaryKey() { 28 | json[key] = obj.value(forKey: key) 29 | } 30 | return json 31 | } 32 | } 33 | 34 | /** 35 | Transform for List of Object, only support transform to JSON. 36 | */ 37 | internal final class ListTransform: TransformType where T: BaseMappable { 38 | @available( *, deprecated: 1, message: "Please use direct mapping without transform.") 39 | func transformFromJSON(_ value: Any?) -> List? { 40 | assertionFailure("Deprecated: Please use direct mapping without transform.") 41 | return nil 42 | } 43 | 44 | func transformToJSON(_ value: List?) -> Any? { 45 | guard let list = value else { return NSNull() } 46 | var json: [[String: Any]] = [] 47 | let mapper = Mapper() 48 | for obj in list { 49 | json.append(mapper.toJSON(obj)) 50 | } 51 | return json 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Tests/Library/Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.h 3 | // RealmS 4 | // 5 | // Created by DaoNV on 4/18/17. 6 | // Copyright © 2017 Apple Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | void DispatchOnce(void(^block)(void)); 12 | -------------------------------------------------------------------------------- /Tests/Library/Utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.m 3 | // RealmS 4 | // 5 | // Created by DaoNV on 4/18/17. 6 | // Copyright © 2017 Apple Inc. All rights reserved. 7 | // 8 | 9 | #import "Utils.h" 10 | 11 | void DispatchOnce(void(^block)(void)) { 12 | static dispatch_once_t onceToken; 13 | dispatch_once(&onceToken, ^{ 14 | block(); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /Tests/Model/CleanUp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CleanUp.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 5/24/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | import RealmS 11 | 12 | extension User { 13 | override public class func relativedTypes() -> [Object.Type] { 14 | return [Address.self, Pet.self] 15 | } 16 | 17 | override public class func clean() { } 18 | } 19 | 20 | extension Address { 21 | override class func relativedTypes() -> [Object.Type] { 22 | return [Phone.self] 23 | } 24 | 25 | override class func clean() { 26 | let realm = RealmS() 27 | let objs = realm.objects(self).filter("users.@count = 0") 28 | realm.write { 29 | realm.delete(objs) 30 | } 31 | } 32 | } 33 | 34 | extension Phone { 35 | override class func clean() { 36 | let realm = RealmS() 37 | let objs = realm.objects(self).filter("addresses.@count = 0") 38 | realm.write { 39 | realm.delete(objs) 40 | } 41 | } 42 | } 43 | 44 | extension Pet { 45 | override class func relativedTypes() -> [Object.Type] { 46 | return [Color.self] 47 | } 48 | 49 | override class func clean() { 50 | let realm = RealmS() 51 | let objs = realm.objects(self).filter("users.@count = 0") 52 | realm.write { 53 | realm.delete(objs) 54 | } 55 | } 56 | } 57 | 58 | extension Color { 59 | override class func clean() { 60 | let realm = RealmS() 61 | let objs = realm.objects(self).filter("dogs.@count = 0") 62 | realm.write { 63 | realm.delete(objs) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/Model/Model.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Model.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 3/14/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import RealmSwift 10 | import ObjectMapper 11 | import RealmS 12 | 13 | final class User: Object, StaticMappable { 14 | @objc dynamic var id = "" 15 | @objc dynamic var name: String? 16 | @objc dynamic var address: Address? 17 | let dogs = List() 18 | let cats = List() 19 | 20 | override class func primaryKey() -> String? { 21 | return "id" 22 | } 23 | 24 | func mapping(map: Map) { 25 | name <- map["name"] 26 | address <- map["address"] 27 | dogs <- map["dogs"] 28 | cats <- map["cats"] 29 | } 30 | 31 | static func objectForMapping(map: Map) -> BaseMappable? { 32 | return RealmS().object(ofType: self, forMapping: map) 33 | } 34 | } 35 | 36 | final class Address: Object, Mappable { 37 | @objc dynamic var street = "" 38 | @objc dynamic var city = "" 39 | @objc dynamic var country = "" 40 | 41 | let phones = List() 42 | 43 | let users = LinkingObjects(fromType: User.self, property: "address") 44 | 45 | convenience required init?(map: Map) { 46 | self.init() 47 | } 48 | 49 | func mapping(map: Map) { 50 | street <- map["street"] 51 | city <- map["city"] 52 | country <- map["country"] 53 | phones <- map["phones"] 54 | } 55 | } 56 | 57 | final class Phone: Object, StaticMappable { 58 | enum PhoneType: String { 59 | case work 60 | case home 61 | } 62 | 63 | @objc dynamic var number = "" 64 | @objc dynamic var type = PhoneType.home.rawValue 65 | 66 | let addresses = LinkingObjects(fromType: Address.self, property: "phones") 67 | 68 | override static func primaryKey() -> String { 69 | return "number" 70 | } 71 | 72 | func mapping(map: Map) { 73 | type <- map["type"] 74 | } 75 | 76 | static func objectForMapping(map: Map) -> BaseMappable? { 77 | return RealmS().object(ofType: self, forMapping: map) 78 | } 79 | } 80 | 81 | final class Pet: Object, StaticMappable { 82 | @objc dynamic var id = "" 83 | @objc dynamic var name: String? 84 | @objc dynamic var color: Color? 85 | 86 | let users = LinkingObjects(fromType: User.self, property: "dogs") 87 | 88 | override class func primaryKey() -> String? { 89 | return "id" 90 | } 91 | 92 | func mapping(map: Map) { 93 | name <- map["name"] 94 | color <- map["color"] 95 | } 96 | 97 | static func objectForMapping(map: Map) -> BaseMappable? { 98 | return RealmS().object(ofType: self, forMapping: map, jsonPrimaryKey: "pk") 99 | } 100 | } 101 | 102 | final class Color: Object, StaticMappable { 103 | @objc dynamic var hex: String! 104 | @objc dynamic var name: String? 105 | 106 | let dogs = LinkingObjects(fromType: Pet.self, property: "color") 107 | 108 | override class func primaryKey() -> String? { 109 | return "hex" 110 | } 111 | 112 | func mapping(map: Map) { 113 | name <- map["name"] 114 | } 115 | 116 | static func objectForMapping(map: Map) -> BaseMappable? { 117 | return RealmS().object(ofType: self, forMapping: map) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Tests/Resources/users.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": "1", 3 | "name": "User A", 4 | "address": { 5 | "street": "123 Street", 6 | "city": "City Abc", 7 | "country": "Country Q", 8 | "phones": [{ 9 | "number": "+849876543210", 10 | "type": "Work" 11 | }] 12 | }, 13 | "dogs": [{ 14 | "pk": "1", 15 | "name": "Jan", 16 | "color": { 17 | "hex": "000000", 18 | "name": "black" 19 | } 20 | }, { 21 | "pk": "2", 22 | "name": "Feb", 23 | "color": { 24 | "hex": "ffffff", 25 | "name": "white" 26 | } 27 | }], 28 | "cats": [{ 29 | "pk": "1", 30 | "name": "Jan", 31 | "color": { 32 | "hex": "000000", 33 | "name": "black" 34 | } 35 | }, { 36 | "pk": "3", 37 | "name": "Mar", 38 | "color": { 39 | "hex": "ffffff", 40 | "name": "white" 41 | } 42 | }] 43 | }, { 44 | "id": "2", 45 | "name": "User B", 46 | "address": { 47 | "street": "456 Street", 48 | "city": "City Xyz", 49 | "country": "Country W", 50 | "phones": [{ 51 | "number": "+849876543211", 52 | "type": "Work" 53 | }] 54 | }, 55 | "dogs": [{ 56 | "pk": "1", 57 | "name": "Pluto", 58 | "color": { 59 | "hex": "000000", 60 | "name": "black" 61 | } 62 | }, { 63 | "pk": "2", 64 | "name": "Gozer", 65 | "color": { 66 | "hex": "d3d3d3", 67 | "name": "gray" 68 | } 69 | }], 70 | "cats": [{ 71 | "pk": "2", 72 | "name": "Feb", 73 | "color": { 74 | "hex": "000000", 75 | "name": "black" 76 | } 77 | }, { 78 | "pk": "4", 79 | "name": "Apr", 80 | "color": { 81 | "hex": "000000", 82 | "name": "black" 83 | } 84 | }] 85 | }] 86 | -------------------------------------------------------------------------------- /Tests/Supports/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Supports/Tests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "Utils.h" 6 | -------------------------------------------------------------------------------- /Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests.swift 3 | // RealmS 4 | // 5 | // Created by DaoNV on 3/14/16. 6 | // Copyright © 2016 Apple Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import RealmSwift 11 | import ObjectMapper 12 | @testable import RealmS 13 | 14 | class Tests: XCTestCase { 15 | 16 | let jsUsers: [[String: Any]] = { 17 | guard let url = Bundle(for: Tests.self).url(forResource: "users", withExtension: "json") else { 18 | fatalError("Missing resource.") 19 | } 20 | 21 | do { 22 | let data = try Data(contentsOf: url) 23 | let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) 24 | guard let array = json as? [[String: Any]] else { 25 | fatalError("Wrong JSON format.") 26 | } 27 | return array 28 | } catch { 29 | fatalError(error.localizedDescription) 30 | } 31 | }() 32 | 33 | var jsUser: [String: Any] { 34 | let jsUser: [String: Any]! = jsUsers.first 35 | XCTAssertNotNil(jsUser) 36 | return jsUser 37 | } 38 | 39 | var userId: String { 40 | let userId: String! = jsUser["id"] as? String 41 | XCTAssertNotNil(userId) 42 | return userId 43 | } 44 | 45 | let jsPets: [[String: Any]] = [ 46 | [ 47 | "pk": "1", 48 | "name": "Pluto", 49 | "color": [ 50 | "hex": "ff0000", 51 | "name": "red new" 52 | ] 53 | ], 54 | [ 55 | "pk": "2", 56 | "name": "Lux", 57 | "color": [ 58 | "hex": "ffffff", 59 | "name": "white new" 60 | ] 61 | ] 62 | ] 63 | 64 | var jsPet: [String: Any] { 65 | let jsPet: [String: Any]! = jsPets.first 66 | XCTAssertNotNil(jsPet) 67 | return jsPet 68 | } 69 | 70 | override func setUp() { 71 | super.setUp() 72 | DispatchOnce { 73 | var config = Realm.Configuration.defaultConfiguration 74 | config.deleteRealmIfMigrationNeeded = true 75 | Realm.Configuration.defaultConfiguration = config 76 | RealmS.onError { (_, error, _) in 77 | XCTAssertThrowsError(error) 78 | } 79 | } 80 | } 81 | 82 | override func tearDown() { 83 | let realm = RealmS() 84 | if realm.isInWriteTransaction { 85 | realm.cancelWrite() 86 | } 87 | realm.write { 88 | realm.deleteAll() 89 | } 90 | super.tearDown() 91 | } 92 | 93 | func test_config() { 94 | let config = RealmS().configuration 95 | do { 96 | let origin = try Realm().configuration 97 | XCTAssertEqual(config.fileURL, origin.fileURL) 98 | } catch { 99 | XCTAssertFalse(true) 100 | } 101 | } 102 | 103 | func test_schema() { 104 | var names: [String] = [] 105 | for cls in RealmS().schema.objectSchema { 106 | names.append(cls.className) 107 | } 108 | names.sort() 109 | XCTAssertEqual(names.joined(separator: ","), "Address,Color,Pet,Phone,User") 110 | } 111 | 112 | func test_cancel() { 113 | let realm = RealmS() 114 | realm.beginWrite() 115 | XCTAssertTrue(realm.isInWriteTransaction) 116 | realm.cancelWrite() 117 | XCTAssertFalse(realm.isInWriteTransaction) 118 | } 119 | 120 | func test_commitWrite() { 121 | let realm = RealmS() 122 | realm.beginWrite() 123 | XCTAssertTrue(realm.isInWriteTransaction) 124 | realm.commitWrite() 125 | XCTAssertFalse(realm.isInWriteTransaction) 126 | } 127 | 128 | func test_map() { 129 | let realm = RealmS() 130 | realm.write { 131 | realm.map(User.self, json: jsUsers) 132 | } 133 | realm.write { 134 | realm.map(User.self, json: jsUsers) 135 | } 136 | let users = realm.objects(User.self) 137 | XCTAssertGreaterThan(users.count, 0) 138 | let dogs = realm.objects(Pet.self) 139 | XCTAssertGreaterThan(dogs.count, 0) 140 | let addrs = realm.objects(Address.self) 141 | XCTAssertGreaterThan(addrs.count, 0) 142 | let user: User! = users.filter("id = %@", userId).first 143 | XCTAssertNotNil(user) 144 | let addr: Address! = user.address 145 | XCTAssertNotNil(addr) 146 | XCTAssertGreaterThan(addr.phones.count, 0) 147 | XCTAssertGreaterThan(user.dogs.count, 0) 148 | realm.write { 149 | realm.map(User.self, json: jsUsers) 150 | } 151 | } 152 | 153 | func test_add() { 154 | var dogs: [Pet] = [] 155 | for i in 1...3 { 156 | let obj = Pet() 157 | obj.id = "\(i)" 158 | obj.name = "Pluto \(i)" 159 | let color = Color() 160 | color.hex = "ffffff" 161 | color.name = "white" 162 | obj.color = color 163 | dogs.append(obj) 164 | } 165 | let realm = RealmS() 166 | realm.write { 167 | realm.add(dogs) 168 | } 169 | XCTAssertGreaterThan(realm.objects(Pet.self).count, 0) 170 | } 171 | 172 | func test_create() { 173 | let realm = RealmS() 174 | realm.write { 175 | for jsUser in jsUsers { 176 | realm.create(User.self, value: jsUser) 177 | } 178 | } 179 | let users = realm.objects(User.self).filter("id = %@", userId) 180 | XCTAssertGreaterThan(users.count, 0) 181 | let user: User! = users.first 182 | let addr: Address! = user.address 183 | XCTAssertNotNil(addr) 184 | XCTAssertGreaterThan(addr.phones.count, 0) 185 | XCTAssertGreaterThan(user.dogs.count, 0) 186 | realm.write { 187 | realm.map(User.self, json: jsUsers) 188 | } 189 | XCTAssertGreaterThan(users.count, 0) 190 | } 191 | 192 | // Also test clean 193 | func test_delete_object() { 194 | let realm = RealmS() 195 | realm.write { 196 | realm.map(User.self, json: jsUsers) 197 | } 198 | let users = realm.objects(User.self) 199 | XCTAssertGreaterThan(users.count, 0) 200 | let user: User! = users.first 201 | realm.write { 202 | realm.delete(user) 203 | } 204 | XCTAssertGreaterThan(users.count, 0) 205 | let addrs = realm.objects(Address.self) 206 | XCTAssertGreaterThan(addrs.count, 0) 207 | let phones = realm.objects(Phone.self) 208 | XCTAssertGreaterThan(phones.count, 0) 209 | let dogs = realm.objects(Pet.self) 210 | XCTAssertGreaterThan(dogs.count, 0) 211 | } 212 | 213 | // Also test clean 214 | func test_delete_results() { 215 | let realm = RealmS() 216 | realm.write { 217 | realm.map(User.self, json: jsUsers) 218 | } 219 | let users = realm.objects(User.self) 220 | XCTAssertGreaterThan(users.count, 0) 221 | realm.write { 222 | realm.delete(users) 223 | } 224 | XCTAssertTrue(realm.isEmpty) 225 | } 226 | 227 | func test_relationChange() { 228 | let realm = RealmS() 229 | realm.write { 230 | realm.map(User.self, json: jsUsers) 231 | } 232 | let user: User! = realm.object(ofType: User.self, forPrimaryKey: userId) 233 | XCTAssertNotNil(user) 234 | let dog: Pet! = user.dogs.first 235 | XCTAssertNotNil(dog) 236 | guard let jsColor = jsPet["color"] as? [String: Any], 237 | let hex = jsColor["hex"] as? String else { 238 | XCTFail("Fail with hex color") 239 | return 240 | } 241 | realm.write { 242 | realm.map(Pet.self, json: jsPets) 243 | } 244 | XCTAssertEqual(dog.color?.hex, hex) 245 | } 246 | 247 | func test_addNilObject() { 248 | let realm = RealmS() 249 | realm.write { 250 | realm.map(User.self, json: jsUsers) 251 | } 252 | let user: User! = realm.object(ofType: User.self, forPrimaryKey: userId) 253 | XCTAssertNotNil(user) 254 | var jsUser = self.jsUser 255 | jsUser["address"] = nil 256 | realm.write { 257 | realm.map(User.self, json: jsUser) 258 | } 259 | XCTAssertNotNil(user.address) 260 | } 261 | 262 | func test_addNullObject() { 263 | let realm = RealmS() 264 | realm.write { 265 | realm.map(User.self, json: jsUsers) 266 | } 267 | let user: User! = realm.object(ofType: User.self, forPrimaryKey: userId) 268 | XCTAssertNotNil(user) 269 | var jsUser = self.jsUser 270 | jsUser["address"] = NSNull() 271 | realm.write { 272 | realm.map(User.self, json: jsUser) 273 | } 274 | XCTAssertNil(user.address) 275 | } 276 | 277 | func test_addNilList() { 278 | let realm = RealmS() 279 | realm.write { 280 | realm.map(User.self, json: jsUsers) 281 | } 282 | let user: User! = realm.object(ofType: User.self, forPrimaryKey: userId) 283 | XCTAssertNotNil(user) 284 | var jsUser = self.jsUser 285 | jsUser["dogs"] = nil 286 | realm.write { 287 | realm.map(User.self, json: jsUser) 288 | } 289 | XCTAssertGreaterThan(user.dogs.count, 0) 290 | } 291 | 292 | func test_addNullList() { 293 | let realm = RealmS() 294 | realm.write { 295 | realm.map(User.self, json: jsUsers) 296 | } 297 | let user: User! = realm.object(ofType: User.self, forPrimaryKey: userId) 298 | XCTAssertNotNil(user) 299 | var jsUser = self.jsUser 300 | jsUser["dogs"] = NSNull() 301 | realm.write { 302 | realm.map(User.self, json: jsUser) 303 | } 304 | XCTAssertTrue(user.dogs.isEmpty) 305 | } 306 | 307 | func test_multiThread() { 308 | let expect = expectation(description: "test_multiThread") 309 | let queue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default) 310 | let group = DispatchGroup() 311 | 312 | let jsUsers = self.jsUsers 313 | for _ in 0 ..< 10 { 314 | group.enter() 315 | queue.async(execute: { 316 | let realm = RealmS() 317 | realm.write { 318 | realm.map(User.self, json: jsUsers) 319 | } 320 | group.leave() 321 | }) 322 | } 323 | 324 | group.notify(queue: DispatchQueue.main) { 325 | expect.fulfill() 326 | } 327 | waitForExpectations(timeout: 10, handler: nil) 328 | } 329 | 330 | func test_notif() { 331 | let expect = expectation(description: "test_notif") 332 | let queue = DispatchQueue.global(qos: DispatchQoS.background.qosClass) 333 | 334 | let realm = RealmS() 335 | let users = realm.objects(User.self) 336 | let token = users.observe { change in 337 | switch change { 338 | case .update(_, let deletions, let insertions, let modifications): 339 | XCTAssertTrue(deletions.isEmpty) 340 | XCTAssertGreaterThan(insertions.count, 0) 341 | XCTAssertTrue(modifications.isEmpty) 342 | expect.fulfill() 343 | case .error(let error): 344 | XCTAssertThrowsError(error) 345 | default: 346 | break 347 | } 348 | } 349 | 350 | queue.async(execute: { 351 | let realm = RealmS() 352 | realm.write { 353 | realm.map(User.self, json: self.jsUsers) 354 | } 355 | }) 356 | 357 | waitForExpectations(timeout: 10, handler: nil) 358 | token.invalidate() 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /scripts/ci/codecov: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bash <(curl -s https://codecov.io/bash) 4 | -------------------------------------------------------------------------------- /scripts/ci/pr_number: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | USERNAME="${REPO_SLUG%/*}" 4 | URL="https://api.github.com/repos/$REPO_SLUG/pulls?head=$USERNAME:$SRC_BRANCH" 5 | RESULT=$(curl -X GET -u "$GITHUB_ACCESS_TOKEN":x-oauth-basic "$URL" | jq -r '.[0].url') 6 | if [[ "$RESULT" == 'null' ]]; then 7 | PR_NUMBER='' 8 | else 9 | PR_NUMBER="${RESULT//\"}" 10 | fi 11 | PR_NUMBER="$(basename "$PR_NUMBER")" 12 | echo "$PR_NUMBER" 13 | -------------------------------------------------------------------------------- /scripts/ci/src_branch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$CIRCLECI" == 'true' ]]; then 4 | echo "$CIRCLE_BRANCH" 5 | exit 0 6 | fi 7 | 8 | if [[ "$TRAVIS_PULL_REQUEST" == 'false' ]]; then 9 | echo "$TRAVIS_BRANCH" 10 | else 11 | URL="https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST" 12 | RESULT=$(curl -X GET -u "$GITHUB_ACCESS_TOKEN":x-oauth-basic "$URL" | jq -r '.head.ref') 13 | if [[ "$RESULT" == 'null' ]]; then 14 | TRAVIS_BRANCH='' 15 | else 16 | TRAVIS_BRANCH="${RESULT//\"}" 17 | fi 18 | echo "$TRAVIS_BRANCH" 19 | fi 20 | -------------------------------------------------------------------------------- /scripts/git/hooks/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | msg_file = ARGV[0] 4 | msg = File.read(msg_file) 5 | 6 | regex = /(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\s*#\d+/ 7 | 8 | if regex.match(msg) 9 | puts '[POLICY] Your commit message contains `autoclose issue` token. Please remove it. 10 | Reference: https://help.github.com/articles/closing-issues-via-commit-messages' 11 | exit 1 12 | end 13 | -------------------------------------------------------------------------------- /scripts/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # DEV ENV 4 | 5 | # update submodule if need 6 | if [[ "$CI" != 'true' ]]; then 7 | git submodule update --init --recursive 8 | mkdir -p .git/hooks 9 | yes | cp -rf scripts/git/hooks/* .git/hooks/ 10 | fi 11 | 12 | # homebrew 13 | if ! which brew > /dev/null; then 14 | sudo chown -R "$(whoami)":admin '/usr/local' 15 | /usr/bin/ruby -e "$(curl -fsSL 'https://raw.githubusercontent.com/Homebrew/install/master/install')" 16 | mkdir -p '/Library/Caches/Homebrew' 17 | sudo chown -R "$(whoami)":admin '/Library/Caches/Homebrew' 18 | fi 19 | 20 | brew update 21 | 22 | # rbenv if need 23 | if [[ "$CI" != 'true' ]]; then 24 | if ! which rbenv > /dev/null; then 25 | echo 'install rbenv' 26 | brew install rbenv 27 | eval "$(rbenv init -)" 28 | echo 'which rbenv > /dev/null && eval "$(rbenv init -)"' >> ~/.bashrc 29 | fi 30 | echo 'n' | rbenv install || true 31 | rbenv rehash 32 | fi 33 | 34 | gem install bundler 35 | 36 | # PROJECT DEPENDENCES 37 | 38 | bundle install --path=vendor/bundle --jobs 4 --retry 3 39 | 40 | brew tap Homebrew/bundle 41 | brew bundle 42 | 43 | if ! bundle exec pod install; then 44 | bundle exec pod install --repo-update 45 | fi 46 | -------------------------------------------------------------------------------- /scripts/tests/branch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Branch name: $SRC_BRANCH" 4 | 5 | if [[ "$SRC_BRANCH" == 'master' ]]; then 6 | exit 0 7 | fi 8 | 9 | for PREFIX in feature bugfix hotfix release; do 10 | if [[ "$SRC_BRANCH" == $PREFIX/* ]]; then 11 | exit 0 12 | fi 13 | for CODE in app lib; do 14 | if [[ "$SRC_BRANCH" == $CODE/$PREFIX/* ]]; then 15 | exit 0 16 | fi 17 | done 18 | done 19 | 20 | echo "Branch name does not pass convention." 21 | exit 1 22 | -------------------------------------------------------------------------------- /scripts/tests/lint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "REPO_SLUG = $REPO_SLUG" 4 | echo "PR_NUMBER = $PR_NUMBER" 5 | 6 | ./Pods/SwiftLint/swiftlint lint --reporter json > swiftlint-report.json || false 7 | 8 | if [[ -z "$PR_NUMBER" ]]; then 9 | echo 'Not in a Pull Request, skip report.' 10 | else 11 | bundle exec linterbot "$REPO_SLUG" "$PR_NUMBER" < swiftlint-report.json 12 | fi 13 | -------------------------------------------------------------------------------- /scripts/tests/pod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "$SDK" ]]; then 4 | echo 'Exporting build environment variables...' 5 | SDK='iphonesimulator11.2' 6 | SCHEME='RealmS' 7 | WORKSPACE='RealmS.xcworkspace' 8 | DESTINATION='OS=11.2,name=iPhone 7' 9 | CONFIGURATION='Debug' 10 | fi 11 | 12 | xcodebuild test \ 13 | -workspace "$WORKSPACE" \ 14 | -scheme "$SCHEME" \ 15 | -sdk "$SDK" \ 16 | -destination "$DESTINATION" \ 17 | -derivedDataPath build \ 18 | ONLY_ACTIVE_ARCH=YES \ 19 | -configuration "$CONFIGURATION" 20 | 21 | exit "${PIPESTATUS[0]}" 22 | --------------------------------------------------------------------------------