From 3c749103aff3f4405ea0c76eeb3f03d855a254ce Mon Sep 17 00:00:00 2001 From: ellinakuznetcova Date: Sat, 12 Nov 2016 16:22:33 +0300 Subject: [PATCH 1/2] added iMessages app example --- .../Assets.xcassets/Contents.json | 6 + .../Contents.json | 58 ++ .../poll.imageset/Contents.json | 23 + .../poll.imageset/poll-hands1-1.png | Bin 0 -> 108233 bytes .../poll.imageset/poll-hands1-2.png | Bin 0 -> 108233 bytes .../poll.imageset/poll-hands1.png | Bin 0 -> 108233 bytes .../Base.lproj/MainInterface.storyboard | 166 ++++ .../CompactViewController.swift | 36 + .../ExpandedViewController.swift | 71 ++ iMessagesExample/MessagesExtension/Info.plist | 31 + .../MessagesViewController.swift | 123 +++ .../MessagesExtension/PollEntity.swift | 88 ++ iMessagesExample/Podfile | 26 + iMessagesExample/Podfile.lock | 12 + iMessagesExample/Pods/Manifest.lock | 12 + iMessagesExample/Pods/ObjectMapper/LICENSE | 8 + .../ObjectMapper/Core/FromJSON.swift | 181 ++++ .../ObjectMapper/Core/ImmutableMappble.swift | 193 +++++ .../ObjectMapper/ObjectMapper/Core/Map.swift | 158 ++++ .../ObjectMapper/Core/MapError.swift | 68 ++ .../ObjectMapper/Core/Mappable.swift | 139 ++++ .../ObjectMapper/Core/Mapper.swift | 430 ++++++++++ .../Core/Operators/EnumOperators.swift | 91 +++ .../Core/Operators/Operators.swift | 377 +++++++++ .../Core/Operators/TransformOperators.swift | 606 ++++++++++++++ .../ObjectMapper/Core/ToJSON.swift | 176 ++++ .../CustomDateFormatTransform.swift | 40 + .../Transforms/DataTransform.swift | 50 ++ .../Transforms/DateFormatterTransform.swift | 54 ++ .../Transforms/DateTransform.swift | 55 ++ .../Transforms/DictionaryTransform.swift | 58 ++ .../Transforms/EnumTransform.swift | 50 ++ .../Transforms/ISO8601DateTransform.swift | 41 + .../Transforms/NSDecimalNumberTransform.swift | 51 ++ .../ObjectMapper/Transforms/TransformOf.swift | 48 ++ .../Transforms/TransformType.swift | 35 + .../Transforms/URLTransform.swift | 65 ++ iMessagesExample/Pods/ObjectMapper/README.md | 472 +++++++++++ .../Pods/Pods.xcodeproj/project.pbxproj | 771 ++++++++++++++++++ .../ObjectMapper/Info.plist | 26 + .../ObjectMapper/ObjectMapper-dummy.m | 5 + .../ObjectMapper/ObjectMapper-prefix.pch | 4 + .../ObjectMapper/ObjectMapper-umbrella.h | 6 + .../ObjectMapper/ObjectMapper.modulemap | 6 + .../ObjectMapper/ObjectMapper.xcconfig | 10 + .../Info.plist | 26 + ...essagesExtension-acknowledgements.markdown | 15 + ...t-MessagesExtension-acknowledgements.plist | 45 + .../Pods-Abstract-MessagesExtension-dummy.m | 5 + ...s-Abstract-MessagesExtension-frameworks.sh | 91 +++ ...ds-Abstract-MessagesExtension-resources.sh | 102 +++ ...Pods-Abstract-MessagesExtension-umbrella.h | 6 + ...-Abstract-MessagesExtension.debug.xcconfig | 10 + .../Pods-Abstract-MessagesExtension.modulemap | 6 + ...bstract-MessagesExtension.release.xcconfig | 10 + .../Pods-Abstract-VoteApp/Info.plist | 26 + ...Abstract-VoteApp-acknowledgements.markdown | 15 + ...ds-Abstract-VoteApp-acknowledgements.plist | 45 + .../Pods-Abstract-VoteApp-dummy.m | 5 + .../Pods-Abstract-VoteApp-frameworks.sh | 91 +++ .../Pods-Abstract-VoteApp-resources.sh | 102 +++ .../Pods-Abstract-VoteApp-umbrella.h | 6 + .../Pods-Abstract-VoteApp.debug.xcconfig | 10 + .../Pods-Abstract-VoteApp.modulemap | 6 + .../Pods-Abstract-VoteApp.release.xcconfig | 10 + .../VoteApp.xcodeproj/project.pbxproj | 557 +++++++++++++ .../contents.xcworkspacedata | 7 + .../contents.xcworkspacedata | 10 + .../AppIcon.appiconset/Contents.json | 93 +++ iMessagesExample/VoteApp/Info.plist | 43 + 70 files changed, 6268 insertions(+) create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/Contents.json create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/Contents.json create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-1.png create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-2.png create mode 100644 iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1.png create mode 100644 iMessagesExample/MessagesExtension/Base.lproj/MainInterface.storyboard create mode 100644 iMessagesExample/MessagesExtension/CompactViewController.swift create mode 100644 iMessagesExample/MessagesExtension/ExpandedViewController.swift create mode 100644 iMessagesExample/MessagesExtension/Info.plist create mode 100644 iMessagesExample/MessagesExtension/MessagesViewController.swift create mode 100644 iMessagesExample/MessagesExtension/PollEntity.swift create mode 100644 iMessagesExample/Podfile create mode 100644 iMessagesExample/Podfile.lock create mode 100644 iMessagesExample/Pods/Manifest.lock create mode 100644 iMessagesExample/Pods/ObjectMapper/LICENSE create mode 100755 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/FromJSON.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ImmutableMappble.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Map.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/MapError.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mappable.swift create mode 100755 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mapper.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/EnumOperators.swift create mode 100755 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/Operators.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/TransformOperators.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ToJSON.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/CustomDateFormatTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DataTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateFormatterTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DictionaryTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/EnumTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/ISO8601DateTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/NSDecimalNumberTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformOf.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformType.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/URLTransform.swift create mode 100644 iMessagesExample/Pods/ObjectMapper/README.md create mode 100644 iMessagesExample/Pods/Pods.xcodeproj/project.pbxproj create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/Info.plist create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-dummy.m create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-prefix.pch create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-umbrella.h create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.modulemap create mode 100644 iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.xcconfig create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Info.plist create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.markdown create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.plist create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-dummy.m create mode 100755 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-frameworks.sh create mode 100755 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-resources.sh create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-umbrella.h create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.debug.xcconfig create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.release.xcconfig create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Info.plist create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.markdown create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.plist create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-dummy.m create mode 100755 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-frameworks.sh create mode 100755 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-resources.sh create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-umbrella.h create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.debug.xcconfig create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap create mode 100644 iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.release.xcconfig create mode 100644 iMessagesExample/VoteApp.xcodeproj/project.pbxproj create mode 100644 iMessagesExample/VoteApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 iMessagesExample/VoteApp.xcworkspace/contents.xcworkspacedata create mode 100644 iMessagesExample/VoteApp/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 iMessagesExample/VoteApp/Info.plist diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/Contents.json b/iMessagesExample/MessagesExtension/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/iMessagesExample/MessagesExtension/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json b/iMessagesExample/MessagesExtension/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json new file mode 100644 index 0000000..22c2afe --- /dev/null +++ b/iMessagesExample/MessagesExtension/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "60x45", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x45", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "67x50", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "74x55", + "scale" : "2x" + }, + { + "size" : "27x20", + "idiom" : "universal", + "scale" : "2x", + "platform" : "ios" + }, + { + "size" : "27x20", + "idiom" : "universal", + "scale" : "3x", + "platform" : "ios" + }, + { + "size" : "32x24", + "idiom" : "universal", + "scale" : "2x", + "platform" : "ios" + }, + { + "size" : "32x24", + "idiom" : "universal", + "scale" : "3x", + "platform" : "ios" + }, + { + "size" : "1024x768", + "idiom" : "ios-marketing", + "scale" : "1x", + "platform" : "ios" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/Contents.json b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/Contents.json new file mode 100644 index 0000000..94d5d6e --- /dev/null +++ b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "poll-hands1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "poll-hands1-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "poll-hands1-2.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-1.png b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..42526a2f5a91e3bdf338004f6297e5ecd31e5270 GIT binary patch literal 108233 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 T-}etlfRDyK9hGXNP1yecvQEA^ literal 0 HcmV?d00001 diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-2.png b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..42526a2f5a91e3bdf338004f6297e5ecd31e5270 GIT binary patch literal 108233 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 T-}etlfRDyK9hGXNP1yecvQEA^ literal 0 HcmV?d00001 diff --git a/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1.png b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1.png new file mode 100644 index 0000000000000000000000000000000000000000..42526a2f5a91e3bdf338004f6297e5ecd31e5270 GIT binary patch literal 108233 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 T-}etlfRDyK9hGXNP1yecvQEA^ literal 0 HcmV?d00001 diff --git a/iMessagesExample/MessagesExtension/Base.lproj/MainInterface.storyboard b/iMessagesExample/MessagesExtension/Base.lproj/MainInterface.storyboard new file mode 100644 index 0000000..a92593d --- /dev/null +++ b/iMessagesExample/MessagesExtension/Base.lproj/MainInterface.storyboard @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iMessagesExample/MessagesExtension/CompactViewController.swift b/iMessagesExample/MessagesExtension/CompactViewController.swift new file mode 100644 index 0000000..d224d39 --- /dev/null +++ b/iMessagesExample/MessagesExtension/CompactViewController.swift @@ -0,0 +1,36 @@ +// +// CompactViewController.swift +// VoteApp +// +// Created by Ellina Kuznecova on 01.11.16. +// Copyright © 2016 Ellina Kuznetcova. All rights reserved. +// + +import UIKit + +protocol CompactViewControllerDelegate: class { + func createPollPressed() + func sendMessage() +} + +class CompactViewController: UIViewController { + @IBOutlet weak var actionButton: UIButton! + + var options: [PollOption] = [] + weak var delegate: CompactViewControllerDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + let actionButtonTitle = self.options.count > 0 ? "Send Poll" : "Create Poll" + self.actionButton.setTitle(actionButtonTitle, for: .normal) + } + + @IBAction func actionButtonPressed(_ sender: AnyObject) { + if self.options.count > 0 { + self.delegate?.sendMessage() + } else { + self.delegate?.createPollPressed() + } + } +} diff --git a/iMessagesExample/MessagesExtension/ExpandedViewController.swift b/iMessagesExample/MessagesExtension/ExpandedViewController.swift new file mode 100644 index 0000000..b047888 --- /dev/null +++ b/iMessagesExample/MessagesExtension/ExpandedViewController.swift @@ -0,0 +1,71 @@ +// +// ExpandedViewController.swift +// VoteApp +// +// Created by Ellina Kuznecova on 01.11.16. +// Copyright © 2016 Ellina Kuznetcova. All rights reserved. +// + +import UIKit + +protocol ExpandedViewControllerDelegate: class { + func pollUpdated(poll: PollEntity) +} + +class ExpandedViewController: UIViewController { + @IBOutlet weak var pollVariantTextField: UITextField! + @IBOutlet weak var tableView: UITableView! + @IBOutlet weak var addNewVariant: UIButton! + + weak var delegate: ExpandedViewControllerDelegate? + var data: PollEntity! + + override func viewDidLoad() { + super.viewDidLoad() + + self.changeViewsState(to: self.data.options.count == 0) + } + + @IBAction func addNewVariantPressed(_ sender: AnyObject) { + self.changeViewsState(to: true) + } + + @IBAction func savePressed(_ sender: AnyObject) { + guard let text = self.pollVariantTextField.text, text != "" else {return} + self.data.options.append(PollOption(name: text)) + self.pollVariantTextField.text = "" + self.tableView.reloadData() + self.delegate?.pollUpdated(poll: self.data) + self.changeViewsState(to: false) + } + + @IBAction func cancelPressed(_ sender: AnyObject) { + self.changeViewsState(to: false) + } + + private func changeViewsState(to visibility: Bool) { + self.tableView.isHidden = visibility + self.addNewVariant.isHidden = visibility + } +} + +extension ExpandedViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return self.data.options.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Basic")! + cell.textLabel?.text = self.data.options[indexPath.row].name + return cell + } +} + +extension ExpandedViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.view.endEditing(true) + self.savePressed(self) + return true + } +} diff --git a/iMessagesExample/MessagesExtension/Info.plist b/iMessagesExample/MessagesExtension/Info.plist new file mode 100644 index 0000000..3319d60 --- /dev/null +++ b/iMessagesExample/MessagesExtension/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + VoteApp + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSExtension + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.message-payload-provider + + + diff --git a/iMessagesExample/MessagesExtension/MessagesViewController.swift b/iMessagesExample/MessagesExtension/MessagesViewController.swift new file mode 100644 index 0000000..3e0e63b --- /dev/null +++ b/iMessagesExample/MessagesExtension/MessagesViewController.swift @@ -0,0 +1,123 @@ +// +// MessagesViewController.swift +// MessagesExtension +// +// Created by Ellina Kuznecova on 01.11.16. +// Copyright © 2016 Ellina Kuznetcova. All rights reserved. +// + +import UIKit +import Messages + +class MessagesViewController: MSMessagesAppViewController { + + var poll: PollEntity! + + override func willBecomeActive(with conversation: MSConversation) { + super.willBecomeActive(with: conversation) + + self.poll = PollEntity(message: conversation.selectedMessage) ?? PollEntity(creatorId: conversation.localParticipantIdentifier.uuidString) + presentVC(for: conversation, with: presentationStyle) + } + + override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) { + guard let conversation = activeConversation else { + fatalError("Expected the active conversation") + } + if let _ = conversation.selectedMessage { + self.poll = PollEntity(message: conversation.selectedMessage) + } + presentVC(for: conversation, with: presentationStyle) + } + + private func presentVC(for conversation: MSConversation, with presentationStyle: MSMessagesAppPresentationStyle) { + let controller: UIViewController + + if presentationStyle == .compact { + controller = instantiateCompactVC() + } else { + controller = instantiateExpandedVC() + } + + // Remove any existing child controllers. + for child in childViewControllers { + child.willMove(toParentViewController: nil) + child.view.removeFromSuperview() + child.removeFromParentViewController() + } + + self.addChildViewController(controller) + + //TODO: figure out why size is not right + controller.view.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: self.view.frame.size) + view.addSubview(controller.view) + + controller.didMove(toParentViewController: self) + } + + private func instantiateCompactVC() -> UIViewController { + guard let compactVC = storyboard?.instantiateViewController(withIdentifier: "CompactVC") as? CompactViewController else { + fatalError("Can't instantiate CompactViewController") + } + compactVC.delegate = self + compactVC.options = self.poll.options + return compactVC + } + + private func instantiateExpandedVC() -> UIViewController { + guard let expandedVC = storyboard?.instantiateViewController(withIdentifier: "ExpandedVC") as? ExpandedViewController else { + fatalError("Can't instantiate ExpandedViewController") + } + expandedVC.delegate = self + expandedVC.data = self.poll + return expandedVC + } + + private func isSenderSameAsRecipient() -> Bool { + guard let conversation = activeConversation else { return false } + guard let message = conversation.selectedMessage else { return false } + + return message.senderParticipantIdentifier == conversation.localParticipantIdentifier + } +} + +extension MessagesViewController: CompactViewControllerDelegate { + func createPollPressed() { + self.requestPresentationStyle(.expanded) + } + + func sendMessage() { + guard let conversation = activeConversation else { fatalError("Expected a conversation") } + // Create a new message with the same session as any currently selected message. + let message = composeMessage(with: "I created new poll!", session: conversation.selectedMessage?.session) + + // Add the message to the conversation. + conversation.insert(message) { error in + if let error = error { + print(error) + } + } + } + + fileprivate func composeMessage(with caption: String, session: MSSession? = nil) -> MSMessage { + + let layout = MSMessageTemplateLayout() + layout.image = #imageLiteral(resourceName: "poll") + layout.caption = caption + + let message = MSMessage(session: session ?? MSSession()) + message.layout = layout + + var components = URLComponents() + components.queryItems = self.poll.queryItems + message.url = components.url! + + return message + } +} + +extension MessagesViewController: ExpandedViewControllerDelegate { + func pollUpdated(poll: PollEntity) { + self.poll = poll + } +} diff --git a/iMessagesExample/MessagesExtension/PollEntity.swift b/iMessagesExample/MessagesExtension/PollEntity.swift new file mode 100644 index 0000000..7cc875f --- /dev/null +++ b/iMessagesExample/MessagesExtension/PollEntity.swift @@ -0,0 +1,88 @@ +// +// PollEntity.swift +// VoteApp +// +// Created by Ellina Kuznecova on 05.11.16. +// Copyright © 2016 Ellina Kuznetcova. All rights reserved. +// + +import Foundation +import Messages +import ObjectMapper + +struct PollEntity { + static var entityKey = "pollEntity" + static var creatorIdKey = "creatorId" + static var optionsKey = "options" + + var options: [PollOption] + var creatorId: String + + var queryItems: [URLQueryItem] { + return [URLQueryItem(name: PollEntity.entityKey, value: self.toJSONString())] + } + + init(creatorId: String) { + self.creatorId = creatorId + self.options = [] + } + + init?(message: MSMessage?) { + guard let messageURL = message?.url else { return nil } + guard let urlComponents = NSURLComponents(url: messageURL, resolvingAgainstBaseURL: false), let queryItems = urlComponents.queryItems else { return nil } + + self.init(queryItems: queryItems) + } + + init?(map: ObjectMapper.Map) { + self.init(message: nil) + } + + init?(queryItems: [URLQueryItem]) { + guard let queryItem = queryItems.first, + let value = queryItem.value, + queryItem.name == PollEntity.entityKey else { return nil } + var decodedObject = PollEntity(creatorId: "") + decodedObject = Mapper().map(JSONString: value, toObject: decodedObject) + guard decodedObject.creatorId != "" else {return nil} + self.creatorId = decodedObject.creatorId + self.options = decodedObject.options + } +} + +extension PollEntity: Mappable { + mutating func mapping(map: ObjectMapper.Map) { + self.creatorId <- map[PollEntity.creatorIdKey] + self.options <- map[PollEntity.optionsKey] + } +} + +struct PollOption: Mappable { + var name: String + var voters: [Voter] + + init(name: String) { + self.name = name + self.voters = [] + } + + init?(map: ObjectMapper.Map) { + self.init(name: "") + } + + mutating func mapping(map: ObjectMapper.Map) { + self.name <- map["name"] + self.voters <- map["voters"] + } +} + +struct Voter: Mappable { + var id: String? + + init?(map: ObjectMapper.Map) {} + + mutating func mapping(map: ObjectMapper.Map) { + self.id <- map["id"] + + } +} diff --git a/iMessagesExample/Podfile b/iMessagesExample/Podfile new file mode 100644 index 0000000..b748e20 --- /dev/null +++ b/iMessagesExample/Podfile @@ -0,0 +1,26 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '9.0' +source 'https://github.com/CocoaPods/Specs.git' +use_frameworks! + +abstract_target 'Abstract' do + + pod 'ObjectMapper' + + target 'MessagesExtension' do + + end + + target 'VoteApp' do + + end +end + + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '3.0' + end + end +end diff --git a/iMessagesExample/Podfile.lock b/iMessagesExample/Podfile.lock new file mode 100644 index 0000000..1be4021 --- /dev/null +++ b/iMessagesExample/Podfile.lock @@ -0,0 +1,12 @@ +PODS: + - ObjectMapper (2.1.0) + +DEPENDENCIES: + - ObjectMapper + +SPEC CHECKSUMS: + ObjectMapper: e5e0f8aef8590fc2ddcde7f27eddb255863ee6e9 + +PODFILE CHECKSUM: a635da266148c6059888f593f9034b9ea6f2e3ad + +COCOAPODS: 1.0.1 diff --git a/iMessagesExample/Pods/Manifest.lock b/iMessagesExample/Pods/Manifest.lock new file mode 100644 index 0000000..1be4021 --- /dev/null +++ b/iMessagesExample/Pods/Manifest.lock @@ -0,0 +1,12 @@ +PODS: + - ObjectMapper (2.1.0) + +DEPENDENCIES: + - ObjectMapper + +SPEC CHECKSUMS: + ObjectMapper: e5e0f8aef8590fc2ddcde7f27eddb255863ee6e9 + +PODFILE CHECKSUM: a635da266148c6059888f593f9034b9ea6f2e3ad + +COCOAPODS: 1.0.1 diff --git a/iMessagesExample/Pods/ObjectMapper/LICENSE b/iMessagesExample/Pods/ObjectMapper/LICENSE new file mode 100644 index 0000000..be48bc6 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/LICENSE @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2014 Hearst + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/FromJSON.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/FromJSON.swift new file mode 100755 index 0000000..7cb4655 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/FromJSON.swift @@ -0,0 +1,181 @@ +// +// FromJSON.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-09. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +internal final class FromJSON { + + /// Basic type + class func basicType(_ field: inout FieldType, object: FieldType?) { + if let value = object { + field = value + } + } + + /// optional basic type + class func optionalBasicType(_ field: inout FieldType?, object: FieldType?) { + field = object + } + + /// Implicitly unwrapped optional basic type + class func optionalBasicType(_ field: inout FieldType!, object: FieldType?) { + field = object + } + + /// Mappable object + class func object(_ field: inout N, map: Map) { + if map.toObject { + _ = Mapper(context: map.context).map(JSONObject: map.currentValue, toObject: field) + } else if let value: N = Mapper(context: map.context).map(JSONObject: map.currentValue) { + field = value + } + } + + /// Optional Mappable Object + + class func optionalObject(_ field: inout N?, map: Map) { + if let field = field , map.toObject && map.currentValue != nil { + _ = Mapper(context: map.context).map(JSONObject: map.currentValue, toObject: field) + } else { + field = Mapper(context: map.context).map(JSONObject: map.currentValue) + } + } + + /// Implicitly unwrapped Optional Mappable Object + class func optionalObject(_ field: inout N!, map: Map) { + if let field = field , map.toObject && map.currentValue != nil { + _ = Mapper(context: map.context).map(JSONObject: map.currentValue, toObject: field) + } else { + field = Mapper(context: map.context).map(JSONObject: map.currentValue) + } + } + + /// mappable object array + class func objectArray(_ field: inout Array, map: Map) { + if let objects = Mapper(context: map.context).mapArray(JSONObject: map.currentValue) { + field = objects + } + } + + /// optional mappable object array + + class func optionalObjectArray(_ field: inout Array?, map: Map) { + if let objects: Array = Mapper(context: map.context).mapArray(JSONObject: map.currentValue) { + field = objects + } else { + field = nil + } + } + + /// Implicitly unwrapped optional mappable object array + class func optionalObjectArray(_ field: inout Array!, map: Map) { + if let objects: Array = Mapper(context: map.context).mapArray(JSONObject: map.currentValue) { + field = objects + } else { + field = nil + } + } + + /// mappable object array + class func twoDimensionalObjectArray(_ field: inout Array>, map: Map) { + if let objects = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) { + field = objects + } + } + + /// optional mappable 2 dimentional object array + class func optionalTwoDimensionalObjectArray(_ field: inout Array>?, map: Map) { + field = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) + } + + /// Implicitly unwrapped optional 2 dimentional mappable object array + class func optionalTwoDimensionalObjectArray(_ field: inout Array>!, map: Map) { + field = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) + } + + /// Dctionary containing Mappable objects + class func objectDictionary(_ field: inout Dictionary, map: Map) { + if map.toObject { + _ = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue, toDictionary: field) + } else { + if let objects = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue) { + field = objects + } + } + } + + /// Optional dictionary containing Mappable objects + class func optionalObjectDictionary(_ field: inout Dictionary?, map: Map) { + if let field = field , map.toObject && map.currentValue != nil { + _ = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue, toDictionary: field) + } else { + field = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue) + } + } + + /// Implicitly unwrapped Dictionary containing Mappable objects + class func optionalObjectDictionary(_ field: inout Dictionary!, map: Map) { + if let field = field , map.toObject && map.currentValue != nil { + _ = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue, toDictionary: field) + } else { + field = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue) + } + } + + /// Dictionary containing Array of Mappable objects + class func objectDictionaryOfArrays(_ field: inout Dictionary, map: Map) { + if let objects = Mapper(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) { + field = objects + } + } + + /// Optional Dictionary containing Array of Mappable objects + class func optionalObjectDictionaryOfArrays(_ field: inout Dictionary?, map: Map) { + field = Mapper(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) + } + + /// Implicitly unwrapped Dictionary containing Array of Mappable objects + class func optionalObjectDictionaryOfArrays(_ field: inout Dictionary!, map: Map) { + field = Mapper(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) + } + + /// mappable object Set + class func objectSet(_ field: inout Set, map: Map) { + if let objects = Mapper(context: map.context).mapSet(JSONObject: map.currentValue) { + field = objects + } + } + + /// optional mappable object array + class func optionalObjectSet(_ field: inout Set?, map: Map) { + field = Mapper(context: map.context).mapSet(JSONObject: map.currentValue) + } + + /// Implicitly unwrapped optional mappable object array + class func optionalObjectSet(_ field: inout Set!, map: Map) { + field = Mapper(context: map.context).mapSet(JSONObject: map.currentValue) + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ImmutableMappble.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ImmutableMappble.swift new file mode 100644 index 0000000..ee67770 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ImmutableMappble.swift @@ -0,0 +1,193 @@ +// +// ImmutableMappble.swift +// ObjectMapper +// +// Created by Suyeol Jeon on 23/09/2016. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +public protocol ImmutableMappable: BaseMappable { + init(map: Map) throws +} + +public extension ImmutableMappable { + + /// Implement this method to support object -> JSON transform. + public func mapping(map: Map) {} + + /// Initializes object from a JSON String + public init(JSONString: String, context: MapContext? = nil) throws { + self = try Mapper(context: context).map(JSONString: JSONString) + } + + /// Initializes object from a JSON Dictionary + public init(JSON: [String: Any], context: MapContext? = nil) throws { + self = try Mapper(context: context).map(JSON: JSON) + } + +} + +public extension Map { + + fileprivate func currentValue(for key: String) -> Any? { + return self[key].currentValue + } + + // MARK: Basic + + /// Returns a value or throws an error. + public func value(_ key: String, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> T { + let currentValue = self.currentValue(for: key) + guard let value = currentValue as? T else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '\(T.self)'", file: file, function: function, line: line) + } + return value + } + + /// Returns a transformed value or throws an error. + public func value(_ key: String, using transform: Transform, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> Transform.Object { + let currentValue = self.currentValue(for: key) + guard let value = transform.transformFromJSON(currentValue) else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot transform to '\(Transform.Object.self)' using \(transform)", file: file, function: function, line: line) + } + return value + } + + // MARK: BaseMappable + + /// Returns a `BaseMappable` object or throws an error. + public func value(_ key: String) throws -> T { + let currentValue = self.currentValue(for: key) + return try Mapper().mapOrFail(JSONObject: currentValue) + } + + // MARK: [BaseMappable] + + /// Returns a `[BaseMappable]` or throws an error. + public func value(_ key: String, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> [T] { + let currentValue = self.currentValue(for: key) + guard let jsonArray = currentValue as? [Any] else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '[Any]'", file: file, function: function, line: line) + } + return try jsonArray.enumerated().map { i, JSONObject -> T in + return try Mapper().mapOrFail(JSONObject: JSONObject) + } + } + + /// Returns a `[BaseMappable]` using transform or throws an error. + public func value(_ key: String, using transform: Transform, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> [Transform.Object] { + let currentValue = self.currentValue(for: key) + guard let jsonArray = currentValue as? [Any] else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '[Any]'", file: file, function: function, line: line) + } + return try jsonArray.enumerated().map { i, json -> Transform.Object in + guard let object = transform.transformFromJSON(json) else { + throw MapError(key: "\(key)[\(i)]", currentValue: json, reason: "Cannot transform to '\(Transform.Object.self)' using \(transform)", file: file, function: function, line: line) + } + return object + } + } + + // MARK: [String: BaseMappable] + + /// Returns a `[String: BaseMappable]` or throws an error. + public func value(_ key: String, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> [String: T] { + let currentValue = self.currentValue(for: key) + guard let jsonDictionary = currentValue as? [String: Any] else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '[String: Any]'", file: file, function: function, line: line) + } + var value: [String: T] = [:] + for (key, json) in jsonDictionary { + value[key] = try Mapper().mapOrFail(JSONObject: json) + } + return value + } + + /// Returns a `[String: BaseMappable]` using transform or throws an error. + public func value(_ key: String, using transform: Transform, file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> [String: Transform.Object] { + let currentValue = self.currentValue(for: key) + guard let jsonDictionary = currentValue as? [String: Any] else { + throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '[String: Any]'", file: file, function: function, line: line) + } + var value: [String: Transform.Object] = [:] + for (key, json) in jsonDictionary { + guard let object = transform.transformFromJSON(json) else { + throw MapError(key: key, currentValue: json, reason: "Cannot transform to '\(Transform.Object.self)' using \(transform)", file: file, function: function, line: line) + } + value[key] = object + } + return value + } + +} + +public extension Mapper where N: ImmutableMappable { + + public func map(JSON: [String: Any]) throws -> N { + return try self.mapOrFail(JSON: JSON) + } + + public func map(JSONString: String) throws -> N { + return try mapOrFail(JSONString: JSONString) + } + + public func map(JSONObject: Any?) throws -> N { + return try mapOrFail(JSONObject: JSONObject) + } + +} + +internal extension Mapper where N: BaseMappable { + + internal func mapOrFail(JSON: [String: Any]) throws -> N { + let map = Map(mappingType: .fromJSON, JSON: JSON, context: context) + + // Check if object is ImmutableMappable, if so use ImmutableMappable protocol for mapping + if let klass = N.self as? ImmutableMappable.Type, + var object = try klass.init(map: map) as? N { + object.mapping(map: map) + return object + } + + // If not, map the object the standard way + guard let value = self.map(JSON: JSON) else { + throw MapError(key: nil, currentValue: JSON, reason: "Cannot map to '\(N.self)'") + } + return value + } + + internal func mapOrFail(JSONString: String) throws -> N { + guard let JSON = Mapper.parseJSONStringIntoDictionary(JSONString: JSONString) else { + throw MapError(key: nil, currentValue: JSONString, reason: "Cannot parse into '[String: Any]'") + } + return try mapOrFail(JSON: JSON) + } + + internal func mapOrFail(JSONObject: Any?) throws -> N { + guard let JSON = JSONObject as? [String: Any] else { + throw MapError(key: nil, currentValue: JSONObject, reason: "Cannot cast to '[String: Any]'") + } + return try mapOrFail(JSON: JSON) + } + +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Map.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Map.swift new file mode 100644 index 0000000..57b9c6c --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Map.swift @@ -0,0 +1,158 @@ +// +// Map.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2015-10-09. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +import Foundation + +/// MapContext is available for developers who wish to pass information around during the mapping process. +public protocol MapContext { + +} + +/// A class used for holding mapping data +public final class Map { + public let mappingType: MappingType + + public internal(set) var JSON: [String: Any] = [:] + public internal(set) var isKeyPresent = false + public internal(set) var currentValue: Any? + public internal(set) var currentKey: String? + var keyIsNested = false + public var context: MapContext? + + let toObject: Bool // indicates whether the mapping is being applied to an existing object + + public init(mappingType: MappingType, JSON: [String: Any], toObject: Bool = false, context: MapContext? = nil) { + self.mappingType = mappingType + self.JSON = JSON + self.toObject = toObject + self.context = context + } + + /// Sets the current mapper value and key. + /// The Key paramater can be a period separated string (ex. "distance.value") to access sub objects. + public subscript(key: String) -> Map { + // save key and value associated to it + let nested = key.contains(".") + return self[key, nested: nested, ignoreNil: false] + } + + public subscript(key: String, nested nested: Bool) -> Map { + return self[key, nested: nested, ignoreNil: false] + } + + public subscript(key: String, ignoreNil ignoreNil: Bool) -> Map { + let nested = key.contains(".") + return self[key, nested: nested, ignoreNil: ignoreNil] + } + + public subscript(key: String, nested nested: Bool, ignoreNil ignoreNil: Bool) -> Map { + // save key and value associated to it + currentKey = key + keyIsNested = nested + + // check if a value exists for the current key + // do this pre-check for performance reasons + if nested == false { + let object = JSON[key] + let isNSNull = object is NSNull + isKeyPresent = isNSNull ? true : object != nil + currentValue = isNSNull ? nil : object + } else { + // break down the components of the key that are separated by . + (isKeyPresent, currentValue) = valueFor(ArraySlice(key.components(separatedBy: ".")), dictionary: JSON) + } + + // update isKeyPresent if ignoreNil is true + if ignoreNil && currentValue == nil { + isKeyPresent = false + } + + return self + } + + public func value() -> T? { + return currentValue as? T + } + +} + +/// Fetch value from JSON dictionary, loop through keyPathComponents until we reach the desired object +private func valueFor(_ keyPathComponents: ArraySlice, dictionary: [String: Any]) -> (Bool, Any?) { + // Implement it as a tail recursive function. + if keyPathComponents.isEmpty { + return (false, nil) + } + + if let keyPath = keyPathComponents.first { + let object = dictionary[keyPath] + if object is NSNull { + return (true, nil) + } else if let dict = object as? [String: Any] , keyPathComponents.count > 1 { + let tail = keyPathComponents.dropFirst() + return valueFor(tail, dictionary: dict) + } else if let array = object as? [Any] , keyPathComponents.count > 1 { + let tail = keyPathComponents.dropFirst() + return valueFor(tail, array: array) + } else { + return (object != nil, object) + } + } + + return (false, nil) +} + +/// Fetch value from JSON Array, loop through keyPathComponents them until we reach the desired object +private func valueFor(_ keyPathComponents: ArraySlice, array: [Any]) -> (Bool, Any?) { + // Implement it as a tail recursive function. + + if keyPathComponents.isEmpty { + return (false, nil) + } + + //Try to convert keypath to Int as index + if let keyPath = keyPathComponents.first, + let index = Int(keyPath) , index >= 0 && index < array.count { + + let object = array[index] + + if object is NSNull { + return (true, nil) + } else if let array = object as? [Any] , keyPathComponents.count > 1 { + let tail = keyPathComponents.dropFirst() + return valueFor(tail, array: array) + } else if let dict = object as? [String: Any] , keyPathComponents.count > 1 { + let tail = keyPathComponents.dropFirst() + return valueFor(tail, dictionary: dict) + } else { + return (true, object) + } + } + + return (false, nil) +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/MapError.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/MapError.swift new file mode 100644 index 0000000..17b52bb --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/MapError.swift @@ -0,0 +1,68 @@ +// +// MapError.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2016-09-26. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public struct MapError: Error { + public var key: String? + public var currentValue: Any? + public var reason: String? + public var file: StaticString? + public var function: StaticString? + public var line: UInt? + + init(key: String?, currentValue: Any?, reason: String?, file: StaticString? = nil, function: StaticString? = nil, line: UInt? = nil) { + self.key = key + self.currentValue = currentValue + self.reason = reason + self.file = file + self.function = function + self.line = line + } +} + +extension MapError: CustomStringConvertible { + + private var location: String? { + guard let file = file, let function = function, let line = line else { return nil } + let fileName = ((String(describing: file).components(separatedBy: "/").last ?? "").components(separatedBy: ".").first ?? "") + return "\(fileName).\(function):\(line)" + } + + public var description: String { + let info: [(String, Any?)] = [ + ("- reason", reason), + ("- location", location), + ("- key", key), + ("- currentValue", currentValue), + ] + let infoString = info.map { "\($0): \($1 ?? "nil")" }.joined(separator: "\n") + return "Got an error while mapping.\n\(infoString)" + } + +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mappable.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mappable.swift new file mode 100644 index 0000000..1069679 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mappable.swift @@ -0,0 +1,139 @@ +// +// Mappable.swift +// ObjectMapper +// +// Created by Scott Hoyt on 10/25/15. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +/// BaseMappable should not be implemented directly. Mappable or StaticMappable should be used instead +public protocol BaseMappable { + /// This function is where all variable mappings should occur. It is executed by Mapper during the mapping (serialization and deserialization) process. + mutating func mapping(map: Map) +} + +public protocol Mappable: BaseMappable { + /// This function can be used to validate JSON prior to mapping. Return nil to cancel mapping at this point + init?(map: Map) +} + +public protocol StaticMappable: BaseMappable { + /// This is function that can be used to: + /// 1) provide an existing cached object to be used for mapping + /// 2) return an object of another class (which conforms to Mappable) to be used for mapping. For instance, you may inspect the JSON to infer the type of object that should be used for any given mapping + static func objectForMapping(map: Map) -> BaseMappable? +} + +public extension BaseMappable { + + /// Initializes object from a JSON String + public init?(JSONString: String, context: MapContext? = nil) { + if let obj: Self = Mapper(context: context).map(JSONString: JSONString) { + self = obj + } else { + return nil + } + } + + /// Initializes object from a JSON Dictionary + public init?(JSON: [String: Any], context: MapContext? = nil) { + if let obj: Self = Mapper(context: context).map(JSON: JSON) { + self = obj + } else { + return nil + } + } + + /// Returns the JSON Dictionary for the object + public func toJSON() -> [String: Any] { + return Mapper().toJSON(self) + } + + /// Returns the JSON String for the object + public func toJSONString(prettyPrint: Bool = false) -> String? { + return Mapper().toJSONString(self, prettyPrint: prettyPrint) + } +} + +public extension Array where Element: BaseMappable { + + /// Initialize Array from a JSON String + public init?(JSONString: String, context: MapContext? = nil) { + if let obj: [Element] = Mapper(context: context).mapArray(JSONString: JSONString) { + self = obj + } else { + return nil + } + } + + /// Initialize Array from a JSON Array + public init?(JSONArray: [[String: Any]], context: MapContext? = nil) { + if let obj: [Element] = Mapper(context: context).mapArray(JSONArray: JSONArray) { + self = obj + } else { + return nil + } + } + + /// Returns the JSON Array + public func toJSON() -> [[String: Any]] { + return Mapper().toJSONArray(self) + } + + /// Returns the JSON String for the object + public func toJSONString(prettyPrint: Bool = false) -> String? { + return Mapper().toJSONString(self, prettyPrint: prettyPrint) + } +} + +public extension Set where Element: BaseMappable { + + /// Initializes a set from a JSON String + public init?(JSONString: String, context: MapContext? = nil) { + if let obj: Set = Mapper(context: context).mapSet(JSONString: JSONString) { + self = obj + } else { + return nil + } + } + + /// Initializes a set from JSON + public init?(JSONArray: [[String: Any]], context: MapContext? = nil) { + guard let obj = Mapper(context: context).mapSet(JSONArray: JSONArray) as Set? else { + return nil + } + self = obj + } + + /// Returns the JSON Set + public func toJSON() -> [[String: Any]] { + return Mapper().toJSONSet(self) + } + + /// Returns the JSON String for the object + public func toJSONString(prettyPrint: Bool = false) -> String? { + return Mapper().toJSONString(self, prettyPrint: prettyPrint) + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mapper.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mapper.swift new file mode 100755 index 0000000..ec57ef5 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Mapper.swift @@ -0,0 +1,430 @@ +// +// Mapper.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-09. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public enum MappingType { + case fromJSON + case toJSON +} + +/// The Mapper class provides methods for converting Model objects to JSON and methods for converting JSON to Model objects +public final class Mapper { + + public var context: MapContext? + + public init(context: MapContext? = nil){ + self.context = context + } + + // MARK: Mapping functions that map to an existing object toObject + + /// Maps a JSON object to an existing Mappable object if it is a JSON dictionary, or returns the passed object as is + public func map(JSONObject: Any?, toObject object: N) -> N { + if let JSON = JSONObject as? [String: Any] { + return map(JSON: JSON, toObject: object) + } + + return object + } + + /// Map a JSON string onto an existing object + public func map(JSONString: String, toObject object: N) -> N { + if let JSON = Mapper.parseJSONStringIntoDictionary(JSONString: JSONString) { + return map(JSON: JSON, toObject: object) + } + return object + } + + /// Maps a JSON dictionary to an existing object that conforms to Mappable. + /// Usefull for those pesky objects that have crappy designated initializers like NSManagedObject + public func map(JSON: [String: Any], toObject object: N) -> N { + var mutableObject = object + let map = Map(mappingType: .fromJSON, JSON: JSON, toObject: true, context: context) + mutableObject.mapping(map: map) + return mutableObject + } + + //MARK: Mapping functions that create an object + + /// Map a JSON string to an object that conforms to Mappable + public func map(JSONString: String) -> N? { + if let JSON = Mapper.parseJSONStringIntoDictionary(JSONString: JSONString) { + return map(JSON: JSON) + } + + return nil + } + + /// Maps a JSON object to a Mappable object if it is a JSON dictionary or NSString, or returns nil. + public func map(JSONObject: Any?) -> N? { + if let JSON = JSONObject as? [String: Any] { + return map(JSON: JSON) + } + + return nil + } + + /// Maps a JSON dictionary to an object that conforms to Mappable + public func map(JSON: [String: Any]) -> N? { + let map = Map(mappingType: .fromJSON, JSON: JSON, context: context) + + // check if object is StaticMappable + if let klass = N.self as? StaticMappable.Type { + if var object = klass.objectForMapping(map: map) as? N { + object.mapping(map: map) + return object + } + } + + // fall back to using init? to create N + if let klass = N.self as? Mappable.Type { + if var object = klass.init(map: map) as? N { + object.mapping(map: map) + return object + } + } + + return nil + } + + // MARK: Mapping functions for Arrays and Dictionaries + + /// Maps a JSON array to an object that conforms to Mappable + public func mapArray(JSONString: String) -> [N]? { + let parsedJSON: Any? = Mapper.parseJSONString(JSONString: JSONString) + + if let objectArray = mapArray(JSONObject: parsedJSON) { + return objectArray + } + + // failed to parse JSON into array form + // try to parse it into a dictionary and then wrap it in an array + if let object = map(JSONObject: parsedJSON) { + return [object] + } + + return nil + } + + /// Maps a JSON object to an array of Mappable objects if it is an array of JSON dictionary, or returns nil. + public func mapArray(JSONObject: Any?) -> [N]? { + if let JSONArray = JSONObject as? [[String: Any]] { + return mapArray(JSONArray: JSONArray) + } + + return nil + } + + /// Maps an array of JSON dictionary to an array of Mappable objects + public func mapArray(JSONArray: [[String: Any]]) -> [N]? { + // map every element in JSON array to type N + let result = JSONArray.flatMap(map) + return result + } + + /// Maps a JSON object to a dictionary of Mappable objects if it is a JSON dictionary of dictionaries, or returns nil. + public func mapDictionary(JSONString: String) -> [String: N]? { + let parsedJSON: Any? = Mapper.parseJSONString(JSONString: JSONString) + return mapDictionary(JSONObject: parsedJSON) + } + + /// Maps a JSON object to a dictionary of Mappable objects if it is a JSON dictionary of dictionaries, or returns nil. + public func mapDictionary(JSONObject: Any?) -> [String: N]? { + if let JSON = JSONObject as? [String: [String: Any]] { + return mapDictionary(JSON: JSON) + } + + return nil + } + + /// Maps a JSON dictionary of dictionaries to a dictionary of Mappble objects + public func mapDictionary(JSON: [String: [String: Any]]) -> [String: N]? { + // map every value in dictionary to type N + let result = JSON.filterMap(map) + if result.isEmpty == false { + return result + } + + return nil + } + + /// Maps a JSON object to a dictionary of Mappable objects if it is a JSON dictionary of dictionaries, or returns nil. + public func mapDictionary(JSONObject: Any?, toDictionary dictionary: [String: N]) -> [String: N] { + if let JSON = JSONObject as? [String : [String : Any]] { + return mapDictionary(JSON: JSON, toDictionary: dictionary) + } + + return dictionary + } + + /// Maps a JSON dictionary of dictionaries to an existing dictionary of Mappble objects + public func mapDictionary(JSON: [String: [String: Any]], toDictionary dictionary: [String: N]) -> [String: N] { + var mutableDictionary = dictionary + for (key, value) in JSON { + if let object = dictionary[key] { + _ = map(JSON: value, toObject: object) + } else { + mutableDictionary[key] = map(JSON: value) + } + } + + return mutableDictionary + } + + /// Maps a JSON object to a dictionary of arrays of Mappable objects + public func mapDictionaryOfArrays(JSONObject: Any?) -> [String: [N]]? { + if let JSON = JSONObject as? [String: [[String: Any]]] { + return mapDictionaryOfArrays(JSON: JSON) + } + + return nil + } + + ///Maps a JSON dictionary of arrays to a dictionary of arrays of Mappable objects + public func mapDictionaryOfArrays(JSON: [String: [[String: Any]]]) -> [String: [N]]? { + // map every value in dictionary to type N + let result = JSON.filterMap { + mapArray(JSONArray: $0) + } + + if result.isEmpty == false { + return result + } + + return nil + } + + /// Maps an 2 dimentional array of JSON dictionaries to a 2 dimentional array of Mappable objects + public func mapArrayOfArrays(JSONObject: Any?) -> [[N]]? { + if let JSONArray = JSONObject as? [[[String: Any]]] { + var objectArray = [[N]]() + for innerJSONArray in JSONArray { + if let array = mapArray(JSONArray: innerJSONArray){ + objectArray.append(array) + } + } + + if objectArray.isEmpty == false { + return objectArray + } + } + + return nil + } + + // MARK: Utility functions for converting strings to JSON objects + + /// Convert a JSON String into a Dictionary using NSJSONSerialization + public static func parseJSONStringIntoDictionary(JSONString: String) -> [String: Any]? { + let parsedJSON: Any? = Mapper.parseJSONString(JSONString: JSONString) + return parsedJSON as? [String: Any] + } + + /// Convert a JSON String into an Object using NSJSONSerialization + public static func parseJSONString(JSONString: String) -> Any? { + let data = JSONString.data(using: String.Encoding.utf8, allowLossyConversion: true) + if let data = data { + let parsedJSON: Any? + do { + parsedJSON = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) + } catch let error { + print(error) + parsedJSON = nil + } + return parsedJSON + } + + return nil + } +} + +extension Mapper { + + // MARK: Functions that create JSON from objects + + ///Maps an object that conforms to Mappable to a JSON dictionary + public func toJSON(_ object: N) -> [String: Any] { + var mutableObject = object + let map = Map(mappingType: .toJSON, JSON: [:], context: context) + mutableObject.mapping(map: map) + return map.JSON + } + + ///Maps an array of Objects to an array of JSON dictionaries [[String: Any]] + public func toJSONArray(_ array: [N]) -> [[String: Any]] { + return array.map { + // convert every element in array to JSON dictionary equivalent + self.toJSON($0) + } + } + + ///Maps a dictionary of Objects that conform to Mappable to a JSON dictionary of dictionaries. + public func toJSONDictionary(_ dictionary: [String: N]) -> [String: [String: Any]] { + return dictionary.map { k, v in + // convert every value in dictionary to its JSON dictionary equivalent + return (k, self.toJSON(v)) + } + } + + ///Maps a dictionary of Objects that conform to Mappable to a JSON dictionary of dictionaries. + public func toJSONDictionaryOfArrays(_ dictionary: [String: [N]]) -> [String: [[String: Any]]] { + return dictionary.map { k, v in + // convert every value (array) in dictionary to its JSON dictionary equivalent + return (k, self.toJSONArray(v)) + } + } + + /// Maps an Object to a JSON string with option of pretty formatting + public func toJSONString(_ object: N, prettyPrint: Bool = false) -> String? { + let JSONDict = toJSON(object) + + return Mapper.toJSONString(JSONDict as Any, prettyPrint: prettyPrint) + } + + /// Maps an array of Objects to a JSON string with option of pretty formatting + public func toJSONString(_ array: [N], prettyPrint: Bool = false) -> String? { + let JSONDict = toJSONArray(array) + + return Mapper.toJSONString(JSONDict as Any, prettyPrint: prettyPrint) + } + + /// Converts an Object to a JSON string with option of pretty formatting + public static func toJSONString(_ JSONObject: Any, prettyPrint: Bool) -> String? { + let options: JSONSerialization.WritingOptions = prettyPrint ? .prettyPrinted : [] + if let JSON = Mapper.toJSONData(JSONObject, options: options) { + return String(data: JSON, encoding: String.Encoding.utf8) + } + + return nil + } + + /// Converts an Object to JSON data with options + public static func toJSONData(_ JSONObject: Any, options: JSONSerialization.WritingOptions) -> Data? { + if JSONSerialization.isValidJSONObject(JSONObject) { + let JSONData: Data? + do { + JSONData = try JSONSerialization.data(withJSONObject: JSONObject, options: options) + } catch let error { + print(error) + JSONData = nil + } + + return JSONData + } + + return nil + } +} + +extension Mapper where N: Hashable { + + /// Maps a JSON array to an object that conforms to Mappable + public func mapSet(JSONString: String) -> Set? { + let parsedJSON: Any? = Mapper.parseJSONString(JSONString: JSONString) + + if let objectArray = mapArray(JSONObject: parsedJSON) { + return Set(objectArray) + } + + // failed to parse JSON into array form + // try to parse it into a dictionary and then wrap it in an array + if let object = map(JSONObject: parsedJSON) { + return Set([object]) + } + + return nil + } + + /// Maps a JSON object to an Set of Mappable objects if it is an array of JSON dictionary, or returns nil. + public func mapSet(JSONObject: Any?) -> Set? { + if let JSONArray = JSONObject as? [[String: Any]] { + return mapSet(JSONArray: JSONArray) + } + + return nil + } + + /// Maps an Set of JSON dictionary to an array of Mappable objects + public func mapSet(JSONArray: [[String: Any]]) -> Set { + // map every element in JSON array to type N + return Set(JSONArray.flatMap(map)) + } + + ///Maps a Set of Objects to a Set of JSON dictionaries [[String : Any]] + public func toJSONSet(_ set: Set) -> [[String: Any]] { + return set.map { + // convert every element in set to JSON dictionary equivalent + self.toJSON($0) + } + } + + /// Maps a set of Objects to a JSON string with option of pretty formatting + public func toJSONString(_ set: Set, prettyPrint: Bool = false) -> String? { + let JSONDict = toJSONSet(set) + + return Mapper.toJSONString(JSONDict as Any, prettyPrint: prettyPrint) + } +} + +extension Dictionary { + internal func map(_ f: (Element) -> (K, V)) -> [K: V] { + var mapped = [K: V]() + + for element in self { + let newElement = f(element) + mapped[newElement.0] = newElement.1 + } + + return mapped + } + + internal func map(_ f: (Element) -> (K, [V])) -> [K: [V]] { + var mapped = [K: [V]]() + + for element in self { + let newElement = f(element) + mapped[newElement.0] = newElement.1 + } + + return mapped + } + + + internal func filterMap(_ f: (Value) -> U?) -> [Key: U] { + var mapped = [Key: U]() + + for (key, value) in self { + if let newValue = f(value) { + mapped[key] = newValue + } + } + + return mapped + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/EnumOperators.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/EnumOperators.swift new file mode 100644 index 0000000..5a1a667 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/EnumOperators.swift @@ -0,0 +1,91 @@ +// +// EnumOperators.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2016-09-26. +// Copyright © 2016 hearst. All rights reserved. +// + +import Foundation + + +// MARK:- Raw Representable types + +/// Object of Raw Representable type +public func <- (left: inout T, right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: T, right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Optional Object of Raw Representable type +public func <- (left: inout T?, right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: T?, right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Implicitly Unwrapped Optional Object of Raw Representable type +public func <- (left: inout T!, right: Map) { + left <- (right, EnumTransform()) +} + +// MARK:- Arrays of Raw Representable type + +/// Array of Raw Representable object +public func <- (left: inout [T], right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: [T], right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Array of Raw Representable object +public func <- (left: inout [T]?, right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: [T]?, right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Array of Raw Representable object +public func <- (left: inout [T]!, right: Map) { + left <- (right, EnumTransform()) +} + +// MARK:- Dictionaries of Raw Representable type + +/// Dictionary of Raw Representable object +public func <- (left: inout [String: T], right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: [String: T], right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Dictionary of Raw Representable object +public func <- (left: inout [String: T]?, right: Map) { + left <- (right, EnumTransform()) +} + +public func >>> (left: [String: T]?, right: Map) { + left >>> (right, EnumTransform()) +} + + +/// Dictionary of Raw Representable object +public func <- (left: inout [String: T]!, right: Map) { + left <- (right, EnumTransform()) +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/Operators.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/Operators.swift new file mode 100755 index 0000000..57741f8 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/Operators.swift @@ -0,0 +1,377 @@ +// +// Operators.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-09. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** +* This file defines a new operator which is used to create a mapping between an object and a JSON key value. +* There is an overloaded operator definition for each type of object that is supported in ObjectMapper. +* This provides a way to add custom logic to handle specific types of objects +*/ + +/// Operator used for defining mappings to and from JSON +infix operator <- + +/// Operator used to define mappings to JSON +infix operator >>> + +// MARK:- Objects with Basic types + +/// Object of Basic type +public func <- (left: inout T, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.basicType(&left, object: right.value()) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: T, right: Map) { + if right.mappingType == .toJSON { + ToJSON.basicType(left, map: right) + } +} + + +/// Optional object of basic type +public func <- (left: inout T?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalBasicType(&left, object: right.value()) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: T?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalBasicType(left, map: right) + } +} + + +/// Implicitly unwrapped optional object of basic type +public func <- (left: inout T!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalBasicType(&left, object: right.value()) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Mappable Objects - + +/// Object conforming to Mappable +public func <- (left: inout T, right: Map) { + switch right.mappingType { + case .fromJSON: + FromJSON.object(&left, map: right) + case .toJSON: + left >>> right + } +} + +public func >>> (left: T, right: Map) { + if right.mappingType == .toJSON { + ToJSON.object(left, map: right) + } +} + + +/// Optional Mappable objects +public func <- (left: inout T?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObject(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: T?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalObject(left, map: right) + } +} + + +/// Implicitly unwrapped optional Mappable objects +public func <- (left: inout T!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObject(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Dictionary of Mappable objects - Dictionary + +/// Dictionary of Mappable objects +public func <- (left: inout Dictionary, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.objectDictionary(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Dictionary, right: Map) { + if right.mappingType == .toJSON { + ToJSON.objectDictionary(left, map: right) + } +} + + +/// Optional Dictionary of Mappable object +public func <- (left: inout Dictionary?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectDictionary(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Dictionary?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalObjectDictionary(left, map: right) + } +} + + +/// Implicitly unwrapped Optional Dictionary of Mappable object +public func <- (left: inout Dictionary!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectDictionary(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +/// Dictionary of Mappable objects +public func <- (left: inout Dictionary, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.objectDictionaryOfArrays(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Dictionary, right: Map) { + if right.mappingType == .toJSON { + ToJSON.objectDictionaryOfArrays(left, map: right) + } +} + +/// Optional Dictionary of Mappable object +public func <- (left: inout Dictionary?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectDictionaryOfArrays(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Dictionary?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalObjectDictionaryOfArrays(left, map: right) + } +} + + +/// Implicitly unwrapped Optional Dictionary of Mappable object +public func <- (left: inout Dictionary!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectDictionaryOfArrays(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Array of Mappable objects - Array + +/// Array of Mappable objects +public func <- (left: inout Array, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.objectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array, right: Map) { + if right.mappingType == .toJSON { + ToJSON.objectArray(left, map: right) + } +} + +/// Optional array of Mappable objects +public func <- (left: inout Array?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalObjectArray(left, map: right) + } +} + + +/// Implicitly unwrapped Optional array of Mappable objects +public func <- (left: inout Array!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Array of Array of Mappable objects - Array> + +/// Array of Array Mappable objects +public func <- (left: inout Array>, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.twoDimensionalObjectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array>, right: Map) { + if right.mappingType == .toJSON { + ToJSON.twoDimensionalObjectArray(left, map: right) + } +} + + +/// Optional array of Mappable objects +public func <- (left:inout Array>?, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalTwoDimensionalObjectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array>?, right: Map) { + if right.mappingType == .toJSON { + ToJSON.optionalTwoDimensionalObjectArray(left, map: right) + } +} + + +/// Implicitly unwrapped Optional array of Mappable objects +public func <- (left: inout Array>!, right: Map) { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalTwoDimensionalObjectArray(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Set of Mappable objects - Set + +/// Set of Mappable objects +public func <- (left: inout Set, right: Map) where T: Hashable { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.objectSet(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Set, right: Map) where T: Hashable { + if right.mappingType == .toJSON { + ToJSON.objectSet(left, map: right) + } +} + + +/// Optional Set of Mappable objects +public func <- (left: inout Set?, right: Map) where T: Hashable, T: Hashable { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectSet(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Set?, right: Map) where T: Hashable, T: Hashable { + if right.mappingType == .toJSON { + ToJSON.optionalObjectSet(left, map: right) + } +} + + +/// Implicitly unwrapped Optional Set of Mappable objects +public func <- (left: inout Set!, right: Map) where T: Hashable { + switch right.mappingType { + case .fromJSON where right.isKeyPresent: + FromJSON.optionalObjectSet(&left, map: right) + case .toJSON: + left >>> right + default: () + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/TransformOperators.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/TransformOperators.swift new file mode 100644 index 0000000..dbe5ad2 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/Operators/TransformOperators.swift @@ -0,0 +1,606 @@ +// +// TransformOperators.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2016-09-26. +// Copyright © 2016 hearst. All rights reserved. +// + +import Foundation + +// MARK:- Transforms + +/// Object of Basic type with Transform +public func <- (left: inout Transform.Object, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value = transform.transformFromJSON(map.currentValue) + FromJSON.basicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Transform.Object, right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == .toJSON { + let value: Transform.JSON? = transform.transformToJSON(left) + ToJSON.optionalBasicType(value, map: map) + } +} + + +/// Optional object of basic type with Transform +public func <- (left: inout Transform.Object?, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value = transform.transformFromJSON(map.currentValue) + FromJSON.optionalBasicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Transform.Object?, right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == .toJSON { + let value: Transform.JSON? = transform.transformToJSON(left) + ToJSON.optionalBasicType(value, map: map) + } +} + + +/// Implicitly unwrapped optional object of basic type with Transform +public func <- (left: inout Transform.Object!, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value = transform.transformFromJSON(map.currentValue) + FromJSON.optionalBasicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + +/// Array of Basic type with Transform +public func <- (left: inout [Transform.Object], right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONArrayWithTransform(map.currentValue, transform: transform) + FromJSON.basicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: [Transform.Object], right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == .toJSON{ + let values = toJSONArrayWithTransform(left, transform: transform) + ToJSON.optionalBasicType(values, map: map) + } +} + + +/// Optional array of Basic type with Transform +public func <- (left: inout [Transform.Object]?, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONArrayWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: [Transform.Object]?, right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == .toJSON { + let values = toJSONArrayWithTransform(left, transform: transform) + ToJSON.optionalBasicType(values, map: map) + } +} + + +/// Implicitly unwrapped optional array of Basic type with Transform +public func <- (left: inout [Transform.Object]!, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONArrayWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +/// Dictionary of Basic type with Transform +public func <- (left: inout [String: Transform.Object], right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform) + FromJSON.basicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: [String: Transform.Object], right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == . toJSON { + let values = toJSONDictionaryWithTransform(left, transform: transform) + ToJSON.optionalBasicType(values, map: map) + } +} + + +/// Optional dictionary of Basic type with Transform +public func <- (left: inout [String: Transform.Object]?, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: [String: Transform.Object]?, right: (Map, Transform)) { + let (map, transform) = right + if map.mappingType == .toJSON { + let values = toJSONDictionaryWithTransform(left, transform: transform) + ToJSON.optionalBasicType(values, map: map) + } +} + + +/// Implicitly unwrapped optional dictionary of Basic type with Transform +public func <- (left: inout [String: Transform.Object]!, right: (Map, Transform)) { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: values) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Transforms of Mappable Objects - + +/// Object conforming to Mappable that have transforms +public func <- (left: inout Transform.Object, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value: Transform.Object? = transform.transformFromJSON(map.currentValue) + FromJSON.basicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Transform.Object, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let value: Transform.JSON? = transform.transformToJSON(left) + ToJSON.optionalBasicType(value, map: map) + } +} + + +/// Optional Mappable objects that have transforms +public func <- (left: inout Transform.Object?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value: Transform.Object? = transform.transformFromJSON(map.currentValue) + FromJSON.optionalBasicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Transform.Object?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON{ + let value: Transform.JSON? = transform.transformToJSON(left) + ToJSON.optionalBasicType(value, map: map) + } +} + + +/// Implicitly unwrapped optional Mappable objects that have transforms +public func <- (left: inout Transform.Object!, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let value: Transform.Object? = transform.transformFromJSON(map.currentValue) + FromJSON.optionalBasicType(&left, object: value) + case .toJSON: + left >>> right + default: () + } +} + + +// MARK:- Dictionary of Mappable objects with a transform - Dictionary + +/// Dictionary of Mappable objects with a transform +public func <- (left: inout Dictionary, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, + let object = map.currentValue as? [String: AnyObject] { + let value = fromJSONDictionaryWithTransform(object as AnyObject?, transform: transform) ?? left + FromJSON.basicType(&left, object: value) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Dictionary, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let value = toJSONDictionaryWithTransform(left, transform: transform) + ToJSON.basicType(value, map: map) + } +} + + +/// Optional Dictionary of Mappable object with a transform +public func <- (left: inout Dictionary?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, let object = map.currentValue as? [String : AnyObject]{ + let value = fromJSONDictionaryWithTransform(object as AnyObject?, transform: transform) ?? left + FromJSON.optionalBasicType(&left, object: value) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Dictionary?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let value = toJSONDictionaryWithTransform(left, transform: transform) + ToJSON.optionalBasicType(value, map: map) + } +} + + +/// Implicitly unwrapped Optional Dictionary of Mappable object with a transform +public func <- (left: inout Dictionary!, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, let dictionary = map.currentValue as? [String : AnyObject]{ + let transformedDictionary = fromJSONDictionaryWithTransform(dictionary as AnyObject?, transform: transform) ?? left + FromJSON.optionalBasicType(&left, object: transformedDictionary) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +/// Dictionary of Mappable objects with a transform +public func <- (left: inout Dictionary, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + + if let dictionary = map.currentValue as? [String : [AnyObject]], map.mappingType == .fromJSON && map.isKeyPresent { + let transformedDictionary = dictionary.map { (key: String, values: [AnyObject]) -> (String, [Transform.Object]) in + if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) { + return (key, jsonArray) + } + if let leftValue = left[key] { + return (key, leftValue) + } + return (key, []) + } + + FromJSON.basicType(&left, object: transformedDictionary) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Dictionary, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + + if map.mappingType == .toJSON { + let transformedDictionary = left.map { (key, values) in + return (key, toJSONArrayWithTransform(values, transform: transform) ?? []) + } + + ToJSON.basicType(transformedDictionary, map: map) + } +} + + +/// Optional Dictionary of Mappable object with a transform +public func <- (left: inout Dictionary?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + + if let dictionary = map.currentValue as? [String : [AnyObject]], map.mappingType == .fromJSON && map.isKeyPresent { + + let transformedDictionary = dictionary.map { (key: String, values: [AnyObject]) -> (String, [Transform.Object]) in + if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) { + return (key, jsonArray) + } + if let leftValue = left?[key] { + return (key, leftValue) + } + return (key, []) + + } + + FromJSON.optionalBasicType(&left, object: transformedDictionary) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Dictionary?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + + if map.mappingType == .toJSON { + let transformedDictionary = left?.map { (key, values) in + return (key, toJSONArrayWithTransform(values, transform: transform) ?? []) + } + + ToJSON.optionalBasicType(transformedDictionary, map: map) + } +} + + +/// Implicitly unwrapped Optional Dictionary of Mappable object with a transform +public func <- (left: inout Dictionary!, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + + if let dictionary = map.currentValue as? [String : [AnyObject]], map.mappingType == .fromJSON && map.isKeyPresent { + let transformedDictionary = dictionary.map { (key: String, values: [AnyObject]) -> (String, [Transform.Object]) in + if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) { + return (key, jsonArray) + } + if let leftValue = left?[key] { + return (key, leftValue) + } + return (key, []) + } + FromJSON.optionalBasicType(&left, object: transformedDictionary) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +// MARK:- Array of Mappable objects with transforms - Array + +/// Array of Mappable objects +public func <- (left: inout Array, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) { + FromJSON.basicType(&left, object: transformedValues) + } + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let transformedValues = toJSONArrayWithTransform(left, transform: transform) + ToJSON.optionalBasicType(transformedValues, map: map) + } +} + + +/// Optional array of Mappable objects +public func <- (left: inout Array?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: transformedValues) + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Array?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let transformedValues = toJSONArrayWithTransform(left, transform: transform) + ToJSON.optionalBasicType(transformedValues, map: map) + } +} + + +/// Implicitly unwrapped Optional array of Mappable objects +public func <- (left: inout Array!, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) + FromJSON.optionalBasicType(&left, object: transformedValues) + case .toJSON: + left >>> right + default: () + } +} + +// MARK:- Array of Array of Mappable objects - Array>> with transforms + +/// Array of Array Mappable objects with transform +public func <- (left: inout Array>, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, let original2DArray = map.currentValue as? [[AnyObject]]{ + let transformed2DArray = original2DArray.flatMap { values in + fromJSONArrayWithTransform(values as AnyObject?, transform: transform) + } + FromJSON.basicType(&left, object: transformed2DArray) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Array>, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let transformed2DArray = left.flatMap { values in + toJSONArrayWithTransform(values, transform: transform) + } + ToJSON.basicType(transformed2DArray, map: map) + } +} + + +/// Optional array of Mappable objects with transform +public func <- (left:inout Array>?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, let original2DArray = map.currentValue as? [[AnyObject]]{ + let transformed2DArray = original2DArray.flatMap { values in + fromJSONArrayWithTransform(values as AnyObject?, transform: transform) + } + FromJSON.optionalBasicType(&left, object: transformed2DArray) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +public func >>> (left: Array>?, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let transformed2DArray = left?.flatMap { values in + toJSONArrayWithTransform(values, transform: transform) + } + ToJSON.optionalBasicType(transformed2DArray, map: map) + } +} + + +/// Implicitly unwrapped Optional array of Mappable objects with transform +public func <- (left: inout Array>!, right: (Map, Transform)) where Transform.Object: BaseMappable { + let (map, transform) = right + if map.mappingType == .fromJSON && map.isKeyPresent, let original2DArray = map.currentValue as? [[AnyObject]] { + let transformed2DArray = original2DArray.flatMap { values in + fromJSONArrayWithTransform(values as AnyObject?, transform: transform) + } + FromJSON.optionalBasicType(&left, object: transformed2DArray) + } else if map.mappingType == .toJSON { + left >>> right + } +} + +// MARK:- Set of Mappable objects with a transform - Set + +/// Set of Mappable objects with transform +public func <- (left: inout Set, right: (Map, Transform)) where Transform.Object: Hashable & BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) { + FromJSON.basicType(&left, object: Set(transformedValues)) + } + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Set, right: (Map, Transform)) where Transform.Object: Hashable & BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + let transformedValues = toJSONArrayWithTransform(Array(left), transform: transform) + ToJSON.optionalBasicType(transformedValues, map: map) + } +} + + +/// Optional Set of Mappable objects with transform +public func <- (left: inout Set?, right: (Map, Transform)) where Transform.Object: Hashable & BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) { + FromJSON.basicType(&left, object: Set(transformedValues)) + } + case .toJSON: + left >>> right + default: () + } +} + +public func >>> (left: Set?, right: (Map, Transform)) where Transform.Object: Hashable & BaseMappable { + let (map, transform) = right + if map.mappingType == .toJSON { + if let values = left { + let transformedValues = toJSONArrayWithTransform(Array(values), transform: transform) + ToJSON.optionalBasicType(transformedValues, map: map) + } + } +} + + +/// Implicitly unwrapped Optional set of Mappable objects with transform +public func <- (left: inout Set!, right: (Map, Transform)) where Transform.Object: Hashable & BaseMappable { + let (map, transform) = right + switch map.mappingType { + case .fromJSON where map.isKeyPresent: + if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) { + FromJSON.basicType(&left, object: Set(transformedValues)) + } + case .toJSON: + left >>> right + default: () + } +} + + +private func fromJSONArrayWithTransform(_ input: Any?, transform: Transform) -> [Transform.Object]? { + if let values = input as? [AnyObject] { + return values.flatMap { value in + return transform.transformFromJSON(value) + } + } else { + return nil + } +} + +private func fromJSONDictionaryWithTransform(_ input: Any?, transform: Transform) -> [String: Transform.Object]? { + if let values = input as? [String: AnyObject] { + return values.filterMap { value in + return transform.transformFromJSON(value) + } + } else { + return nil + } +} + +private func toJSONArrayWithTransform(_ input: [Transform.Object]?, transform: Transform) -> [Transform.JSON]? { + return input?.flatMap { value in + return transform.transformToJSON(value) + } +} + +private func toJSONDictionaryWithTransform(_ input: [String: Transform.Object]?, transform: Transform) -> [String: Transform.JSON]? { + return input?.filterMap { value in + return transform.transformToJSON(value) + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ToJSON.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ToJSON.swift new file mode 100644 index 0000000..cdb2960 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Core/ToJSON.swift @@ -0,0 +1,176 @@ +// +// ToJSON.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-13. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import class Foundation.NSNumber + +private func setValue(_ value: Any, map: Map) { + setValue(value, key: map.currentKey!, checkForNestedKeys: map.keyIsNested, dictionary: &map.JSON) +} + +private func setValue(_ value: Any, key: String, checkForNestedKeys: Bool, dictionary: inout [String : Any]) { + if checkForNestedKeys { + let keyComponents = ArraySlice(key.characters.split { $0 == "." }) + setValue(value, forKeyPathComponents: keyComponents, dictionary: &dictionary) + } else { + dictionary[key] = value + } +} + +private func setValue(_ value: Any, forKeyPathComponents components: ArraySlice, dictionary: inout [String : Any]) { + if components.isEmpty { + return + } + + let head = components.first! + + if components.count == 1 { + dictionary[String(head)] = value + } else { + var child = dictionary[String(head)] as? [String : Any] + if child == nil { + child = [:] + } + + let tail = components.dropFirst() + setValue(value, forKeyPathComponents: tail, dictionary: &child!) + + dictionary[String(head)] = child + } +} + +internal final class ToJSON { + + class func basicType(_ field: N, map: Map) { + if let x = field as Any? , false + || x is NSNumber // Basic types + || x is Bool + || x is Int + || x is Double + || x is Float + || x is String + || x is Array // Arrays + || x is Array + || x is Array + || x is Array + || x is Array + || x is Array + || x is Array + || x is Array> + || x is Dictionary // Dictionaries + || x is Dictionary + || x is Dictionary + || x is Dictionary + || x is Dictionary + || x is Dictionary + || x is Dictionary + { + setValue(x, map: map) + } + } + + class func optionalBasicType(_ field: N?, map: Map) { + if let field = field { + basicType(field, map: map) + } + } + + class func object(_ field: N, map: Map) { + if let result = Mapper(context: map.context).toJSON(field) as Any? { + setValue(result, map: map) + } + } + + class func optionalObject(_ field: N?, map: Map) { + if let field = field { + object(field, map: map) + } + } + + class func objectArray(_ field: Array, map: Map) { + let JSONObjects = Mapper(context: map.context).toJSONArray(field) + + setValue(JSONObjects, map: map) + } + + class func optionalObjectArray(_ field: Array?, map: Map) { + if let field = field { + objectArray(field, map: map) + } + } + + class func twoDimensionalObjectArray(_ field: Array>, map: Map) { + var array = [[[String: Any]]]() + for innerArray in field { + let JSONObjects = Mapper(context: map.context).toJSONArray(innerArray) + array.append(JSONObjects) + } + setValue(array, map: map) + } + + class func optionalTwoDimensionalObjectArray(_ field: Array>?, map: Map) { + if let field = field { + twoDimensionalObjectArray(field, map: map) + } + } + + class func objectSet(_ field: Set, map: Map) where N: Hashable { + let JSONObjects = Mapper(context: map.context).toJSONSet(field) + + setValue(JSONObjects, map: map) + } + + class func optionalObjectSet(_ field: Set?, map: Map) where N: Hashable { + if let field = field { + objectSet(field, map: map) + } + } + + class func objectDictionary(_ field: Dictionary, map: Map) { + let JSONObjects = Mapper(context: map.context).toJSONDictionary(field) + + setValue(JSONObjects, map: map) + } + + class func optionalObjectDictionary(_ field: Dictionary?, map: Map) { + if let field = field { + objectDictionary(field, map: map) + } + } + + class func objectDictionaryOfArrays(_ field: Dictionary, map: Map) { + let JSONObjects = Mapper(context: map.context).toJSONDictionaryOfArrays(field) + + setValue(JSONObjects, map: map) + } + + class func optionalObjectDictionaryOfArrays(_ field: Dictionary?, map: Map) { + if let field = field { + objectDictionaryOfArrays(field, map: map) + } + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/CustomDateFormatTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/CustomDateFormatTransform.swift new file mode 100644 index 0000000..3cd5c59 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/CustomDateFormatTransform.swift @@ -0,0 +1,40 @@ +// +// CustomDateFormatTransform.swift +// ObjectMapper +// +// Created by Dan McCracken on 3/8/15. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class CustomDateFormatTransform: DateFormatterTransform { + + public init(formatString: String) { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.dateFormat = formatString + + super.init(dateFormatter: formatter) + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DataTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DataTransform.swift new file mode 100644 index 0000000..d96f3d6 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DataTransform.swift @@ -0,0 +1,50 @@ +// +// DataTransform.swift +// ObjectMapper +// +// Created by Yagrushkin, Evgeny on 8/30/16. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class DataTransform: TransformType { + public typealias Object = Data + public typealias JSON = String + + public init() {} + + open func transformFromJSON(_ value: Any?) -> Data? { + guard let string = value as? String else{ + return nil + } + return Data(base64Encoded: string) + } + + open func transformToJSON(_ value: Data?) -> String? { + guard let data = value else{ + return nil + } + return data.base64EncodedString() + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateFormatterTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateFormatterTransform.swift new file mode 100644 index 0000000..77c6e2b --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateFormatterTransform.swift @@ -0,0 +1,54 @@ +// +// DateFormatterTransform.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2015-03-09. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class DateFormatterTransform: TransformType { + public typealias Object = Date + public typealias JSON = String + + let dateFormatter: DateFormatter + + public init(dateFormatter: DateFormatter) { + self.dateFormatter = dateFormatter + } + + open func transformFromJSON(_ value: Any?) -> Date? { + if let dateString = value as? String { + return dateFormatter.date(from: dateString) + } + return nil + } + + open func transformToJSON(_ value: Date?) -> String? { + if let date = value { + return dateFormatter.string(from: date) + } + return nil + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateTransform.swift new file mode 100644 index 0000000..2c175cb --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DateTransform.swift @@ -0,0 +1,55 @@ +// +// DateTransform.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-13. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class DateTransform: TransformType { + public typealias Object = Date + public typealias JSON = Double + + public init() {} + + open func transformFromJSON(_ value: Any?) -> Date? { + if let timeInt = value as? Double { + return Date(timeIntervalSince1970: TimeInterval(timeInt)) + } + + if let timeStr = value as? String { + return Date(timeIntervalSince1970: TimeInterval(atof(timeStr))) + } + + return nil + } + + open func transformToJSON(_ value: Date?) -> Double? { + if let date = value { + return Double(date.timeIntervalSince1970) + } + return nil + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DictionaryTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DictionaryTransform.swift new file mode 100644 index 0000000..e7b6ef3 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/DictionaryTransform.swift @@ -0,0 +1,58 @@ +// +// DictionaryTransform.swift +// ObjectMapper +// +// Created by Milen Halachev on 7/20/16. +// Copyright © 2016 hearst. All rights reserved. +// + +import Foundation + +///Transforms [String: AnyObject] <-> [Key: Value] where Key is RawRepresentable as String, Value is Mappable +public struct DictionaryTransform: TransformType where Key: Hashable, Key: RawRepresentable, Key.RawValue == String, Value: Mappable { + + public init() { + + } + + public func transformFromJSON(_ value: Any?) -> [Key: Value]? { + + guard let json = value as? [String: Any] else { + + return nil + } + + let result = json.reduce([:]) { (result, element) -> [Key: Value] in + + guard + let key = Key(rawValue: element.0), + let valueJSON = element.1 as? [String: Any], + let value = Value(JSON: valueJSON) + else { + + return result + } + + var result = result + result[key] = value + return result + } + + return result + } + + public func transformToJSON(_ value: [Key: Value]?) -> Any? { + + let result = value?.reduce([:]) { (result, element) -> [String: Any] in + + let key = element.0.rawValue + let value = element.1.toJSON() + + var result = result + result[key] = value + return result + } + + return result + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/EnumTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/EnumTransform.swift new file mode 100644 index 0000000..43e4ce7 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/EnumTransform.swift @@ -0,0 +1,50 @@ +// +// EnumTransform.swift +// ObjectMapper +// +// Created by Kaan Dedeoglu on 3/20/15. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class EnumTransform: TransformType { + public typealias Object = T + public typealias JSON = T.RawValue + + public init() {} + + open func transformFromJSON(_ value: Any?) -> T? { + if let raw = value as? T.RawValue { + return T(rawValue: raw) + } + return nil + } + + open func transformToJSON(_ value: T?) -> T.RawValue? { + if let obj = value { + return obj.rawValue + } + return nil + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/ISO8601DateTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/ISO8601DateTransform.swift new file mode 100644 index 0000000..5a17b73 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/ISO8601DateTransform.swift @@ -0,0 +1,41 @@ +// +// ISO8601DateTransform.swift +// ObjectMapper +// +// Created by Jean-Pierre Mouilleseaux on 21 Nov 2014. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class ISO8601DateTransform: DateFormatterTransform { + + public init() { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" + + super.init(dateFormatter: formatter) + } + +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/NSDecimalNumberTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/NSDecimalNumberTransform.swift new file mode 100644 index 0000000..3b3ebab --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/NSDecimalNumberTransform.swift @@ -0,0 +1,51 @@ +// +// TransformOf.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 8/22/16. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class NSDecimalNumberTransform: TransformType { + public typealias Object = NSDecimalNumber + public typealias JSON = String + + public init() {} + + open func transformFromJSON(_ value: Any?) -> NSDecimalNumber? { + if let string = value as? String { + return NSDecimalNumber(string: string) + } + if let double = value as? Double { + return NSDecimalNumber(value: double) + } + return nil + } + + open func transformToJSON(_ value: NSDecimalNumber?) -> String? { + guard let value = value else { return nil } + return value.description + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformOf.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformOf.swift new file mode 100644 index 0000000..97056c6 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformOf.swift @@ -0,0 +1,48 @@ +// +// TransformOf.swift +// ObjectMapper +// +// Created by Syo Ikeda on 1/23/15. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +open class TransformOf: TransformType { + public typealias Object = ObjectType + public typealias JSON = JSONType + + private let fromJSON: (JSONType?) -> ObjectType? + private let toJSON: (ObjectType?) -> JSONType? + + public init(fromJSON: @escaping(JSONType?) -> ObjectType?, toJSON: @escaping(ObjectType?) -> JSONType?) { + self.fromJSON = fromJSON + self.toJSON = toJSON + } + + open func transformFromJSON(_ value: Any?) -> ObjectType? { + return fromJSON(value as? JSONType) + } + + open func transformToJSON(_ value: ObjectType?) -> JSONType? { + return toJSON(value) + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformType.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformType.swift new file mode 100644 index 0000000..61578c3 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/TransformType.swift @@ -0,0 +1,35 @@ +// +// TransformType.swift +// ObjectMapper +// +// Created by Syo Ikeda on 2/4/15. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +public protocol TransformType { + associatedtype Object + associatedtype JSON + + func transformFromJSON(_ value: Any?) -> Object? + func transformToJSON(_ value: Object?) -> JSON? +} diff --git a/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/URLTransform.swift b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/URLTransform.swift new file mode 100644 index 0000000..4ef109f --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/ObjectMapper/Transforms/URLTransform.swift @@ -0,0 +1,65 @@ +// +// URLTransform.swift +// ObjectMapper +// +// Created by Tristan Himmelman on 2014-10-27. +// +// The MIT License (MIT) +// +// Copyright (c) 2014-2016 Hearst +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class URLTransform: TransformType { + public typealias Object = URL + public typealias JSON = String + private let shouldEncodeURLString: Bool + + /** + Initializes the URLTransform with an option to encode URL strings before converting them to an NSURL + - parameter shouldEncodeUrlString: when true (the default) the string is encoded before passing + to `NSURL(string:)` + - returns: an initialized transformer + */ + public init(shouldEncodeURLString: Bool = true) { + self.shouldEncodeURLString = shouldEncodeURLString + } + + open func transformFromJSON(_ value: Any?) -> URL? { + guard let URLString = value as? String else { return nil } + + if !shouldEncodeURLString { + return URL(string: URLString) + } + + guard let escapedURLString = URLString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else { + return nil + } + return URL(string: escapedURLString) + } + + open func transformToJSON(_ value: URL?) -> String? { + if let URL = value { + return URL.absoluteString + } + return nil + } +} diff --git a/iMessagesExample/Pods/ObjectMapper/README.md b/iMessagesExample/Pods/ObjectMapper/README.md new file mode 100644 index 0000000..89c24a7 --- /dev/null +++ b/iMessagesExample/Pods/ObjectMapper/README.md @@ -0,0 +1,472 @@ +ObjectMapper +============ +[![CocoaPods](https://img.shields.io/cocoapods/v/ObjectMapper.svg)](https://github.com/Hearst-DD/ObjectMapper) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Build Status](https://travis-ci.org/Hearst-DD/ObjectMapper.svg?branch=master)](https://travis-ci.org/Hearst-DD/ObjectMapper) + +ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from JSON. + +- [Features](#features) +- [The Basics](#the-basics) +- [Mapping Nested Objects](#easy-mapping-of-nested-objects) +- [Custom Transformations](#custom-transforms) +- [Subclassing](#subclasses) +- [Generic Objects](#generic-objects) +- [Mapping Context](#mapping-context) +- [ObjectMapper + Alamofire](#objectmapper--alamofire) +- [ObjectMapper + Realm](#objectmapper--realm) +- [To Do](#to-do) +- [Contributing](#contributing) +- [Installation](#installation) + +# Features: +- Mapping JSON to objects +- Mapping objects to JSON +- Nested Objects (stand alone, in arrays or in dictionaries) +- Custom transformations during mapping +- Struct support +- [Immutable support](#immutablemappable-protocol-beta) (currently in beta) + +# The Basics +To support mapping, a class or struct just needs to implement the ```Mappable``` protocol which includes the following functions: +```swift +init?(map: Map) +mutating func mapping(map: Map) +``` +ObjectMapper uses the ```<-``` operator to define how each member variable maps to and from JSON. + +```swift +class User: Mappable { + var username: String? + var age: Int? + var weight: Double! + var array: [AnyObject]? + var dictionary: [String : AnyObject] = [:] + var bestFriend: User? // Nested User object + var friends: [User]? // Array of Users + var birthday: NSDate? + + required init?(map: Map) { + + } + + // Mappable + func mapping(map: Map) { + username <- map["username"] + age <- map["age"] + weight <- map["weight"] + array <- map["arr"] + dictionary <- map["dict"] + bestFriend <- map["best_friend"] + friends <- map["friends"] + birthday <- (map["birthday"], DateTransform()) + } +} + +struct Temperature: Mappable { + var celsius: Double? + var fahrenheit: Double? + + init?(map: Map) { + + } + + mutating func mapping(map: Map) { + celsius <- map["celsius"] + fahrenheit <- map["fahrenheit"] + } +} +``` + +Once your class implements `Mappable`, ObjectMapper allows you to easily convert to and from JSON. + +Convert a JSON string to a model object: +```swift +let user = User(JSONString: JSONString) +``` + +Convert a model object to a JSON string: +```swift +let JSONString = user.toJSONString(prettyPrint: true) +``` + +Alternatively, the `Mapper.swift` class can also be used to accomplish the above (it also provides extra functionality for other situations): +``` +// Convert JSON String to Model +let user = Mapper().map(JSONString: JSONString) +// Create JSON String from Model +let JSONString = Mapper().toJSONString(user, prettyPrint: true) +``` + +ObjectMapper can map classes composed of the following types: +- `Int` +- `Bool` +- `Double` +- `Float` +- `String` +- `RawRepresentable` (Enums) +- `Array` +- `Dictionary` +- `Object` +- `Array` +- `Array>` +- `Set` +- `Dictionary` +- `Dictionary>` +- Optionals of all the above +- Implicitly Unwrapped Optionals of the above + +## `Mappable` Protocol + +#### `mutating func mapping(map: Map)` +This function is where all mapping definitions should go. When parsing JSON, this function is executed after successful object creation. When generating JSON, it is the only function that is called on the object. + +#### `init?(map: Map)` +This failable initializer is used by ObjectMapper for object creation. It can be used by developers to validate JSON prior to object serialization. Returning nil within the function will prevent the mapping from occuring. You can inspect the JSON stored within the `Map` object to do your validation: +```swift +required init?(map: Map){ + // check if a required "name" property exists within the JSON. + if map.JSONDictionary["name"] == nil { + return nil + } +} +``` + +## `StaticMappable` Protocol +`StaticMappable` is an alternative to `Mappable`. It provides developers with a static function that is used by ObjectMapper for object initialization instead of `init?(map: Map)`. + +Note: `StaticMappable`, like `Mappable`, is a sub protocol of `BaseMappable` which is where the `mapping(map: Map)` function is defined. + +#### `static func objectForMapping(map: Map) -> BaseMappable?` +ObjectMapper uses this function to get objects to use for mapping. Developers should return an instance of an object that conforms to `BaseMappable` in this function. This function can also be used to: +- validate JSON prior to object serialization +- provide an existing cached object to be used for mapping +- return an object of another type (which also conforms to BaseMappable) to be used for mapping. For instance, you may inspect the JSON to infer the type of object that should be used for mapping ([see example](https://github.com/Hearst-DD/ObjectMapper/blob/master/ObjectMapperTests/ClassClusterTests.swift#L62)) + +If you need to implemented ObjectMapper in an extension, you will need to select this protocol instead of `Mappable`. + +## `ImmutableMappable` Protocol (Beta) + +> ⚠️ This feature is currently in Beta. There might be breaking API changes in the future. + +`ImmutableMappable` provides the ability to map immutable properties. This is how `ImmutableMappable` differs from `Mappable`: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ImmutableMappableMappable
Properties
+
+let id: Int
+let name: String?
+
+
+
+var id: Int!
+var name: String?
+
+
JSON -> Model
+
+init(map: Map) throws {
+  id   = try map.value("id")
+  name = try? map.value("name")
+}
+
+
+
+mutating func mapping(map: Map) {
+  id   <- map["id"]
+  name <- map["name"]
+}
+
+
Model -> JSON
+
+mutating func mapping(map: Map) {
+  id   >>> map["id"]
+  name >>> map["name"]
+}
+
+
+
+mutating func mapping(map: Map) {
+  id   <- map["id"]
+  name <- map["name"]
+}
+
+
Initializing
+
+try User(JSONString: JSONString)
+
+
+
+User(JSONString: JSONString)
+
+
+ +#### `init(map: Map) throws` + +This throwable initializer is used to map immutable properties from the given `Map`. Every immutable propertie should be initialized in this initializer. + +This initializer throws an error when: +- `Map` fails to get a value for the given key +- `Map` fails to transform a value using `Transform` + +`ImmutableMappable` uses `Map.value(_:using:)` method to get values from the `Map`. This method should be used with the `try` keyword as it is throwable. `Optional` properties can easily be handled using `try?`. + +```swift +init(map: Map) throws { + name = try map.value("name") // throws an error when it fails + createdAt = try map.value("createdAt", using: DateTransform()) // throws an error when it fails + updatedAt = try? map.value("updatedAt", using: DateTransform()) // optional + posts = (try? map.value("posts")) ?? [] // optional + default value +} +``` + +#### `mutating func mapping(map: Map)` + +This method is where the reverse transform is performed (Model to JSON). Since immutable properties can not be mapped with the `<-` operator, developers have to define the reverse transform using the `>>>` operator. + +```swift +mutating func mapping(map: Map) { + name >>> map["name"] + createdAt >>> (map["createdAt"], DateTransform()) + updatedAt >>> (map["updatedAt"], DateTransform()) + posts >>> map["posts"] +} +``` + + +# Easy Mapping of Nested Objects +ObjectMapper supports dot notation within keys for easy mapping of nested objects. Given the following JSON String: +```json +"distance" : { + "text" : "102 ft", + "value" : 31 +} +``` +You can access the nested objects as follows: +```swift +func mapping(map: Map) { + distance <- map["distance.value"] +} +``` +Nested keys also support accessing values from an array. Given a JSON response with an array of distances, the value could be accessed as follows: +``` +distance <- map["distances.0.value"] +``` +If you have a key that contains `.`, you can individually disable the above feature as follows: +```swift +func mapping(map: Map) { + identifier <- map["app.identifier", nested: false] +} +``` + +# Custom Transforms +ObjectMapper also supports custom transforms that convert values during the mapping process. To use a transform, simply create a tuple with ```map["field_name"]``` and the transform of your choice on the right side of the ```<-``` operator: +```swift +birthday <- (map["birthday"], DateTransform()) +``` +The above transform will convert the JSON Int value to an NSDate when reading JSON and will convert the NSDate to an Int when converting objects to JSON. + +You can easily create your own custom transforms by adopting and implementing the methods in the ```TransformType``` protocol: +```swift +public protocol TransformType { + associatedtype Object + associatedtype JSON + + func transformFromJSON(_ value: Any?) -> Object? + func transformToJSON(_ value: Object?) -> JSON? +} +``` + +### TransformOf +In a lot of situations you can use the built-in transform class ```TransformOf``` to quickly perform a desired transformation. ```TransformOf``` is initialized with two types and two closures. The types define what the transform is converting to and from and the closures perform the actual transformation. + +For example, if you want to transform a JSON String value to an Int you could use ```TransformOf``` as follows: +```swift +let transform = TransformOf(fromJSON: { (value: String?) -> Int? in + // transform value from String? to Int? + return Int(value!) +}, toJSON: { (value: Int?) -> String? in + // transform value from Int? to String? + if let value = value { + return String(value) + } + return nil +}) + +id <- (map["id"], transform) +``` +Here is a more condensed version of the above: +```swift +id <- (map["id"], TransformOf(fromJSON: { Int($0!) }, toJSON: { $0.map { String($0) } })) +``` + +# Subclasses + +Classes that implement the ```Mappable``` protocol can easily be subclassed. When subclassing mappable classes, follow the structure below: + +```swift +class Base: Mappable { + var base: String? + + required init?(map: Map) { + + } + + func mapping(map: Map) { + base <- map["base"] + } +} + +class Subclass: Base { + var sub: String? + + required init?(map: Map) { + super.init(map) + } + + override func mapping(map: Map) { + super.mapping(map) + + sub <- map["sub"] + } +} +``` + +Make sure your subclass implemenation calls the right initializers and mapping functions to also apply the mappings from your superclass. + +# Generic Objects + +ObjectMapper can handle classes with generic types as long as the generic type also conforms to `Mappable`. See the following example: +```swift +class Result: Mappable { + var result: T? + + required init?(map: Map){ + + } + + func mapping(map: Map) { + result <- map["result"] + } +} + +let result = Mapper>().map(JSON) +``` + +# Mapping Context + +The `Map` object which is passed around during mapping, has an optional `MapContext` object that is available for developers to use if they need to pass information around during mapping. + +To take advantage of this feature, simple create an object that implements `MapContext` (which is an empty protocol) and pass it into `Mapper` during initialization. +```swift +struct Context: MapContext { + var importantMappingInfo = "Info that I need during mapping" +} + +class User: Mappable { + var name: String? + + required init?(map: Map){ + + } + + func mapping(map: Map){ + if let context = map.context as? Context { + // use context to make decisions about mapping + } + } +} + +let context = Context() +let user = Mapper(context: context).map(JSONString) +``` + +#ObjectMapper + Alamofire + +If you are using [Alamofire](https://github.com/Alamofire/Alamofire) for networking and you want to convert your responses to Swift objects, you can use [AlamofireObjectMapper](https://github.com/tristanhimmelman/AlamofireObjectMapper). It is a simple Alamofire extension that uses ObjectMapper to automatically map JSON response data to Swift objects. + + +#ObjectMapper + Realm + +ObjectMapper and Realm can be used together. Simply follow the class structure below and you will be able to use ObjectMapper to generate your Realm models: + +```swift +class Model: Object, Mappable { + dynamic var name = "" + + required convenience init?(map: Map) { + self.init() + } + + func mapping(map: Map) { + name <- map["name"] + } +} +``` + +If you want to serialize associated RealmObjects, you can use [ObjectMapper+Realm](https://github.com/jakenberg/ObjectMapper-Realm). It is a simple Realm extension that serializes arbitrary JSON into Realm's List class. + +Note: Generating a JSON string of a Realm Object using ObjectMappers' `toJSON` function only works within a Realm write transaction. This is caused because ObjectMapper uses the `inout` flag in its mapping functions (`<-`) which are used both for serializing and deserializing. Realm detects the flag and forces the `toJSON` function to be called within a write block even though the objects are not being modified. + +# To Do +- Improve error handling. Perhaps using `throws` +- Class cluster documentation + +# Contributing + +Contributions are very welcome 👍😃. + +Before submitting any pull request, please ensure you have run the included tests and they have passed. If you are including new functionality, please write test cases for it as well. + +# Installation +ObjectMapper can be added to your project using [CocoaPods 0.36 or later](http://blog.cocoapods.org/Pod-Authors-Guide-to-CocoaPods-Frameworks/) by adding the following line to your `Podfile`: + +```ruby +pod 'ObjectMapper', '~> 2.1' +``` + +If you're using [Carthage](https://github.com/Carthage/Carthage) you can add a dependency on ObjectMapper by adding it to your `Cartfile`: +``` +github "Hearst-DD/ObjectMapper" ~> 2.1 +``` + +Otherwise, ObjectMapper can be added as a submodule: + +1. Add ObjectMapper as a [submodule](http://git-scm.com/docs/git-submodule) by opening the terminal, `cd`-ing into your top-level project directory, and entering the command `git submodule add https://github.com/Hearst-DD/ObjectMapper.git` +2. Open the `ObjectMapper` folder, and drag `ObjectMapper.xcodeproj` into the file navigator of your app project. +3. In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the "Targets" heading in the sidebar. +4. Ensure that the deployment target of `ObjectMapper.framework` matches that of the application target. +5. In the tab bar at the top of that window, open the "Build Phases" panel. +6. Expand the "Target Dependencies" group, and add `ObjectMapper.framework`. +7. Click on the `+` button at the top left of the panel and select "New Copy Files Phase". Rename this new phase to "Copy Frameworks", set the "Destination" to "Frameworks", and add `ObjectMapper.framework`. diff --git a/iMessagesExample/Pods/Pods.xcodeproj/project.pbxproj b/iMessagesExample/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..55169be --- /dev/null +++ b/iMessagesExample/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,771 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1204B669131D7182F03E9FC07217576F /* TransformOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2377D7EB75AF73C34C9149DD71B028DE /* TransformOf.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 30C1D2BFCFBDA52DBCF823F3C17B20DC /* NSDecimalNumberTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = F255AE287F48F1346599F61BFFB5C849 /* NSDecimalNumberTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 48AAA43EAA03D4C1F3295B2098983508 /* Pods-Abstract-MessagesExtension-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B63C429E4CBF13DBA777F335C73D798A /* Pods-Abstract-MessagesExtension-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 504461CD520506E56709C3EFCD299D4D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; + 550993484584C6CEFC84B9B81FA1C044 /* DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3B89882F10148C719B4FF88F645FE1D /* DateTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 5B102AF44A1DC7D348F9A12245408B2E /* Pods-Abstract-VoteApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DE9C0D90A49D741DC62767D906BB92 /* Pods-Abstract-VoteApp-dummy.m */; }; + 5E615E95845FFB03B4077A7A4D4B267D /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB647F86DD614D191245B5C0774F0F88 /* Operators.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 796F4733CC2BEB533CB61F5F4FDDEFD0 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2225C45B83904842C4A5639EE5CD2E11 /* Map.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8103462367AD098EC83FD658FE74A9C6 /* FromJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0592CD3C0DDDF0F2750AEEE71863FD62 /* FromJSON.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8198880F24A6D1896284D105D9738346 /* Mappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4A1AE24835DED75ED0F17A35AD34E5 /* Mappable.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 87D1D555CC9328C92570156FB5513410 /* EnumOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD1DD1B77E2997D1B4CE32FE954B264 /* EnumOperators.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 8D7304FC21A3D1BDA63B5C796757DC5F /* ImmutableMappble.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06C1844723E62F105BD023A3C8904F5C /* ImmutableMappble.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9A999095EFD9A8A273D6B9405DC757E2 /* URLTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C4BBABDCE9964B7879277706C5C0B2 /* URLTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9DC24404AC81888E6D4E6C15EE847D54 /* CustomDateFormatTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9238EE7A07A1934C2D9AA5179899208 /* CustomDateFormatTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A181B3A1537E237C7AABA3E844A1BBED /* Pods-Abstract-VoteApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BA7383582CC4B2246E0DB6BC9FAED8A /* Pods-Abstract-VoteApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A1D8448D03975EF7A5200BA464C662D1 /* ObjectMapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A42D30987E231B8C88B101602A3E64 /* ObjectMapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A7AE6F28787B4DA16A533BA5701AA0AA /* MapError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943AF28BF6176E469F4F05B02A79B780 /* MapError.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A9803B03390E23F39164FBD04157487E /* ISO8601DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83257AE5D0488CE5E7ABFB6FF515ECF5 /* ISO8601DateTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + AF05FEC025DC7C5F1F36769CAB420628 /* Pods-Abstract-MessagesExtension-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3509097DAF16AC34A1CD1B1844E5C2 /* Pods-Abstract-MessagesExtension-dummy.m */; }; + B8A13CC2976E28A2872F9D895F0142D4 /* EnumTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B520984678476419587AD0BBC949C87A /* EnumTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + B8BFDCDA0B52C4A77B19ADA363C42B63 /* DateFormatterTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 599F19E2AC99EF530EA1E7CDA4D42F74 /* DateFormatterTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + B94C1138897092367D1F63BF945ECA20 /* DictionaryTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70F3BFDCB67778CE026F29F6C50ABEE /* DictionaryTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BC968E6360A97DE612F4FB0CDEBE1210 /* DataTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F972000BA505F402EDAFD77E75438E4 /* DataTransform.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D51CD78BCEBA635EC0024576195EA6F7 /* TransformOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02CFDB02A6342CE9365BFF862C83F55 /* TransformOperators.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DA8483F40A9AFD0E2A57DED7C408E59B /* ToJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0767C2A97ED89BC9AD27AC7B0D6FC755 /* ToJSON.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + E2DEF0F579FA288C6A1478A308478946 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; + E6FBEA1F406E65035E9FA78640D46C13 /* Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4724CDADF6C25B310068F27FBDC9BB18 /* Mapper.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + EC12D04994316EE3A4D9396D6809DE8D /* ObjectMapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2844933DED2A771CDBBF7B445A02DE57 /* ObjectMapper-dummy.m */; }; + EF155D526B5F8AAF9781697205AE5EB0 /* TransformType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7D4658C6C21A348CB3738C8F281ED3 /* TransformType.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F9CCFE94F29F32C0BD4780EA5015D729 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 56522D2DDA124DD8A881378EBA98645B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C8A84485A82D0105AD90775E6388A52B; + remoteInfo = ObjectMapper; + }; + 7E20DF07609719F2D751FA87F11C91BF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C8A84485A82D0105AD90775E6388A52B; + remoteInfo = ObjectMapper; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 03E504B5A5D07CC7F0F0244475EEC95A /* ObjectMapper.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ObjectMapper.xcconfig; sourceTree = ""; }; + 0592CD3C0DDDF0F2750AEEE71863FD62 /* FromJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FromJSON.swift; path = ObjectMapper/Core/FromJSON.swift; sourceTree = ""; }; + 06C1844723E62F105BD023A3C8904F5C /* ImmutableMappble.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmutableMappble.swift; path = ObjectMapper/Core/ImmutableMappble.swift; sourceTree = ""; }; + 0767C2A97ED89BC9AD27AC7B0D6FC755 /* ToJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToJSON.swift; path = ObjectMapper/Core/ToJSON.swift; sourceTree = ""; }; + 13C4BBABDCE9964B7879277706C5C0B2 /* URLTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLTransform.swift; path = ObjectMapper/Transforms/URLTransform.swift; sourceTree = ""; }; + 1D9E8DFECE85C367FF7DD6E34EAC175D /* Pods-Abstract-VoteApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-VoteApp.debug.xcconfig"; sourceTree = ""; }; + 1F972000BA505F402EDAFD77E75438E4 /* DataTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataTransform.swift; path = ObjectMapper/Transforms/DataTransform.swift; sourceTree = ""; }; + 2225C45B83904842C4A5639EE5CD2E11 /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = ObjectMapper/Core/Map.swift; sourceTree = ""; }; + 2377D7EB75AF73C34C9149DD71B028DE /* TransformOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOf.swift; path = ObjectMapper/Transforms/TransformOf.swift; sourceTree = ""; }; + 2844933DED2A771CDBBF7B445A02DE57 /* ObjectMapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ObjectMapper-dummy.m"; sourceTree = ""; }; + 2AD1DD1B77E2997D1B4CE32FE954B264 /* EnumOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumOperators.swift; path = ObjectMapper/Core/Operators/EnumOperators.swift; sourceTree = ""; }; + 343E35AFA56E408D3E97C7E16283A78D /* ObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 388BCB3DFD580EF9E3E810F455059FE6 /* Pods-Abstract-VoteApp-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-VoteApp-frameworks.sh"; sourceTree = ""; }; + 3A7D4658C6C21A348CB3738C8F281ED3 /* TransformType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformType.swift; path = ObjectMapper/Transforms/TransformType.swift; sourceTree = ""; }; + 4188A34EC188FBA708A26C2565CAA73E /* Pods-Abstract-MessagesExtension-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-MessagesExtension-resources.sh"; sourceTree = ""; }; + 4724CDADF6C25B310068F27FBDC9BB18 /* Mapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mapper.swift; path = ObjectMapper/Core/Mapper.swift; sourceTree = ""; }; + 5526EFFB160C2D573C904E47961B8DB0 /* ObjectMapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = ObjectMapper.modulemap; sourceTree = ""; }; + 599F19E2AC99EF530EA1E7CDA4D42F74 /* DateFormatterTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateFormatterTransform.swift; path = ObjectMapper/Transforms/DateFormatterTransform.swift; sourceTree = ""; }; + 5A4A1AE24835DED75ED0F17A35AD34E5 /* Mappable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mappable.swift; path = ObjectMapper/Core/Mappable.swift; sourceTree = ""; }; + 7D3509097DAF16AC34A1CD1B1844E5C2 /* Pods-Abstract-MessagesExtension-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Abstract-MessagesExtension-dummy.m"; sourceTree = ""; }; + 7D82104DCEA7A3FB25CA40941943D49C /* Pods-Abstract-MessagesExtension-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Abstract-MessagesExtension-acknowledgements.plist"; sourceTree = ""; }; + 827973F95E6784D0A9DDAC6EF3BB54B7 /* Pods-Abstract-MessagesExtension-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Abstract-MessagesExtension-acknowledgements.markdown"; sourceTree = ""; }; + 83257AE5D0488CE5E7ABFB6FF515ECF5 /* ISO8601DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISO8601DateTransform.swift; path = ObjectMapper/Transforms/ISO8601DateTransform.swift; sourceTree = ""; }; + 83A42D30987E231B8C88B101602A3E64 /* ObjectMapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-umbrella.h"; sourceTree = ""; }; + 8A82EC9E4CB7DC568BB7F6323A6DA011 /* Pods-Abstract-VoteApp-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-VoteApp-resources.sh"; sourceTree = ""; }; + 906FD63FE9B5BCBBDB5AACC2C9497D60 /* ObjectMapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-prefix.pch"; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 943AF28BF6176E469F4F05B02A79B780 /* MapError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MapError.swift; path = ObjectMapper/Core/MapError.swift; sourceTree = ""; }; + 9ABFA74CE7DFABC215B55A06FB3C018A /* Pods_Abstract_MessagesExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_MessagesExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9BA7383582CC4B2246E0DB6BC9FAED8A /* Pods-Abstract-VoteApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Abstract-VoteApp-umbrella.h"; sourceTree = ""; }; + A70F3BFDCB67778CE026F29F6C50ABEE /* DictionaryTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DictionaryTransform.swift; path = ObjectMapper/Transforms/DictionaryTransform.swift; sourceTree = ""; }; + AB79428FB0F0D90CAA03A9E801A1F0DB /* Pods-Abstract-MessagesExtension-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-MessagesExtension-frameworks.sh"; sourceTree = ""; }; + ABA1E49FDBB963983E71604D03C720DC /* Pods_Abstract_VoteApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_VoteApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AE93AF49289D8C05B1AD56BC3BBA79AC /* Pods-Abstract-VoteApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-VoteApp.release.xcconfig"; sourceTree = ""; }; + B3B89882F10148C719B4FF88F645FE1D /* DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateTransform.swift; path = ObjectMapper/Transforms/DateTransform.swift; sourceTree = ""; }; + B4BDE83CAA43BD3C8E46ACBD261C2BF8 /* Pods-Abstract-VoteApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Abstract-VoteApp-acknowledgements.markdown"; sourceTree = ""; }; + B520984678476419587AD0BBC949C87A /* EnumTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumTransform.swift; path = ObjectMapper/Transforms/EnumTransform.swift; sourceTree = ""; }; + B635FC2B100DC497A3BA93E3EFCEBE4E /* Pods-Abstract-MessagesExtension.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Abstract-MessagesExtension.modulemap"; sourceTree = ""; }; + B63C429E4CBF13DBA777F335C73D798A /* Pods-Abstract-MessagesExtension-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Abstract-MessagesExtension-umbrella.h"; sourceTree = ""; }; + C7B88806BEE3C176785231FB2436FCFA /* Pods-Abstract-VoteApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Abstract-VoteApp.modulemap"; sourceTree = ""; }; + CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + D010E2B0F2C6801AECA67867534C98E9 /* Pods-Abstract-MessagesExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-MessagesExtension.release.xcconfig"; sourceTree = ""; }; + D02CFDB02A6342CE9365BFF862C83F55 /* TransformOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOperators.swift; path = ObjectMapper/Core/Operators/TransformOperators.swift; sourceTree = ""; }; + D67A9284E8FDB646B3EC24AEA6A7DB6C /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D69BE3B0BE5FFC5B0100A511A2D2B7D4 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DA71950108282381205A82098602A868 /* Pods-Abstract-VoteApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Abstract-VoteApp-acknowledgements.plist"; sourceTree = ""; }; + DB647F86DD614D191245B5C0774F0F88 /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = ObjectMapper/Core/Operators/Operators.swift; sourceTree = ""; }; + DDA0DB363F137870A92177FEFDCB5255 /* Pods-Abstract-MessagesExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-MessagesExtension.debug.xcconfig"; sourceTree = ""; }; + E01DBDB4C1EB4E35E420B5ED9102E570 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E9238EE7A07A1934C2D9AA5179899208 /* CustomDateFormatTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CustomDateFormatTransform.swift; path = ObjectMapper/Transforms/CustomDateFormatTransform.swift; sourceTree = ""; }; + F255AE287F48F1346599F61BFFB5C849 /* NSDecimalNumberTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NSDecimalNumberTransform.swift; path = ObjectMapper/Transforms/NSDecimalNumberTransform.swift; sourceTree = ""; }; + F4DE9C0D90A49D741DC62767D906BB92 /* Pods-Abstract-VoteApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Abstract-VoteApp-dummy.m"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3FE0EED1980276C3EA98C5BFF53843E7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 504461CD520506E56709C3EFCD299D4D /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB9F97A13F817D86F6662D7B3EC2D1CB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E2DEF0F579FA288C6A1478A308478946 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F38138D919D5CFFD7DF08F523B2DAC8B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F9CCFE94F29F32C0BD4780EA5015D729 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 359BD8C4BD27C7861824A7D28D14A9E2 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + C0344D27C5C8648F6F3E5043994C9567 /* Pods-Abstract-MessagesExtension */, + EA218A2A166B86D107502CAB44256707 /* Pods-Abstract-VoteApp */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 3DCAB2B7CDE207B3958B6CB957FCC758 /* iOS */ = { + isa = PBXGroup; + children = ( + CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, + 9DBE93B63FBA71038683759AE3BA532C /* Pods */, + D5F9B1D5BDAF7F6C805F1E8D1F184F09 /* Products */, + 359BD8C4BD27C7861824A7D28D14A9E2 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 9DBE93B63FBA71038683759AE3BA532C /* Pods */ = { + isa = PBXGroup; + children = ( + DCE0C65487AD0572AC51D2F1B3D28BD0 /* ObjectMapper */, + ); + name = Pods; + sourceTree = ""; + }; + B8B7593F584DEF5DDB76DB4AA887088F /* Support Files */ = { + isa = PBXGroup; + children = ( + D69BE3B0BE5FFC5B0100A511A2D2B7D4 /* Info.plist */, + 5526EFFB160C2D573C904E47961B8DB0 /* ObjectMapper.modulemap */, + 03E504B5A5D07CC7F0F0244475EEC95A /* ObjectMapper.xcconfig */, + 2844933DED2A771CDBBF7B445A02DE57 /* ObjectMapper-dummy.m */, + 906FD63FE9B5BCBBDB5AACC2C9497D60 /* ObjectMapper-prefix.pch */, + 83A42D30987E231B8C88B101602A3E64 /* ObjectMapper-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/ObjectMapper"; + sourceTree = ""; + }; + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3DCAB2B7CDE207B3958B6CB957FCC758 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + C0344D27C5C8648F6F3E5043994C9567 /* Pods-Abstract-MessagesExtension */ = { + isa = PBXGroup; + children = ( + E01DBDB4C1EB4E35E420B5ED9102E570 /* Info.plist */, + B635FC2B100DC497A3BA93E3EFCEBE4E /* Pods-Abstract-MessagesExtension.modulemap */, + 827973F95E6784D0A9DDAC6EF3BB54B7 /* Pods-Abstract-MessagesExtension-acknowledgements.markdown */, + 7D82104DCEA7A3FB25CA40941943D49C /* Pods-Abstract-MessagesExtension-acknowledgements.plist */, + 7D3509097DAF16AC34A1CD1B1844E5C2 /* Pods-Abstract-MessagesExtension-dummy.m */, + AB79428FB0F0D90CAA03A9E801A1F0DB /* Pods-Abstract-MessagesExtension-frameworks.sh */, + 4188A34EC188FBA708A26C2565CAA73E /* Pods-Abstract-MessagesExtension-resources.sh */, + B63C429E4CBF13DBA777F335C73D798A /* Pods-Abstract-MessagesExtension-umbrella.h */, + DDA0DB363F137870A92177FEFDCB5255 /* Pods-Abstract-MessagesExtension.debug.xcconfig */, + D010E2B0F2C6801AECA67867534C98E9 /* Pods-Abstract-MessagesExtension.release.xcconfig */, + ); + name = "Pods-Abstract-MessagesExtension"; + path = "Target Support Files/Pods-Abstract-MessagesExtension"; + sourceTree = ""; + }; + D5F9B1D5BDAF7F6C805F1E8D1F184F09 /* Products */ = { + isa = PBXGroup; + children = ( + 343E35AFA56E408D3E97C7E16283A78D /* ObjectMapper.framework */, + 9ABFA74CE7DFABC215B55A06FB3C018A /* Pods_Abstract_MessagesExtension.framework */, + ABA1E49FDBB963983E71604D03C720DC /* Pods_Abstract_VoteApp.framework */, + ); + name = Products; + sourceTree = ""; + }; + DCE0C65487AD0572AC51D2F1B3D28BD0 /* ObjectMapper */ = { + isa = PBXGroup; + children = ( + E9238EE7A07A1934C2D9AA5179899208 /* CustomDateFormatTransform.swift */, + 1F972000BA505F402EDAFD77E75438E4 /* DataTransform.swift */, + 599F19E2AC99EF530EA1E7CDA4D42F74 /* DateFormatterTransform.swift */, + B3B89882F10148C719B4FF88F645FE1D /* DateTransform.swift */, + A70F3BFDCB67778CE026F29F6C50ABEE /* DictionaryTransform.swift */, + 2AD1DD1B77E2997D1B4CE32FE954B264 /* EnumOperators.swift */, + B520984678476419587AD0BBC949C87A /* EnumTransform.swift */, + 0592CD3C0DDDF0F2750AEEE71863FD62 /* FromJSON.swift */, + 06C1844723E62F105BD023A3C8904F5C /* ImmutableMappble.swift */, + 83257AE5D0488CE5E7ABFB6FF515ECF5 /* ISO8601DateTransform.swift */, + 2225C45B83904842C4A5639EE5CD2E11 /* Map.swift */, + 943AF28BF6176E469F4F05B02A79B780 /* MapError.swift */, + 5A4A1AE24835DED75ED0F17A35AD34E5 /* Mappable.swift */, + 4724CDADF6C25B310068F27FBDC9BB18 /* Mapper.swift */, + F255AE287F48F1346599F61BFFB5C849 /* NSDecimalNumberTransform.swift */, + DB647F86DD614D191245B5C0774F0F88 /* Operators.swift */, + 0767C2A97ED89BC9AD27AC7B0D6FC755 /* ToJSON.swift */, + 2377D7EB75AF73C34C9149DD71B028DE /* TransformOf.swift */, + D02CFDB02A6342CE9365BFF862C83F55 /* TransformOperators.swift */, + 3A7D4658C6C21A348CB3738C8F281ED3 /* TransformType.swift */, + 13C4BBABDCE9964B7879277706C5C0B2 /* URLTransform.swift */, + B8B7593F584DEF5DDB76DB4AA887088F /* Support Files */, + ); + path = ObjectMapper; + sourceTree = ""; + }; + EA218A2A166B86D107502CAB44256707 /* Pods-Abstract-VoteApp */ = { + isa = PBXGroup; + children = ( + D67A9284E8FDB646B3EC24AEA6A7DB6C /* Info.plist */, + C7B88806BEE3C176785231FB2436FCFA /* Pods-Abstract-VoteApp.modulemap */, + B4BDE83CAA43BD3C8E46ACBD261C2BF8 /* Pods-Abstract-VoteApp-acknowledgements.markdown */, + DA71950108282381205A82098602A868 /* Pods-Abstract-VoteApp-acknowledgements.plist */, + F4DE9C0D90A49D741DC62767D906BB92 /* Pods-Abstract-VoteApp-dummy.m */, + 388BCB3DFD580EF9E3E810F455059FE6 /* Pods-Abstract-VoteApp-frameworks.sh */, + 8A82EC9E4CB7DC568BB7F6323A6DA011 /* Pods-Abstract-VoteApp-resources.sh */, + 9BA7383582CC4B2246E0DB6BC9FAED8A /* Pods-Abstract-VoteApp-umbrella.h */, + 1D9E8DFECE85C367FF7DD6E34EAC175D /* Pods-Abstract-VoteApp.debug.xcconfig */, + AE93AF49289D8C05B1AD56BC3BBA79AC /* Pods-Abstract-VoteApp.release.xcconfig */, + ); + name = "Pods-Abstract-VoteApp"; + path = "Target Support Files/Pods-Abstract-VoteApp"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 464A5120491E8B4F9F6657D569BDD8C5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A181B3A1537E237C7AABA3E844A1BBED /* Pods-Abstract-VoteApp-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B9CDA7E708278D9DBA6BC2313E3ED6EC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 48AAA43EAA03D4C1F3295B2098983508 /* Pods-Abstract-MessagesExtension-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F77A7511AE66E6B363582E21E0E1D5A3 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A1D8448D03975EF7A5200BA464C662D1 /* ObjectMapper-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 21AAB2416AD09F93261537454BD30EE5 /* Pods-Abstract-MessagesExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 131AA4F08128D2F2D8DFF9C49949DBC2 /* Build configuration list for PBXNativeTarget "Pods-Abstract-MessagesExtension" */; + buildPhases = ( + 129D4DA4AA9C2EC5C4A6FE0AD89D30CF /* Sources */, + 3FE0EED1980276C3EA98C5BFF53843E7 /* Frameworks */, + B9CDA7E708278D9DBA6BC2313E3ED6EC /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 98EFDF01F9717FBCBA7A65297E7A1BBD /* PBXTargetDependency */, + ); + name = "Pods-Abstract-MessagesExtension"; + productName = "Pods-Abstract-MessagesExtension"; + productReference = 9ABFA74CE7DFABC215B55A06FB3C018A /* Pods_Abstract_MessagesExtension.framework */; + productType = "com.apple.product-type.framework"; + }; + A29AA3D3BD24E11584BE810C196BB956 /* Pods-Abstract-VoteApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = A346ADEBD8B0868A0A09A83FBEB6B978 /* Build configuration list for PBXNativeTarget "Pods-Abstract-VoteApp" */; + buildPhases = ( + BE210C818CD85CE2071E553D4E533FC0 /* Sources */, + F38138D919D5CFFD7DF08F523B2DAC8B /* Frameworks */, + 464A5120491E8B4F9F6657D569BDD8C5 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 8AD4AE8F95F33147BB41389287D46B0C /* PBXTargetDependency */, + ); + name = "Pods-Abstract-VoteApp"; + productName = "Pods-Abstract-VoteApp"; + productReference = ABA1E49FDBB963983E71604D03C720DC /* Pods_Abstract_VoteApp.framework */; + productType = "com.apple.product-type.framework"; + }; + C8A84485A82D0105AD90775E6388A52B /* ObjectMapper */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7F19C2F79017BBC55D4555B43F8BAF66 /* Build configuration list for PBXNativeTarget "ObjectMapper" */; + buildPhases = ( + 892429104F3287776EB4B4C5AD9AF356 /* Sources */, + EB9F97A13F817D86F6662D7B3EC2D1CB /* Frameworks */, + F77A7511AE66E6B363582E21E0E1D5A3 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ObjectMapper; + productName = ObjectMapper; + productReference = 343E35AFA56E408D3E97C7E16283A78D /* ObjectMapper.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = D5F9B1D5BDAF7F6C805F1E8D1F184F09 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + C8A84485A82D0105AD90775E6388A52B /* ObjectMapper */, + 21AAB2416AD09F93261537454BD30EE5 /* Pods-Abstract-MessagesExtension */, + A29AA3D3BD24E11584BE810C196BB956 /* Pods-Abstract-VoteApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 129D4DA4AA9C2EC5C4A6FE0AD89D30CF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AF05FEC025DC7C5F1F36769CAB420628 /* Pods-Abstract-MessagesExtension-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 892429104F3287776EB4B4C5AD9AF356 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9DC24404AC81888E6D4E6C15EE847D54 /* CustomDateFormatTransform.swift in Sources */, + BC968E6360A97DE612F4FB0CDEBE1210 /* DataTransform.swift in Sources */, + B8BFDCDA0B52C4A77B19ADA363C42B63 /* DateFormatterTransform.swift in Sources */, + 550993484584C6CEFC84B9B81FA1C044 /* DateTransform.swift in Sources */, + B94C1138897092367D1F63BF945ECA20 /* DictionaryTransform.swift in Sources */, + 87D1D555CC9328C92570156FB5513410 /* EnumOperators.swift in Sources */, + B8A13CC2976E28A2872F9D895F0142D4 /* EnumTransform.swift in Sources */, + 8103462367AD098EC83FD658FE74A9C6 /* FromJSON.swift in Sources */, + 8D7304FC21A3D1BDA63B5C796757DC5F /* ImmutableMappble.swift in Sources */, + A9803B03390E23F39164FBD04157487E /* ISO8601DateTransform.swift in Sources */, + 796F4733CC2BEB533CB61F5F4FDDEFD0 /* Map.swift in Sources */, + A7AE6F28787B4DA16A533BA5701AA0AA /* MapError.swift in Sources */, + 8198880F24A6D1896284D105D9738346 /* Mappable.swift in Sources */, + E6FBEA1F406E65035E9FA78640D46C13 /* Mapper.swift in Sources */, + 30C1D2BFCFBDA52DBCF823F3C17B20DC /* NSDecimalNumberTransform.swift in Sources */, + EC12D04994316EE3A4D9396D6809DE8D /* ObjectMapper-dummy.m in Sources */, + 5E615E95845FFB03B4077A7A4D4B267D /* Operators.swift in Sources */, + DA8483F40A9AFD0E2A57DED7C408E59B /* ToJSON.swift in Sources */, + 1204B669131D7182F03E9FC07217576F /* TransformOf.swift in Sources */, + D51CD78BCEBA635EC0024576195EA6F7 /* TransformOperators.swift in Sources */, + EF155D526B5F8AAF9781697205AE5EB0 /* TransformType.swift in Sources */, + 9A999095EFD9A8A273D6B9405DC757E2 /* URLTransform.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BE210C818CD85CE2071E553D4E533FC0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5B102AF44A1DC7D348F9A12245408B2E /* Pods-Abstract-VoteApp-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8AD4AE8F95F33147BB41389287D46B0C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ObjectMapper; + target = C8A84485A82D0105AD90775E6388A52B /* ObjectMapper */; + targetProxy = 7E20DF07609719F2D751FA87F11C91BF /* PBXContainerItemProxy */; + }; + 98EFDF01F9717FBCBA7A65297E7A1BBD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ObjectMapper; + target = C8A84485A82D0105AD90775E6388A52B /* ObjectMapper */; + targetProxy = 56522D2DDA124DD8A881378EBA98645B /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 034014829C1E4434983CF3A690C12017 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + ONLY_ACTIVE_ARCH = YES; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 27B86B511D96E96740BF0DD3EC4EED1F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1D9E8DFECE85C367FF7DD6E34EAC175D /* Pods-Abstract-VoteApp.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-VoteApp/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_VoteApp; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 27B86F2DEB8AE9DEE9804A5158F7DED1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AE93AF49289D8C05B1AD56BC3BBA79AC /* Pods-Abstract-VoteApp.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-VoteApp/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_VoteApp; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 2AC5D0E5809050B3EF62D07967D37611 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D010E2B0F2C6801AECA67867534C98E9 /* Pods-Abstract-MessagesExtension.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-MessagesExtension/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_MessagesExtension; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 64D9F9B0D8CDDE1BFD3F869733CE8850 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 03E504B5A5D07CC7F0F0244475EEC95A /* ObjectMapper.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/ObjectMapper/ObjectMapper-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/ObjectMapper/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/ObjectMapper/ObjectMapper.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = ObjectMapper; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + C7E474A03CAE21F1CB6046E7344C59BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + D4170B59540162251AB7CD6082A1A9C5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DDA0DB363F137870A92177FEFDCB5255 /* Pods-Abstract-MessagesExtension.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-MessagesExtension/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_MessagesExtension; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D4B7C6AD29A2965C892D868D30CE9E1F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 03E504B5A5D07CC7F0F0244475EEC95A /* ObjectMapper.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/ObjectMapper/ObjectMapper-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/ObjectMapper/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/ObjectMapper/ObjectMapper.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = ObjectMapper; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 131AA4F08128D2F2D8DFF9C49949DBC2 /* Build configuration list for PBXNativeTarget "Pods-Abstract-MessagesExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4170B59540162251AB7CD6082A1A9C5 /* Debug */, + 2AC5D0E5809050B3EF62D07967D37611 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 034014829C1E4434983CF3A690C12017 /* Debug */, + C7E474A03CAE21F1CB6046E7344C59BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7F19C2F79017BBC55D4555B43F8BAF66 /* Build configuration list for PBXNativeTarget "ObjectMapper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4B7C6AD29A2965C892D868D30CE9E1F /* Debug */, + 64D9F9B0D8CDDE1BFD3F869733CE8850 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A346ADEBD8B0868A0A09A83FBEB6B978 /* Build configuration list for PBXNativeTarget "Pods-Abstract-VoteApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 27B86B511D96E96740BF0DD3EC4EED1F /* Debug */, + 27B86F2DEB8AE9DEE9804A5158F7DED1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/Info.plist b/iMessagesExample/Pods/Target Support Files/ObjectMapper/Info.plist new file mode 100644 index 0000000..7f71fff --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-dummy.m b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-dummy.m new file mode 100644 index 0000000..7033cce --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_ObjectMapper : NSObject +@end +@implementation PodsDummy_ObjectMapper +@end diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-prefix.pch b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-umbrella.h b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-umbrella.h new file mode 100644 index 0000000..88f99d1 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double ObjectMapperVersionNumber; +FOUNDATION_EXPORT const unsigned char ObjectMapperVersionString[]; + diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.modulemap b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.modulemap new file mode 100644 index 0000000..539c248 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.modulemap @@ -0,0 +1,6 @@ +framework module ObjectMapper { + umbrella header "ObjectMapper-umbrella.h" + + export * + module * { export * } +} diff --git a/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.xcconfig b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.xcconfig new file mode 100644 index 0000000..f9a1958 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/ObjectMapper/ObjectMapper.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ObjectMapper +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +SWIFT_VERSION = 3.0 diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Info.plist b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.markdown b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.markdown new file mode 100644 index 0000000..2cf919b --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.markdown @@ -0,0 +1,15 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## ObjectMapper + +The MIT License (MIT) +Copyright (c) 2014 Hearst + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.plist b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.plist new file mode 100644 index 0000000..9d82a00 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-acknowledgements.plist @@ -0,0 +1,45 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) +Copyright (c) 2014 Hearst + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + ObjectMapper + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-dummy.m b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-dummy.m new file mode 100644 index 0000000..85ba944 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_Abstract_MessagesExtension : NSObject +@end +@implementation PodsDummy_Pods_Abstract_MessagesExtension +@end diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-frameworks.sh b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-frameworks.sh new file mode 100755 index 0000000..e6738ad --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-frameworks.sh @@ -0,0 +1,91 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/ObjectMapper/ObjectMapper.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/ObjectMapper/ObjectMapper.framework" +fi diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-resources.sh b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-resources.sh new file mode 100755 index 0000000..0a15615 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-resources.sh @@ -0,0 +1,102 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +realpath() { + DIRECTORY="$(cd "${1%/*}" && pwd)" + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-umbrella.h b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-umbrella.h new file mode 100644 index 0000000..80ba0c4 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_Abstract_MessagesExtensionVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_Abstract_MessagesExtensionVersionString[]; + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.debug.xcconfig b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.debug.xcconfig new file mode 100644 index 0000000..14c2674 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.debug.xcconfig @@ -0,0 +1,10 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper/ObjectMapper.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "ObjectMapper" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap new file mode 100644 index 0000000..0ca9ee3 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.modulemap @@ -0,0 +1,6 @@ +framework module Pods_Abstract_MessagesExtension { + umbrella header "Pods-Abstract-MessagesExtension-umbrella.h" + + export * + module * { export * } +} diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.release.xcconfig b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.release.xcconfig new file mode 100644 index 0000000..14c2674 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.release.xcconfig @@ -0,0 +1,10 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper/ObjectMapper.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "ObjectMapper" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Info.plist b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.markdown b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.markdown new file mode 100644 index 0000000..2cf919b --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.markdown @@ -0,0 +1,15 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## ObjectMapper + +The MIT License (MIT) +Copyright (c) 2014 Hearst + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.plist b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.plist new file mode 100644 index 0000000..9d82a00 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-acknowledgements.plist @@ -0,0 +1,45 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) +Copyright (c) 2014 Hearst + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + ObjectMapper + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-dummy.m b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-dummy.m new file mode 100644 index 0000000..abe2ff1 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_Abstract_VoteApp : NSObject +@end +@implementation PodsDummy_Pods_Abstract_VoteApp +@end diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-frameworks.sh b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-frameworks.sh new file mode 100755 index 0000000..e6738ad --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-frameworks.sh @@ -0,0 +1,91 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/ObjectMapper/ObjectMapper.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/ObjectMapper/ObjectMapper.framework" +fi diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-resources.sh b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-resources.sh new file mode 100755 index 0000000..0a15615 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-resources.sh @@ -0,0 +1,102 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +realpath() { + DIRECTORY="$(cd "${1%/*}" && pwd)" + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-umbrella.h b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-umbrella.h new file mode 100644 index 0000000..06f7b06 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_Abstract_VoteAppVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_Abstract_VoteAppVersionString[]; + diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.debug.xcconfig b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.debug.xcconfig new file mode 100644 index 0000000..14c2674 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.debug.xcconfig @@ -0,0 +1,10 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper/ObjectMapper.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "ObjectMapper" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap new file mode 100644 index 0000000..ab88213 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.modulemap @@ -0,0 +1,6 @@ +framework module Pods_Abstract_VoteApp { + umbrella header "Pods-Abstract-VoteApp-umbrella.h" + + export * + module * { export * } +} diff --git a/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.release.xcconfig b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.release.xcconfig new file mode 100644 index 0000000..14c2674 --- /dev/null +++ b/iMessagesExample/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.release.xcconfig @@ -0,0 +1,10 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ObjectMapper/ObjectMapper.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "ObjectMapper" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/iMessagesExample/VoteApp.xcodeproj/project.pbxproj b/iMessagesExample/VoteApp.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1234b5b --- /dev/null +++ b/iMessagesExample/VoteApp.xcodeproj/project.pbxproj @@ -0,0 +1,557 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3DF44B274E82324DE497DF78 /* Pods_Abstract_VoteApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 359D4F28F0B8BCE76DDC1803 /* Pods_Abstract_VoteApp.framework */; }; + DC5635A91DCE297300E4840B /* PollEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5635A81DCE297300E4840B /* PollEntity.swift */; }; + DCB5F9F01DC8C70F0030FC43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DCB5F9EF1DC8C70F0030FC43 /* Assets.xcassets */; }; + DCB5F9F71DC8C70F0030FC43 /* MessagesExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DCB5F9F61DC8C70F0030FC43 /* MessagesExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + DCB5F9FC1DC8C70F0030FC43 /* Messages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB5F9FB1DC8C70F0030FC43 /* Messages.framework */; }; + DCB5F9FF1DC8C70F0030FC43 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB5F9FE1DC8C70F0030FC43 /* MessagesViewController.swift */; }; + DCB5FA021DC8C70F0030FC43 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DCB5FA001DC8C70F0030FC43 /* MainInterface.storyboard */; }; + DCB5FA041DC8C70F0030FC43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DCB5FA031DC8C70F0030FC43 /* Assets.xcassets */; }; + DCB5FA101DC8CE5D0030FC43 /* ExpandedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB5FA0F1DC8CE5D0030FC43 /* ExpandedViewController.swift */; }; + DCB5FA141DC8E7DE0030FC43 /* CompactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB5FA131DC8E7DE0030FC43 /* CompactViewController.swift */; }; + EA376D82A9B7248C3C111996 /* Pods_Abstract_MessagesExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CD39F780FC2CA69347CB1C2 /* Pods_Abstract_MessagesExtension.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + DCB5F9F81DC8C70F0030FC43 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DCB5F9E61DC8C70F0030FC43 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB5F9F51DC8C70F0030FC43; + remoteInfo = MessagesExtension; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + DCB5FA0B1DC8C70F0030FC43 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + DCB5F9F71DC8C70F0030FC43 /* MessagesExtension.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 32424C6FA93C9B93C60A587E /* Pods-Abstract-MessagesExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Abstract-MessagesExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.release.xcconfig"; sourceTree = ""; }; + 359D4F28F0B8BCE76DDC1803 /* Pods_Abstract_VoteApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_VoteApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4E986ACCC82778BE3DDFDAAE /* Pods-Abstract-MessagesExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Abstract-MessagesExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension.debug.xcconfig"; sourceTree = ""; }; + 5CD39F780FC2CA69347CB1C2 /* Pods_Abstract_MessagesExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_MessagesExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8BB6646EA54790B6C0F12530 /* Pods-Abstract-VoteApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Abstract-VoteApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.debug.xcconfig"; sourceTree = ""; }; + DC5635A81DCE297300E4840B /* PollEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PollEntity.swift; sourceTree = ""; }; + DCB5F9EC1DC8C70F0030FC43 /* VoteApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoteApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DCB5F9EF1DC8C70F0030FC43 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DCB5F9F11DC8C70F0030FC43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DCB5F9F61DC8C70F0030FC43 /* MessagesExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MessagesExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + DCB5F9FB1DC8C70F0030FC43 /* Messages.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Messages.framework; path = System/Library/Frameworks/Messages.framework; sourceTree = SDKROOT; }; + DCB5F9FE1DC8C70F0030FC43 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; }; + DCB5FA011DC8C70F0030FC43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; + DCB5FA031DC8C70F0030FC43 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DCB5FA051DC8C70F0030FC43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DCB5FA0F1DC8CE5D0030FC43 /* ExpandedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpandedViewController.swift; sourceTree = ""; }; + DCB5FA131DC8E7DE0030FC43 /* CompactViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompactViewController.swift; sourceTree = ""; }; + E2B350645C3A478E2B8E108B /* Pods-Abstract-VoteApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Abstract-VoteApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + BAA38EB0F70FDA81D8F41C57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3DF44B274E82324DE497DF78 /* Pods_Abstract_VoteApp.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCB5F9F31DC8C70F0030FC43 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCB5F9FC1DC8C70F0030FC43 /* Messages.framework in Frameworks */, + EA376D82A9B7248C3C111996 /* Pods_Abstract_MessagesExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 353742FEB9D1C88F4C99DA38 /* Pods */ = { + isa = PBXGroup; + children = ( + 4E986ACCC82778BE3DDFDAAE /* Pods-Abstract-MessagesExtension.debug.xcconfig */, + 32424C6FA93C9B93C60A587E /* Pods-Abstract-MessagesExtension.release.xcconfig */, + 8BB6646EA54790B6C0F12530 /* Pods-Abstract-VoteApp.debug.xcconfig */, + E2B350645C3A478E2B8E108B /* Pods-Abstract-VoteApp.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + DCB5F9E51DC8C70F0030FC43 = { + isa = PBXGroup; + children = ( + DCB5F9EE1DC8C70F0030FC43 /* VoteApp */, + DCB5F9FD1DC8C70F0030FC43 /* MessagesExtension */, + DCB5F9FA1DC8C70F0030FC43 /* Frameworks */, + DCB5F9ED1DC8C70F0030FC43 /* Products */, + 353742FEB9D1C88F4C99DA38 /* Pods */, + ); + sourceTree = ""; + }; + DCB5F9ED1DC8C70F0030FC43 /* Products */ = { + isa = PBXGroup; + children = ( + DCB5F9EC1DC8C70F0030FC43 /* VoteApp.app */, + DCB5F9F61DC8C70F0030FC43 /* MessagesExtension.appex */, + ); + name = Products; + sourceTree = ""; + }; + DCB5F9EE1DC8C70F0030FC43 /* VoteApp */ = { + isa = PBXGroup; + children = ( + DCB5F9EF1DC8C70F0030FC43 /* Assets.xcassets */, + DCB5F9F11DC8C70F0030FC43 /* Info.plist */, + ); + path = VoteApp; + sourceTree = ""; + }; + DCB5F9FA1DC8C70F0030FC43 /* Frameworks */ = { + isa = PBXGroup; + children = ( + DCB5F9FB1DC8C70F0030FC43 /* Messages.framework */, + 5CD39F780FC2CA69347CB1C2 /* Pods_Abstract_MessagesExtension.framework */, + 359D4F28F0B8BCE76DDC1803 /* Pods_Abstract_VoteApp.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + DCB5F9FD1DC8C70F0030FC43 /* MessagesExtension */ = { + isa = PBXGroup; + children = ( + DCB5F9FE1DC8C70F0030FC43 /* MessagesViewController.swift */, + DCB5FA001DC8C70F0030FC43 /* MainInterface.storyboard */, + DCB5FA131DC8E7DE0030FC43 /* CompactViewController.swift */, + DCB5FA0F1DC8CE5D0030FC43 /* ExpandedViewController.swift */, + DC5635A81DCE297300E4840B /* PollEntity.swift */, + DCB5FA031DC8C70F0030FC43 /* Assets.xcassets */, + DCB5FA051DC8C70F0030FC43 /* Info.plist */, + ); + path = MessagesExtension; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DCB5F9EB1DC8C70F0030FC43 /* VoteApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = DCB5FA0C1DC8C70F0030FC43 /* Build configuration list for PBXNativeTarget "VoteApp" */; + buildPhases = ( + 1D9F47DD329150B4DE225340 /* [CP] Check Pods Manifest.lock */, + DCB5F9EA1DC8C70F0030FC43 /* Resources */, + DCB5FA0B1DC8C70F0030FC43 /* Embed App Extensions */, + BAA38EB0F70FDA81D8F41C57 /* Frameworks */, + 6069AF35BB210E780CCEDEDC /* [CP] Copy Pods Resources */, + 383911F5EECBE407BBE2C3A5 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + DCB5F9F91DC8C70F0030FC43 /* PBXTargetDependency */, + ); + name = VoteApp; + productName = VoteApp; + productReference = DCB5F9EC1DC8C70F0030FC43 /* VoteApp.app */; + productType = "com.apple.product-type.application.messages"; + }; + DCB5F9F51DC8C70F0030FC43 /* MessagesExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = DCB5FA081DC8C70F0030FC43 /* Build configuration list for PBXNativeTarget "MessagesExtension" */; + buildPhases = ( + 8BF6A18D5DABDA37951090DE /* [CP] Check Pods Manifest.lock */, + DCB5F9F21DC8C70F0030FC43 /* Sources */, + DCB5F9F31DC8C70F0030FC43 /* Frameworks */, + DCB5F9F41DC8C70F0030FC43 /* Resources */, + B984A87F17220FF5497BDB03 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MessagesExtension; + productName = MessagesExtension; + productReference = DCB5F9F61DC8C70F0030FC43 /* MessagesExtension.appex */; + productType = "com.apple.product-type.app-extension.messages"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DCB5F9E61DC8C70F0030FC43 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = "Ellina Kuznetcova"; + TargetAttributes = { + DCB5F9EB1DC8C70F0030FC43 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = C9ZJ96D59R; + ProvisioningStyle = Automatic; + }; + DCB5F9F51DC8C70F0030FC43 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = C9ZJ96D59R; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = DCB5F9E91DC8C70F0030FC43 /* Build configuration list for PBXProject "VoteApp" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DCB5F9E51DC8C70F0030FC43; + productRefGroup = DCB5F9ED1DC8C70F0030FC43 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DCB5F9EB1DC8C70F0030FC43 /* VoteApp */, + DCB5F9F51DC8C70F0030FC43 /* MessagesExtension */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DCB5F9EA1DC8C70F0030FC43 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCB5F9F01DC8C70F0030FC43 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCB5F9F41DC8C70F0030FC43 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCB5FA041DC8C70F0030FC43 /* Assets.xcassets in Resources */, + DCB5FA021DC8C70F0030FC43 /* MainInterface.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 1D9F47DD329150B4DE225340 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../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"; + showEnvVarsInLog = 0; + }; + 383911F5EECBE407BBE2C3A5 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 6069AF35BB210E780CCEDEDC /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Abstract-VoteApp/Pods-Abstract-VoteApp-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8BF6A18D5DABDA37951090DE /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../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"; + showEnvVarsInLog = 0; + }; + B984A87F17220FF5497BDB03 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Abstract-MessagesExtension/Pods-Abstract-MessagesExtension-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DCB5F9F21DC8C70F0030FC43 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCB5FA141DC8E7DE0030FC43 /* CompactViewController.swift in Sources */, + DCB5F9FF1DC8C70F0030FC43 /* MessagesViewController.swift in Sources */, + DCB5FA101DC8CE5D0030FC43 /* ExpandedViewController.swift in Sources */, + DC5635A91DCE297300E4840B /* PollEntity.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + DCB5F9F91DC8C70F0030FC43 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCB5F9F51DC8C70F0030FC43 /* MessagesExtension */; + targetProxy = DCB5F9F81DC8C70F0030FC43 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + DCB5FA001DC8C70F0030FC43 /* MainInterface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DCB5FA011DC8C70F0030FC43 /* Base */, + ); + name = MainInterface.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + DCB5FA061DC8C70F0030FC43 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + DCB5FA071DC8C70F0030FC43 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DCB5FA091DC8C70F0030FC43 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4E986ACCC82778BE3DDFDAAE /* Pods-Abstract-MessagesExtension.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; + DEVELOPMENT_TEAM = C9ZJ96D59R; + INFOPLIST_FILE = MessagesExtension/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eldkuznetcova.VoteApp1.MessagesExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + DCB5FA0A1DC8C70F0030FC43 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 32424C6FA93C9B93C60A587E /* Pods-Abstract-MessagesExtension.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; + DEVELOPMENT_TEAM = C9ZJ96D59R; + INFOPLIST_FILE = MessagesExtension/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eldkuznetcova.VoteApp1.MessagesExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + DCB5FA0D1DC8C70F0030FC43 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8BB6646EA54790B6C0F12530 /* Pods-Abstract-VoteApp.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = C9ZJ96D59R; + INFOPLIST_FILE = VoteApp/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.eldkuznetcova.VoteApp1; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + DCB5FA0E1DC8C70F0030FC43 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E2B350645C3A478E2B8E108B /* Pods-Abstract-VoteApp.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = C9ZJ96D59R; + INFOPLIST_FILE = VoteApp/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.eldkuznetcova.VoteApp1; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DCB5F9E91DC8C70F0030FC43 /* Build configuration list for PBXProject "VoteApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCB5FA061DC8C70F0030FC43 /* Debug */, + DCB5FA071DC8C70F0030FC43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DCB5FA081DC8C70F0030FC43 /* Build configuration list for PBXNativeTarget "MessagesExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCB5FA091DC8C70F0030FC43 /* Debug */, + DCB5FA0A1DC8C70F0030FC43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DCB5FA0C1DC8C70F0030FC43 /* Build configuration list for PBXNativeTarget "VoteApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCB5FA0D1DC8C70F0030FC43 /* Debug */, + DCB5FA0E1DC8C70F0030FC43 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DCB5F9E61DC8C70F0030FC43 /* Project object */; +} diff --git a/iMessagesExample/VoteApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iMessagesExample/VoteApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..42813d4 --- /dev/null +++ b/iMessagesExample/VoteApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iMessagesExample/VoteApp.xcworkspace/contents.xcworkspacedata b/iMessagesExample/VoteApp.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c2f1e30 --- /dev/null +++ b/iMessagesExample/VoteApp.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/iMessagesExample/VoteApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/iMessagesExample/VoteApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/iMessagesExample/VoteApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iMessagesExample/VoteApp/Info.plist b/iMessagesExample/VoteApp/Info.plist new file mode 100644 index 0000000..c12df3b --- /dev/null +++ b/iMessagesExample/VoteApp/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + From 372167474ee9268b950869e51728173b6e9021dd Mon Sep 17 00:00:00 2001 From: ellinakuznetcova Date: Sun, 20 Nov 2016 15:38:49 +0300 Subject: [PATCH 2/2] added siri kit example --- SiriKitExample/Podfile | 40 + SiriKitExample/Podfile.lock | 18 + SiriKitExample/Pods/Manifest.lock | 18 + .../Pods/Pods.xcodeproj/project.pbxproj | 1537 +++++++ SiriKitExample/Pods/Realm/LICENSE | 269 ++ SiriKitExample/Pods/Realm/README.md | 72 + .../src/collection_notifications.cpp | 56 + .../src/impl/apple/external_commit_helper.cpp | 226 ++ .../src/impl/collection_change_builder.cpp | 662 ++++ .../src/impl/collection_notifier.cpp | 344 ++ .../Realm/ObjectStore/src/impl/handover.cpp | 91 + .../ObjectStore/src/impl/list_notifier.cpp | 119 + .../src/impl/realm_coordinator.cpp | 603 +++ .../ObjectStore/src/impl/results_notifier.cpp | 219 + .../src/impl/transact_log_handler.cpp | 773 ++++ .../src/impl/weak_realm_notifier.cpp | 47 + .../Realm/Realm/ObjectStore/src/index_set.cpp | 707 ++++ .../Pods/Realm/Realm/ObjectStore/src/list.cpp | 229 ++ .../Realm/ObjectStore/src/object_schema.cpp | 222 ++ .../Realm/ObjectStore/src/object_store.cpp | 813 ++++ .../Realm/ObjectStore/src/placeholder.cpp | 1 + .../Realm/Realm/ObjectStore/src/results.cpp | 601 +++ .../Realm/Realm/ObjectStore/src/schema.cpp | 214 + .../Realm/ObjectStore/src/shared_realm.cpp | 671 ++++ .../Realm/ObjectStore/src/thread_confined.cpp | 126 + .../Realm/ObjectStore/src/util/format.cpp | 82 + .../Pods/Realm/Realm/RLMAccessor.mm | 800 ++++ .../Pods/Realm/Realm/RLMAnalytics.mm | 240 ++ SiriKitExample/Pods/Realm/Realm/RLMArray.mm | 439 ++ .../Pods/Realm/Realm/RLMArrayLinkView.mm | 424 ++ .../Pods/Realm/Realm/RLMClassInfo.mm | 107 + .../Pods/Realm/Realm/RLMCollection.mm | 344 ++ .../Pods/Realm/Realm/RLMConstants.m | 34 + .../Pods/Realm/Realm/RLMListBase.mm | 60 + .../Pods/Realm/Realm/RLMMigration.mm | 162 + SiriKitExample/Pods/Realm/Realm/RLMObject.mm | 223 ++ .../Pods/Realm/Realm/RLMObjectBase.mm | 450 +++ .../Pods/Realm/Realm/RLMObjectSchema.mm | 440 ++ .../Pods/Realm/Realm/RLMObjectStore.mm | 543 +++ .../Pods/Realm/Realm/RLMObservation.mm | 500 +++ .../Pods/Realm/Realm/RLMOptionalBase.mm | 89 + .../Pods/Realm/Realm/RLMPredicateUtil.mm | 118 + .../Pods/Realm/Realm/RLMProperty.mm | 569 +++ .../Pods/Realm/Realm/RLMQueryUtil.mm | 1378 +++++++ SiriKitExample/Pods/Realm/Realm/RLMRealm.mm | 689 ++++ .../Pods/Realm/Realm/RLMRealmConfiguration.mm | 295 ++ .../Pods/Realm/Realm/RLMRealmUtil.mm | 142 + SiriKitExample/Pods/Realm/Realm/RLMResults.mm | 444 +++ SiriKitExample/Pods/Realm/Realm/RLMSchema.mm | 338 ++ .../Pods/Realm/Realm/RLMSwiftSupport.m | 31 + .../Pods/Realm/Realm/RLMUpdateChecker.mm | 48 + SiriKitExample/Pods/Realm/Realm/RLMUtil.mm | 353 ++ .../Pods/Realm/Realm/module.modulemap | 27 + SiriKitExample/Pods/Realm/build.sh | 1261 ++++++ SiriKitExample/Pods/Realm/core/librealm-ios.a | Bin 0 -> 45497424 bytes .../Pods/Realm/include/RLMAccessor.h | 63 + .../Pods/Realm/include/RLMAnalytics.hpp | 55 + SiriKitExample/Pods/Realm/include/RLMArray.h | 369 ++ .../Pods/Realm/include/RLMArray_Private.h | 28 + .../Pods/Realm/include/RLMArray_Private.hpp | 70 + .../Pods/Realm/include/RLMClassInfo.hpp | 107 + .../Pods/Realm/include/RLMCollection.h | 325 ++ .../Realm/include/RLMCollection_Private.hpp | 72 + .../Pods/Realm/include/RLMConstants.h | 204 + .../Pods/Realm/include/RLMListBase.h | 33 + .../Pods/Realm/include/RLMMigration.h | 127 + .../Pods/Realm/include/RLMMigration_Private.h | 40 + SiriKitExample/Pods/Realm/include/RLMObject.h | 445 +++ .../Pods/Realm/include/RLMObjectBase.h | 41 + .../Realm/include/RLMObjectBase_Dynamic.h | 82 + .../Pods/Realm/include/RLMObjectSchema.h | 72 + .../Realm/include/RLMObjectSchema_Private.h | 68 + .../Realm/include/RLMObjectSchema_Private.hpp | 29 + .../Pods/Realm/include/RLMObjectStore.h | 102 + .../Pods/Realm/include/RLMObject_Private.h | 98 + .../Pods/Realm/include/RLMObject_Private.hpp | 58 + .../Pods/Realm/include/RLMObservation.hpp | 153 + .../Pods/Realm/include/RLMOptionalBase.h | 38 + .../Pods/Realm/include/RLMPlatform.h | 0 .../Pods/Realm/include/RLMPredicateUtil.hpp | 21 + SiriKitExample/Pods/Realm/include/RLMPrefix.h | 35 + .../Pods/Realm/include/RLMProperty.h | 121 + .../Pods/Realm/include/RLMProperty_Private.h | 111 + .../Realm/include/RLMProperty_Private.hpp | 29 + .../Pods/Realm/include/RLMQueryUtil.hpp | 42 + SiriKitExample/Pods/Realm/include/RLMRealm.h | 514 +++ .../Realm/include/RLMRealmConfiguration.h | 99 + .../include/RLMRealmConfiguration_Private.h | 42 + .../include/RLMRealmConfiguration_Private.hpp | 26 + .../Pods/Realm/include/RLMRealmUtil.hpp | 38 + .../Pods/Realm/include/RLMRealm_Dynamic.h | 118 + .../Pods/Realm/include/RLMRealm_Private.h | 54 + .../Pods/Realm/include/RLMRealm_Private.hpp | 36 + .../Pods/Realm/include/RLMResults.h | 332 ++ .../Pods/Realm/include/RLMResults_Private.h | 32 + SiriKitExample/Pods/Realm/include/RLMSchema.h | 77 + .../Pods/Realm/include/RLMSchema_Private.h | 54 + .../Pods/Realm/include/RLMSchema_Private.hpp | 31 + .../Realm/include/RLMSwiftBridgingHeader.h | 49 + .../Pods/Realm/include/RLMSwiftSupport.h | 30 + .../Pods/Realm/include/RLMUpdateChecker.hpp | 20 + SiriKitExample/Pods/Realm/include/RLMUtil.hpp | 200 + SiriKitExample/Pods/Realm/include/Realm.h | 30 + .../Pods/Realm/include/binding_context.hpp | 159 + .../include/collection_notifications.hpp | 71 + .../Pods/Realm/include/core/realm.hpp | 27 + .../Pods/Realm/include/core/realm/alloc.hpp | 444 +++ .../Realm/include/core/realm/alloc_slab.hpp | 568 +++ .../Pods/Realm/include/core/realm/array.hpp | 3522 +++++++++++++++++ .../Realm/include/core/realm/array_basic.hpp | 116 + .../include/core/realm/array_basic_tpl.hpp | 460 +++ .../Realm/include/core/realm/array_binary.hpp | 255 ++ .../Realm/include/core/realm/array_blob.hpp | 142 + .../include/core/realm/array_blobs_big.hpp | 219 + .../include/core/realm/array_integer.hpp | 660 +++ .../Realm/include/core/realm/array_string.hpp | 180 + .../include/core/realm/array_string_long.hpp | 226 ++ .../Realm/include/core/realm/binary_data.hpp | 217 + .../Pods/Realm/include/core/realm/bptree.hpp | 877 ++++ .../Pods/Realm/include/core/realm/column.hpp | 1500 +++++++ .../include/core/realm/column_backlink.hpp | 234 ++ .../include/core/realm/column_binary.hpp | 388 ++ .../Realm/include/core/realm/column_fwd.hpp | 54 + .../Realm/include/core/realm/column_link.hpp | 185 + .../include/core/realm/column_linkbase.hpp | 204 + .../include/core/realm/column_linklist.hpp | 251 ++ .../Realm/include/core/realm/column_mixed.hpp | 264 ++ .../include/core/realm/column_mixed_tpl.hpp | 508 +++ .../include/core/realm/column_string.hpp | 387 ++ .../include/core/realm/column_string_enum.hpp | 313 ++ .../Realm/include/core/realm/column_table.hpp | 603 +++ .../include/core/realm/column_timestamp.hpp | 142 + .../Realm/include/core/realm/column_tpl.hpp | 140 + .../Realm/include/core/realm/column_type.hpp | 70 + .../include/core/realm/column_type_traits.hpp | 175 + .../Realm/include/core/realm/commit_log.hpp | 52 + .../Realm/include/core/realm/data_type.hpp | 51 + .../Realm/include/core/realm/descriptor.hpp | 829 ++++ .../include/core/realm/descriptor_fwd.hpp | 33 + .../core/realm/disable_sync_to_disk.hpp | 37 + .../Realm/include/core/realm/exceptions.hpp | 252 ++ .../Pods/Realm/include/core/realm/group.hpp | 1379 +++++++ .../Realm/include/core/realm/group_shared.hpp | 1190 ++++++ .../Realm/include/core/realm/group_writer.hpp | 168 + .../include/core/realm/handover_defs.hpp | 82 + .../Pods/Realm/include/core/realm/history.hpp | 35 + .../include/core/realm/impl/array_writer.hpp | 42 + .../impl/continuous_transactions_history.hpp | 212 + .../include/core/realm/impl/destroy_guard.hpp | 229 ++ .../include/core/realm/impl/input_stream.hpp | 240 ++ .../include/core/realm/impl/output_stream.hpp | 78 + .../core/realm/impl/sequential_getter.hpp | 115 + .../core/realm/impl/simulated_failure.hpp | 216 + .../include/core/realm/impl/transact_log.hpp | 2638 ++++++++++++ .../Realm/include/core/realm/importer.hpp | 128 + .../Realm/include/core/realm/index_string.hpp | 540 +++ .../include/core/realm/lang_bind_helper.hpp | 393 ++ .../Realm/include/core/realm/link_view.hpp | 377 ++ .../include/core/realm/link_view_fwd.hpp | 32 + .../Pods/Realm/include/core/realm/mixed.hpp | 623 +++ .../Pods/Realm/include/core/realm/null.hpp | 129 + .../Realm/include/core/realm/olddatetime.hpp | 147 + .../Realm/include/core/realm/owned_data.hpp | 80 + .../Pods/Realm/include/core/realm/query.hpp | 428 ++ .../include/core/realm/query_conditions.hpp | 386 ++ .../Realm/include/core/realm/query_engine.hpp | 1748 ++++++++ .../include/core/realm/query_expression.hpp | 2848 +++++++++++++ .../include/core/realm/realm_nmmintrin.h | 182 + .../Realm/include/core/realm/replication.hpp | 533 +++ .../Pods/Realm/include/core/realm/row.hpp | 813 ++++ .../Pods/Realm/include/core/realm/spec.hpp | 474 +++ .../Realm/include/core/realm/string_data.hpp | 326 ++ .../Pods/Realm/include/core/realm/table.hpp | 2390 +++++++++++ .../include/core/realm/table_accessors.hpp | 1737 ++++++++ .../Realm/include/core/realm/table_basic.hpp | 748 ++++ .../include/core/realm/table_basic_fwd.hpp | 38 + .../Realm/include/core/realm/table_macros.hpp | 935 +++++ .../Realm/include/core/realm/table_ref.hpp | 454 +++ .../Realm/include/core/realm/table_view.hpp | 1572 ++++++++ .../include/core/realm/table_view_basic.hpp | 372 ++ .../Realm/include/core/realm/timestamp.hpp | 120 + .../Pods/Realm/include/core/realm/unicode.hpp | 156 + .../Realm/include/core/realm/util/assert.hpp | 109 + .../core/realm/util/basic_system_errors.hpp | 92 + .../include/core/realm/util/bind_ptr.hpp | 366 ++ .../Realm/include/core/realm/util/buffer.hpp | 259 ++ .../core/realm/util/call_with_tuple.hpp | 56 + .../Realm/include/core/realm/util/cf_ptr.hpp | 108 + .../Realm/include/core/realm/util/config.h | 27 + .../realm/util/encrypted_file_mapping.hpp | 155 + .../Realm/include/core/realm/util/features.h | 265 ++ .../Realm/include/core/realm/util/file.hpp | 1133 ++++++ .../include/core/realm/util/file_mapper.hpp | 122 + .../include/core/realm/util/hex_dump.hpp | 55 + .../Realm/include/core/realm/util/inspect.hpp | 76 + .../core/realm/util/interprocess_condvar.hpp | 130 + .../core/realm/util/interprocess_mutex.hpp | 264 ++ .../Realm/include/core/realm/util/logger.hpp | 486 +++ .../include/core/realm/util/memory_stream.hpp | 205 + .../Realm/include/core/realm/util/meta.hpp | 39 + .../include/core/realm/util/misc_errors.hpp | 50 + .../include/core/realm/util/miscellaneous.hpp | 49 + .../include/core/realm/util/optional.hpp | 627 +++ .../core/realm/util/priority_queue.hpp | 310 ++ .../include/core/realm/util/safe_int_ops.hpp | 632 +++ .../include/core/realm/util/scope_exit.hpp | 72 + .../include/core/realm/util/shared_ptr.hpp | 129 + .../include/core/realm/util/string_buffer.hpp | 186 + .../include/core/realm/util/terminate.hpp | 72 + .../Realm/include/core/realm/util/thread.hpp | 588 +++ .../include/core/realm/util/to_string.hpp | 71 + .../Realm/include/core/realm/util/tuple.hpp | 185 + .../include/core/realm/util/type_list.hpp | 229 ++ .../include/core/realm/util/type_traits.hpp | 159 + .../Realm/include/core/realm/util/utf8.hpp | 393 ++ .../Realm/include/core/realm/utilities.hpp | 235 ++ .../Pods/Realm/include/core/realm/version.hpp | 54 + .../Pods/Realm/include/core/realm/views.hpp | 126 + .../impl/apple/external_commit_helper.hpp | 80 + .../impl/collection_change_builder.hpp | 67 + .../include/impl/collection_notifier.hpp | 247 ++ .../include/impl/external_commit_helper.hpp | 32 + .../Pods/Realm/include/impl/handover.hpp | 84 + .../Pods/Realm/include/impl/list_notifier.hpp | 59 + .../Realm/include/impl/realm_coordinator.hpp | 131 + .../Realm/include/impl/results_notifier.hpp | 84 + .../include/impl/transact_log_handler.hpp | 59 + .../include/impl/weak_realm_notifier.hpp | 75 + .../Pods/Realm/include/index_set.hpp | 326 ++ SiriKitExample/Pods/Realm/include/list.hpp | 130 + .../Pods/Realm/include/object_accessor.hpp | 432 ++ .../Pods/Realm/include/object_schema.hpp | 66 + .../Pods/Realm/include/object_store.hpp | 147 + .../Pods/Realm/include/property.hpp | 150 + SiriKitExample/Pods/Realm/include/results.hpp | 227 ++ SiriKitExample/Pods/Realm/include/schema.hpp | 166 + .../Pods/Realm/include/shared_realm.hpp | 390 ++ .../Pods/Realm/include/thread_confined.hpp | 75 + .../include/util/apple/event_loop_signal.hpp | 82 + .../Realm/include/util/atomic_shared_ptr.hpp | 137 + .../Pods/Realm/include/util/compiler.hpp | 34 + .../Realm/include/util/event_loop_signal.hpp | 34 + .../Pods/Realm/include/util/format.hpp | 75 + SiriKitExample/Pods/RealmSwift/LICENSE | 269 ++ SiriKitExample/Pods/RealmSwift/README.md | 72 + .../Pods/RealmSwift/RealmSwift/Aliases.swift | 57 + .../Pods/RealmSwift/RealmSwift/Error.swift | 283 ++ .../RealmSwift/LinkingObjects.swift | 809 ++++ .../Pods/RealmSwift/RealmSwift/List.swift | 1027 +++++ .../RealmSwift/RealmSwift/Migration.swift | 420 ++ .../Pods/RealmSwift/RealmSwift/Object.swift | 737 ++++ .../RealmSwift/RealmSwift/ObjectSchema.swift | 151 + .../Pods/RealmSwift/RealmSwift/Optional.swift | 103 + .../Pods/RealmSwift/RealmSwift/Property.swift | 134 + .../Pods/RealmSwift/RealmSwift/Realm.swift | 1250 ++++++ .../RealmSwift/RealmCollection.swift | 1543 ++++++++ .../RealmSwift/RealmConfiguration.swift | 407 ++ .../Pods/RealmSwift/RealmSwift/Results.swift | 821 ++++ .../Pods/RealmSwift/RealmSwift/Schema.swift | 129 + .../RealmSwift/SortDescriptor.swift | 223 ++ .../RealmSwift/RealmSwift/SwiftVersion.swift | 1 + .../Pods/RealmSwift/RealmSwift/Util.swift | 219 + SiriKitExample/Pods/RealmSwift/build.sh | 1261 ++++++ .../Pods-Abstract-SiriKitExample/Info.plist | 26 + ...t-SiriKitExample-acknowledgements.markdown | 549 +++ ...ract-SiriKitExample-acknowledgements.plist | 583 +++ .../Pods-Abstract-SiriKitExample-dummy.m | 5 + ...Pods-Abstract-SiriKitExample-frameworks.sh | 93 + .../Pods-Abstract-SiriKitExample-resources.sh | 102 + .../Pods-Abstract-SiriKitExample-umbrella.h | 6 + ...ods-Abstract-SiriKitExample.debug.xcconfig | 10 + .../Pods-Abstract-SiriKitExample.modulemap | 6 + ...s-Abstract-SiriKitExample.release.xcconfig | 10 + .../Info.plist | 26 + ...xampleSiriIntent-acknowledgements.markdown | 549 +++ ...itExampleSiriIntent-acknowledgements.plist | 583 +++ ...-Abstract-SiriKitExampleSiriIntent-dummy.m | 5 + ...act-SiriKitExampleSiriIntent-frameworks.sh | 93 + ...ract-SiriKitExampleSiriIntent-resources.sh | 102 + ...stract-SiriKitExampleSiriIntent-umbrella.h | 6 + ...ct-SiriKitExampleSiriIntent.debug.xcconfig | 10 + ...bstract-SiriKitExampleSiriIntent.modulemap | 6 + ...-SiriKitExampleSiriIntent.release.xcconfig | 10 + .../Info.plist | 26 + ...mpleSiriIntentUI-acknowledgements.markdown | 549 +++ ...ExampleSiriIntentUI-acknowledgements.plist | 583 +++ ...bstract-SiriKitExampleSiriIntentUI-dummy.m | 5 + ...t-SiriKitExampleSiriIntentUI-frameworks.sh | 93 + ...ct-SiriKitExampleSiriIntentUI-resources.sh | 102 + ...ract-SiriKitExampleSiriIntentUI-umbrella.h | 6 + ...-SiriKitExampleSiriIntentUI.debug.xcconfig | 10 + ...tract-SiriKitExampleSiriIntentUI.modulemap | 6 + ...iriKitExampleSiriIntentUI.release.xcconfig | 10 + .../Target Support Files/Realm/Info.plist | 26 + .../Target Support Files/Realm/Realm-dummy.m | 5 + .../Realm/Realm-prefix.pch | 4 + .../Realm/Realm.modulemap | 27 + .../Target Support Files/Realm/Realm.xcconfig | 13 + .../RealmSwift/Info.plist | 26 + .../RealmSwift/RealmSwift-dummy.m | 5 + .../RealmSwift/RealmSwift-prefix.pch | 4 + .../RealmSwift/RealmSwift-umbrella.h | 6 + .../RealmSwift/RealmSwift.modulemap | 6 + .../RealmSwift/RealmSwift.xcconfig | 12 + .../SiriKitExample.xcodeproj/project.pbxproj | 793 ++++ .../contents.xcworkspacedata | 7 + .../contents.xcworkspacedata | 10 + .../SiriKitExample/AppDelegate.swift | 49 + .../AppIcon.appiconset/Contents.json | 48 + ...076086-Cockroach-vector-Stock-Vector-1.jpg | Bin 0 -> 106206 bytes ...076086-Cockroach-vector-Stock-Vector-2.jpg | Bin 0 -> 106206 bytes ...39076086-Cockroach-vector-Stock-Vector.jpg | Bin 0 -> 106206 bytes .../Cockroach.imageset/Contents.json | 23 + .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 27 + .../SiriKitExample/Base.lproj/Main.storyboard | 107 + SiriKitExample/SiriKitExample/BridgeHeader.h | 10 + .../ContactsViewController.swift | 44 + SiriKitExample/SiriKitExample/Database.swift | 61 + SiriKitExample/SiriKitExample/Info.plist | 40 + .../MessagesTableViewController.swift | 28 + .../SiriKitExample.entitlements | 10 + .../SiriKitExampleSiriIntent/Info.plist | 42 + .../IntentHandler.swift | 114 + .../SiriKitExampleSiriIntent.entitlements | 10 + .../Base.lproj/MainInterface.storyboard | 47 + .../SiriKitExampleSiriIntentUI/Info.plist | 38 + .../IntentViewController.swift | 40 + 328 files changed, 91553 insertions(+) create mode 100644 SiriKitExample/Podfile create mode 100644 SiriKitExample/Podfile.lock create mode 100644 SiriKitExample/Pods/Manifest.lock create mode 100644 SiriKitExample/Pods/Pods.xcodeproj/project.pbxproj create mode 100644 SiriKitExample/Pods/Realm/LICENSE create mode 100644 SiriKitExample/Pods/Realm/README.md create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/collection_notifications.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_change_builder.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_notifier.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/handover.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/list_notifier.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/realm_coordinator.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/results_notifier.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/transact_log_handler.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/index_set.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/list.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_schema.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_store.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/placeholder.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/results.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/schema.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/shared_realm.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/thread_confined.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/ObjectStore/src/util/format.cpp create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMAccessor.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMAnalytics.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMArray.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMArrayLinkView.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMClassInfo.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMCollection.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMConstants.m create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMListBase.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMMigration.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMObject.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMObjectBase.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMObjectSchema.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMObjectStore.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMObservation.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMOptionalBase.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMPredicateUtil.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMProperty.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMQueryUtil.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMRealm.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMRealmConfiguration.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMRealmUtil.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMResults.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMSchema.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMSwiftSupport.m create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMUpdateChecker.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/RLMUtil.mm create mode 100644 SiriKitExample/Pods/Realm/Realm/module.modulemap create mode 100755 SiriKitExample/Pods/Realm/build.sh create mode 100644 SiriKitExample/Pods/Realm/core/librealm-ios.a create mode 100644 SiriKitExample/Pods/Realm/include/RLMAccessor.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMAnalytics.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMArray.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMArray_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMArray_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMClassInfo.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMCollection.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMCollection_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMConstants.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMListBase.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMMigration.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMMigration_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObject.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectBase.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectBase_Dynamic.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectSchema.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectSchema_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectSchema_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMObjectStore.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObject_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMObject_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMObservation.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMOptionalBase.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMPlatform.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMPredicateUtil.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMPrefix.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMProperty.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMProperty_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMProperty_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMQueryUtil.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealm.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealmConfiguration.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealmConfiguration_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealmConfiguration_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealmUtil.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealm_Dynamic.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealm_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMRealm_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMResults.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMResults_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMSchema.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMSchema_Private.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMSchema_Private.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMSwiftBridgingHeader.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMSwiftSupport.h create mode 100644 SiriKitExample/Pods/Realm/include/RLMUpdateChecker.hpp create mode 100644 SiriKitExample/Pods/Realm/include/RLMUtil.hpp create mode 100644 SiriKitExample/Pods/Realm/include/Realm.h create mode 100644 SiriKitExample/Pods/Realm/include/binding_context.hpp create mode 100644 SiriKitExample/Pods/Realm/include/collection_notifications.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/alloc.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/alloc_slab.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_basic.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_basic_tpl.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_binary.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_blob.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_blobs_big.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_integer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_string.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/array_string_long.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/binary_data.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/bptree.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_backlink.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_binary.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_fwd.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_link.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_linkbase.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_linklist.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_mixed.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_mixed_tpl.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_string.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_string_enum.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_table.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_timestamp.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_tpl.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_type.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/column_type_traits.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/commit_log.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/data_type.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/descriptor.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/descriptor_fwd.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/disable_sync_to_disk.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/exceptions.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/group.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/group_shared.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/group_writer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/handover_defs.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/history.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/array_writer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/continuous_transactions_history.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/destroy_guard.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/input_stream.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/output_stream.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/sequential_getter.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/simulated_failure.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/impl/transact_log.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/importer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/index_string.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/lang_bind_helper.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/link_view.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/link_view_fwd.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/mixed.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/null.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/olddatetime.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/owned_data.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/query.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/query_conditions.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/query_engine.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/query_expression.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/realm_nmmintrin.h create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/replication.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/row.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/spec.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/string_data.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_accessors.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_basic.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_basic_fwd.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_macros.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_ref.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_view.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/table_view_basic.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/timestamp.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/unicode.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/assert.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/basic_system_errors.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/bind_ptr.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/buffer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/call_with_tuple.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/cf_ptr.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/config.h create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/encrypted_file_mapping.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/features.h create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/file.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/file_mapper.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/hex_dump.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/inspect.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/interprocess_condvar.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/interprocess_mutex.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/logger.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/memory_stream.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/meta.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/misc_errors.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/miscellaneous.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/optional.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/priority_queue.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/safe_int_ops.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/scope_exit.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/shared_ptr.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/string_buffer.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/terminate.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/thread.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/to_string.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/tuple.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/type_list.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/type_traits.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/util/utf8.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/utilities.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/version.hpp create mode 100644 SiriKitExample/Pods/Realm/include/core/realm/views.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/apple/external_commit_helper.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/collection_change_builder.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/collection_notifier.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/external_commit_helper.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/handover.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/list_notifier.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/realm_coordinator.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/results_notifier.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/transact_log_handler.hpp create mode 100644 SiriKitExample/Pods/Realm/include/impl/weak_realm_notifier.hpp create mode 100644 SiriKitExample/Pods/Realm/include/index_set.hpp create mode 100644 SiriKitExample/Pods/Realm/include/list.hpp create mode 100644 SiriKitExample/Pods/Realm/include/object_accessor.hpp create mode 100644 SiriKitExample/Pods/Realm/include/object_schema.hpp create mode 100644 SiriKitExample/Pods/Realm/include/object_store.hpp create mode 100644 SiriKitExample/Pods/Realm/include/property.hpp create mode 100644 SiriKitExample/Pods/Realm/include/results.hpp create mode 100644 SiriKitExample/Pods/Realm/include/schema.hpp create mode 100644 SiriKitExample/Pods/Realm/include/shared_realm.hpp create mode 100644 SiriKitExample/Pods/Realm/include/thread_confined.hpp create mode 100644 SiriKitExample/Pods/Realm/include/util/apple/event_loop_signal.hpp create mode 100644 SiriKitExample/Pods/Realm/include/util/atomic_shared_ptr.hpp create mode 100644 SiriKitExample/Pods/Realm/include/util/compiler.hpp create mode 100644 SiriKitExample/Pods/Realm/include/util/event_loop_signal.hpp create mode 100644 SiriKitExample/Pods/Realm/include/util/format.hpp create mode 100644 SiriKitExample/Pods/RealmSwift/LICENSE create mode 100644 SiriKitExample/Pods/RealmSwift/README.md create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Aliases.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Error.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/LinkingObjects.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/List.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Migration.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Object.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/ObjectSchema.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Optional.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Property.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Realm.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/RealmCollection.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/RealmConfiguration.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Results.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Schema.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/SortDescriptor.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/SwiftVersion.swift create mode 100644 SiriKitExample/Pods/RealmSwift/RealmSwift/Util.swift create mode 100755 SiriKitExample/Pods/RealmSwift/build.sh create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Info.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-acknowledgements.markdown create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-acknowledgements.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-dummy.m create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-frameworks.sh create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-resources.sh create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample-umbrella.h create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample.debug.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample.modulemap create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample.release.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Info.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.markdown create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-dummy.m create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-frameworks.sh create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-resources.sh create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent.debug.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent.modulemap create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent.release.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Info.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.markdown create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-frameworks.sh create mode 100755 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-resources.sh create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI.debug.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap create mode 100644 SiriKitExample/Pods/Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI.release.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/Realm/Info.plist create mode 100644 SiriKitExample/Pods/Target Support Files/Realm/Realm-dummy.m create mode 100644 SiriKitExample/Pods/Target Support Files/Realm/Realm-prefix.pch create mode 100644 SiriKitExample/Pods/Target Support Files/Realm/Realm.modulemap create mode 100644 SiriKitExample/Pods/Target Support Files/Realm/Realm.xcconfig create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/Info.plist create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/RealmSwift-dummy.m create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/RealmSwift-prefix.pch create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/RealmSwift-umbrella.h create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/RealmSwift.modulemap create mode 100644 SiriKitExample/Pods/Target Support Files/RealmSwift/RealmSwift.xcconfig create mode 100644 SiriKitExample/SiriKitExample.xcodeproj/project.pbxproj create mode 100644 SiriKitExample/SiriKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 SiriKitExample/SiriKitExample.xcworkspace/contents.xcworkspacedata create mode 100644 SiriKitExample/SiriKitExample/AppDelegate.swift create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/Cockroach.imageset/39076086-Cockroach-vector-Stock-Vector-1.jpg create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/Cockroach.imageset/39076086-Cockroach-vector-Stock-Vector-2.jpg create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/Cockroach.imageset/39076086-Cockroach-vector-Stock-Vector.jpg create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/Cockroach.imageset/Contents.json create mode 100644 SiriKitExample/SiriKitExample/Assets.xcassets/Contents.json create mode 100644 SiriKitExample/SiriKitExample/Base.lproj/LaunchScreen.storyboard create mode 100644 SiriKitExample/SiriKitExample/Base.lproj/Main.storyboard create mode 100644 SiriKitExample/SiriKitExample/BridgeHeader.h create mode 100644 SiriKitExample/SiriKitExample/ContactsViewController.swift create mode 100644 SiriKitExample/SiriKitExample/Database.swift create mode 100644 SiriKitExample/SiriKitExample/Info.plist create mode 100644 SiriKitExample/SiriKitExample/MessagesTableViewController.swift create mode 100644 SiriKitExample/SiriKitExample/SiriKitExample.entitlements create mode 100644 SiriKitExample/SiriKitExampleSiriIntent/Info.plist create mode 100644 SiriKitExample/SiriKitExampleSiriIntent/IntentHandler.swift create mode 100644 SiriKitExample/SiriKitExampleSiriIntent/SiriKitExampleSiriIntent.entitlements create mode 100644 SiriKitExample/SiriKitExampleSiriIntentUI/Base.lproj/MainInterface.storyboard create mode 100644 SiriKitExample/SiriKitExampleSiriIntentUI/Info.plist create mode 100644 SiriKitExample/SiriKitExampleSiriIntentUI/IntentViewController.swift diff --git a/SiriKitExample/Podfile b/SiriKitExample/Podfile new file mode 100644 index 0000000..50875d1 --- /dev/null +++ b/SiriKitExample/Podfile @@ -0,0 +1,40 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' +source 'https://github.com/CocoaPods/Specs.git' +use_frameworks! + +abstract_target 'Abstract' do + pod 'RealmSwift', '=1.1.0' + + target 'SiriKitExample' do + # Comment this line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for SiriKitExample + + end + + target 'SiriKitExampleSiriIntent' do + # Comment this line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for SiriKitExampleSiriIntent + + end + + target 'SiriKitExampleSiriIntentUI' do + # Comment this line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for SiriKitExampleSiriIntentUI + + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '3.0' + end + end +end diff --git a/SiriKitExample/Podfile.lock b/SiriKitExample/Podfile.lock new file mode 100644 index 0000000..a385a13 --- /dev/null +++ b/SiriKitExample/Podfile.lock @@ -0,0 +1,18 @@ +PODS: + - Realm (1.1.0): + - Realm/Headers (= 1.1.0) + - Realm/Headers (1.1.0) + - RealmSwift (1.1.0): + - Realm (= 1.1.0) + +DEPENDENCIES: + - Realm (= 1.1.0) + - RealmSwift (= 1.1.0) + +SPEC CHECKSUMS: + Realm: ceecf1a4540c4ce9efe196fe73fa9855bce05bd8 + RealmSwift: 838058b2db95b12cb86bd0cf209df642c33fb60a + +PODFILE CHECKSUM: 1e6b407e0eb444986d1748d016d1ba6da842e7e4 + +COCOAPODS: 1.0.1 diff --git a/SiriKitExample/Pods/Manifest.lock b/SiriKitExample/Pods/Manifest.lock new file mode 100644 index 0000000..a385a13 --- /dev/null +++ b/SiriKitExample/Pods/Manifest.lock @@ -0,0 +1,18 @@ +PODS: + - Realm (1.1.0): + - Realm/Headers (= 1.1.0) + - Realm/Headers (1.1.0) + - RealmSwift (1.1.0): + - Realm (= 1.1.0) + +DEPENDENCIES: + - Realm (= 1.1.0) + - RealmSwift (= 1.1.0) + +SPEC CHECKSUMS: + Realm: ceecf1a4540c4ce9efe196fe73fa9855bce05bd8 + RealmSwift: 838058b2db95b12cb86bd0cf209df642c33fb60a + +PODFILE CHECKSUM: 1e6b407e0eb444986d1748d016d1ba6da842e7e4 + +COCOAPODS: 1.0.1 diff --git a/SiriKitExample/Pods/Pods.xcodeproj/project.pbxproj b/SiriKitExample/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8e73b9e --- /dev/null +++ b/SiriKitExample/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,1537 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0032CE35FD56A9809E13FE36112D4A67 /* RLMResults_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = B85217406965A6F439FF8370D33C4D13 /* RLMResults_Private.h */; }; + 06E9608AE8E74C3C2A6F2AC98F3CAA47 /* RLMAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = E523BF9B67952F3971734F9317759B48 /* RLMAccessor.h */; }; + 0757ACA979B39BC77B19DB23F9BAF7D3 /* RLMSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = 621975F8E2D07283D4AFE111B207491C /* RLMSchema.h */; }; + 090E3BF32CACCCDA18635B5EFA3F6773 /* RLMArrayLinkView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 22B3A9988AC2D49D500963159791BAB0 /* RLMArrayLinkView.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 09190384DB804249A521861B0D013309 /* RLMResults.mm in Sources */ = {isa = PBXBuildFile; fileRef = 796154D364E38B24B9890EA21530520D /* RLMResults.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 0E6097E6182D1D3722A52056543791C0 /* SwiftVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75B1B8751A4AA764288FF4C735A2E33 /* SwiftVersion.swift */; }; + 109F4E72BC4880D226C9263224FECB2C /* transact_log_handler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F7F8AF36B00C7B7206B10B9BBFCC872 /* transact_log_handler.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 15320D1811842F9FEA775373C9BD0033 /* RLMObjectSchema_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 5649F569F9DF6A08A2C9A142D69D824F /* RLMObjectSchema_Private.h */; }; + 159C243AAFA2525170BAD64C82A030F2 /* RLMQueryUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = B7C9195E39B50F15B65918F41965369D /* RLMQueryUtil.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 1618AA5ABA295D086860863BB5CF7A7C /* List.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7532539A224F0219EA76B5F5FBCFB0D1 /* List.swift */; }; + 170370A76F95C2C3C13FB9F6FC62008A /* RLMObject_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = CFFE0D23E969576A357BF2632E504749 /* RLMObject_Private.h */; }; + 1E4C1B93DD3FA97246C75956C353C218 /* RLMPlatform.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 90C7D93637C4F5BFDCCC2F9A2B9B9286 /* RLMPlatform.h */; }; + 20B778958110774A871B70FC97031224 /* RealmConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F287A91BE127F2A2441F1834D7537E23 /* RealmConfiguration.swift */; }; + 24881ECA02B40B7ABFD4F7799A668E9F /* RLMResults.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = D095A3DC68EAD70B6FA15C99B9C2570A /* RLMResults.h */; }; + 2582147E6FC78D914D28C4A301D385E3 /* Realm-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 143DC32879715A3E635833619C5C546A /* Realm-dummy.m */; }; + 28A6A562B690B7B1A77DD15AAA54308C /* Realm.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = A1D50ABD8B5F4727C844FAEB7141E8B0 /* Realm.h */; }; + 2ABE2EE6F824F681E8C185C250064753 /* RLMObjectBase.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 63A5177E90000F5EB6C5C76970347FC5 /* RLMObjectBase.h */; }; + 2BF488A853A7ED449E21A57037593252 /* RLMCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 05F1E405B6EE64A4266CF425DD80288A /* RLMCollection.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 2EBEA5B819D72BB30B3AC954E1311507 /* RLMObject.h in Headers */ = {isa = PBXBuildFile; fileRef = FF3374CF1BA7A1E0981140D0622EEAAC /* RLMObject.h */; }; + 308DBD588CB086F494FD66FD734E0791 /* Realm.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D50ABD8B5F4727C844FAEB7141E8B0 /* Realm.h */; }; + 30D089762C6D1158000EAF58FBEE81A2 /* RLMAnalytics.mm in Sources */ = {isa = PBXBuildFile; fileRef = 436ABD7A1A7F658B25967AD37A2AFCA6 /* RLMAnalytics.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 3301C49F45060513DEC43EDA3F0BBEE0 /* Pods-Abstract-SiriKitExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08E18F888ED89072D2E3FF4EFCD7F518 /* Pods-Abstract-SiriKitExample-dummy.m */; }; + 379DBAA26A6534AF62C49F5A94F97E22 /* Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E860CC888D6662669EE9098252D355 /* Object.swift */; }; + 386EBD553B521BCA407355DB39C50A4C /* RLMProperty_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 58611CC7789C0314F5F25E105472E232 /* RLMProperty_Private.h */; }; + 389DDD3F94482813BB443A124A087708 /* RLMSchema.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0479CCE8A914E5585FDE2514545FAC8E /* RLMSchema.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 39780F2254CF9CD9BFF5094E2F78408A /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3056258FD0C38D6DCC75B798FA2ABDAC /* Realm.framework */; }; + 3AB39C4EF009A6CFE9C8F7AE0BB00F27 /* RLMObjectStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EDF0B3EDC8560C1EB73D58225CBF327 /* RLMObjectStore.h */; }; + 3C1F68A5F2A977F95C3CC225100C7965 /* RLMObjectBase_Dynamic.h in Headers */ = {isa = PBXBuildFile; fileRef = AD8FDA9F9D69AA41E037199C5E1C9123 /* RLMObjectBase_Dynamic.h */; }; + 3C4AC116155C1A9D10970370C068F1CC /* RLMRealmConfiguration.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 866724B2FEEAE5E537FB6AF285FCC55E /* RLMRealmConfiguration.h */; }; + 3F7077F2CAA3CF2024F054302A2313E1 /* RLMObject_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CFFE0D23E969576A357BF2632E504749 /* RLMObject_Private.h */; }; + 48721CD9685E6C4E1619FFA82BE1DCF8 /* RLMListBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2529FD63B39AD3AC3E46684AE4528109 /* RLMListBase.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 4B161B734697381360EBB4B800394ABF /* results.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55108D804B83B5199434A09ED9B306D0 /* results.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 4CAD46B805FD287D2F16A351067A3E7A /* Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A160C124D3797D418F557BC77D76FA8C /* Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4D3B0A0477202370A065534A610AC13B /* RealmCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21094FAC31FEBEACBFC2F9DBE288F387 /* RealmCollection.swift */; }; + 4D649D6A1A75EF8570BEBB6EE11EECB1 /* RLMMigration_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 67156F56A6251C094C18417C5E9CAF1C /* RLMMigration_Private.h */; }; + 4F6AFE53BCCA4C549B3B849541B7C723 /* RLMObjectBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0D2DDEF3DA55C4F5335E491E2DB6008B /* RLMObjectBase.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 50A490D5505F22DADABC331A79544FFB /* RLMMigration_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 67156F56A6251C094C18417C5E9CAF1C /* RLMMigration_Private.h */; }; + 5456A76985ACE8F58DB10DC139D9A321 /* Pods-Abstract-SiriKitExampleSiriIntent-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1909B62FDD4B8F52E6A10315D4D0E3A1 /* Pods-Abstract-SiriKitExampleSiriIntent-dummy.m */; }; + 54FC7E1578A81A8FDB69A5E73A755873 /* RLMUpdateChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BADDE90620AC871ADC94A08D389C458 /* RLMUpdateChecker.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 56EF6E8267B5C456E87841396E46A602 /* RLMClassInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = C44E32CBCA86DBF2F268050E9BB1C264 /* RLMClassInfo.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 57112DB3C1568FF688E4A7645B650ED7 /* RLMListBase.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = CE5A233AD6FCDACD9E070CFB9D4958F2 /* RLMListBase.h */; }; + 577C7CAFD9C818A473AF92DF75B689CF /* RLMObjectSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D100467E73BD5628A5FFC41F9006414 /* RLMObjectSchema.h */; }; + 579D1F26C25384DD1DB1BE5BC33B72EE /* Pods-Abstract-SiriKitExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 165B902CFE265EB6898DF8F3E3F66F3E /* Pods-Abstract-SiriKitExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 588F364D3C237788E4D9A3353E88FD09 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */; }; + 5BC67B848FE9E757410073CF20D1B003 /* collection_notifications.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AF8951163295E8B49F8C9BCFA16DED8 /* collection_notifications.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 5BE23D2809AFB0B1D84AED71E9C258D2 /* RLMMigration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31B0BBCB19A28A16EFB1F585DD5699C0 /* RLMMigration.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 5C30F771D4003B95B54FD0BF29ACFD7F /* RealmSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EEF7197CDB194B4337C9C9B6B25C2CDE /* RealmSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5D72D32649B32EE66BBC2DEB6750B016 /* RLMListBase.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = CE5A233AD6FCDACD9E070CFB9D4958F2 /* RLMListBase.h */; }; + 60AA25A9AEDC5828041641B69BBF8049 /* collection_change_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5590FE1B6ACFE1AAE6F2B3E5587D853E /* collection_change_builder.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 60C531BAE48A0A5B35302809CB84CA1D /* object_schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 98F80099DEF4E44E8F77F4971C2195E5 /* object_schema.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 60CBEA8A37D3CE527F732EC7E346B519 /* LinkingObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5C9A1BFE4964D63F58EFDAF8603762 /* LinkingObjects.swift */; }; + 61C11AA4752CBC5BBD26108003D73BA6 /* RLMArray.mm in Sources */ = {isa = PBXBuildFile; fileRef = 366F3B848DF7588701BBDCE39BBC072A /* RLMArray.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 6213148FB5114B5C8625C4D585849E33 /* RLMCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = BB00326D562DD60AC0D4F1E1BDA599D7 /* RLMCollection.h */; }; + 64724617867E866EBDB3BBDCB74DEA8A /* RLMAccessor.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = E523BF9B67952F3971734F9317759B48 /* RLMAccessor.h */; }; + 65213987CE11AA7CB11C26AEDCF12165 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */; }; + 660E7F5B8AED1B3301F2E38347D2CD2B /* placeholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49EE2F5DA1E1A1E29B94A21CF861C587 /* placeholder.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 666629576DF9FBE3C9E114B560474BD0 /* RLMPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 90C7D93637C4F5BFDCCC2F9A2B9B9286 /* RLMPlatform.h */; }; + 686A203451FB59581664B3B43C59D53B /* index_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7972404FF3C4260EB6A2F72B20C9C8FD /* index_set.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 68F7A0C1742C3E95661570A956703360 /* Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4008BCBE7C5C87F38E54502626171CBB /* Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m */; }; + 69513F2307371DEEDA34CA955F53D1B8 /* RLMSchema.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 621975F8E2D07283D4AFE111B207491C /* RLMSchema.h */; }; + 6A95EA452F3E3262197CC9C95FC7BD84 /* RLMRealmUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A6DE5974160987A403ED465DB108BDF /* RLMRealmUtil.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 6AFC52FA3D9F3A68377A304590151CA1 /* RLMRealmConfiguration_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 7F06BCF01D58FE275D42F53050091054 /* RLMRealmConfiguration_Private.h */; }; + 6DBEDA0734A6AD7B35EA9ABAAB63CC25 /* external_commit_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 198A65BDE5F32B4ACAB8478993490991 /* external_commit_helper.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 6E1FDCF23A17A4B0E4601A81B34DB8AF /* Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 47DB5419A1875CDABB71BE330FDC2CDB /* Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 70114BD12454E3BB6E6787CCBB3432D9 /* object_store.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5DCC8BF3630AF6D49DD2B88CD6E2BF8 /* object_store.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 7239C68D18BB84959ED6513D26B33F5D /* ObjectSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F9E161B6AAB03BF52DA8807936A222 /* ObjectSchema.swift */; }; + 730ADA732D8A76E1A376ABDA73511194 /* RLMArray.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 1990F65EE5CD3970B95801EC893F7023 /* RLMArray.h */; }; + 76B745E1B6ED833C8492EC03D19248C0 /* RLMArray_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 07255E0F2C2E324D44ED065E23A4DC2E /* RLMArray_Private.h */; }; + 7799DBD9DB4A7A983D6AB2F54DB4292A /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B179AE470981EC3AA10725491B2C442 /* Property.swift */; }; + 7AFC3B8025AAAC7333FAB641FBCB01C3 /* Aliases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70CA05FDBC8B43930550B71713D5582E /* Aliases.swift */; }; + 7B1D271DF28EFC73BEF9FA2D5C27A0B8 /* RLMCollection.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = BB00326D562DD60AC0D4F1E1BDA599D7 /* RLMCollection.h */; }; + 7C2DD02FB23E320F4BD001CE5E8FAE68 /* RLMOptionalBase.h in Headers */ = {isa = PBXBuildFile; fileRef = C992B27EB9C3280ECEE250E8812AD166 /* RLMOptionalBase.h */; }; + 7CF963FD4253EA48A6DD699B40EF0EEA /* RLMRealm_Dynamic.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = F57956B8D2A770EBED0BFF7F85B9D29F /* RLMRealm_Dynamic.h */; }; + 7D5C974E9775B7CC7E2A3BC644EF0B54 /* Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C39CCAB7851760C0BDEBE5CE9A5960A /* Migration.swift */; }; + 81E99760E1FEF42B2A90BF10F1071609 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06236DB56685E84315B8657E2B46CCFD /* Optional.swift */; }; + 8533A869F364D653A51ACBED102D4CD1 /* Realm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B396D35C7CD4FBEC47D31EE54A4E324 /* Realm.swift */; }; + 863061D5A181C2E36DD017FD7B6A2962 /* RLMConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = F034ED9BDB35D258599BABBB34D1CBA6 /* RLMConstants.h */; }; + 885585F019357D659C6615ECEF5EEF87 /* RLMObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E20A4F837A27723BBF28AD7DE233AD5 /* RLMObject.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 8CB9BFB7AC42857B58D9A96114C56EF5 /* Results.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ADB04329F626A89B9A10FA0908E6961 /* Results.swift */; }; + 8EA127C34BB787BFB823383FA051E6E5 /* weak_realm_notifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF4905F966A1014FE706940F3523AE8 /* weak_realm_notifier.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 90A61FACBF66C8AEDFECBD8E452C6664 /* RLMProperty.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6C4A0DAB2ED319738210B91AED8CBF6 /* RLMProperty.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 916613D903B90822AEC6D08992FE1BE3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */; }; + 91E760FFDCCA6D56578DE27EFAE778C5 /* handover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A09C890040CEBAB8CA57C11861FCF71 /* handover.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 9250C32107F8179F81513C35EFBEAAFA /* RLMRealm.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7E3BFDBE836C79F27A3AC600D8A46F /* RLMRealm.h */; }; + 93E6469A8EE3566AACF849928F06A137 /* shared_realm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BDE13C3BAE16C02F1F35157AADDCD0B /* shared_realm.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 959B5561711B66B48EAA9FF3AB9DCB98 /* RLMRealm_Dynamic.h in Headers */ = {isa = PBXBuildFile; fileRef = F57956B8D2A770EBED0BFF7F85B9D29F /* RLMRealm_Dynamic.h */; }; + 97A9A1EA6B0956C42524A2FC0F0C7F0A /* schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD25AF1E3E42EA405AC6776DE9FB8EC5 /* schema.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + 9B4CF4789C9C60653D5BA59953464A9D /* RLMObjectStore.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 6EDF0B3EDC8560C1EB73D58225CBF327 /* RLMObjectStore.h */; }; + 9C54B03F15F6F4F9C3F0A42C60BCC705 /* RLMProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = A0C6A1ACDD47C654A89E0E1853933B52 /* RLMProperty.h */; }; + 9EE4E578F709A1B41454E3008D08062A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */; }; + A840C6C2E8A3B6A5B4768852307FE256 /* RLMPredicateUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = 560E4B5FE192BC60E773FA5A35629991 /* RLMPredicateUtil.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + A8A1ECA0B91515C0B5E1ACAD95906BCC /* RLMObjectBase_Dynamic.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = AD8FDA9F9D69AA41E037199C5E1C9123 /* RLMObjectBase_Dynamic.h */; }; + AA36C7D6BA0E8A5AAC7A69C6AFF82AAC /* thread_confined.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00F5598161EF126F7DA69A64C5DB714B /* thread_confined.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + ABE2ACCAC3F1C043AEA19476C2045C78 /* results_notifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A34F3725F39D96A0A12E82AFE3C05EE9 /* results_notifier.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + AC7EB4178CD3C18C128C4B03C1C6F498 /* RLMProperty_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 58611CC7789C0314F5F25E105472E232 /* RLMProperty_Private.h */; }; + ACFB67331C772F990B5AE2F85CF39C46 /* RLMRealmConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EE575F7032F45A150314BEBB0DB9423 /* RLMRealmConfiguration.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + AE70367ACC6ECEAAD093D279CB5D2983 /* RLMRealm.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8D753BFF2BCED0FE7BD675D102FBAFEE /* RLMRealm.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + AF281E48CF94DA6A3F1DBA53CBEB9527 /* format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA376102351A08E7F18573CD736D1E9A /* format.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + AFD5AE9BBA7C00419A380F2158B9751E /* realm_coordinator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9921372EF33E6D7116B4909079F5ADB /* realm_coordinator.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + B3B2C90E174C903EE92B71536DC711F7 /* collection_notifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5BD1CC0F3FDC0CBA26A763EEC9AFA56 /* collection_notifier.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + B4D568BA269A4AF0B209DC22E3DB2A80 /* RealmSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 675CB81A7674FCF89BAD9507F320C809 /* RealmSwift-dummy.m */; }; + B9044FF42638E18A0A24FBE292E28D55 /* RLMObjectSchema.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6652EEFE99D613E4AF38C696067C2AC /* RLMObjectSchema.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + BAE8E772CFD4454E2F4C215134A29204 /* RLMObjectSchema.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 7D100467E73BD5628A5FFC41F9006414 /* RLMObjectSchema.h */; }; + BAFDED2060875CF9EB61BC477D8153DD /* RLMMigration.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = B83556211BB55DFE4316B39D0B159D9D /* RLMMigration.h */; }; + C3EACD06F7212B238841CF5614DB3473 /* RLMArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 1990F65EE5CD3970B95801EC893F7023 /* RLMArray.h */; }; + C44EE1C50FF5FD5C40F0A0EC768B371B /* RLMRealmConfiguration_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F06BCF01D58FE275D42F53050091054 /* RLMRealmConfiguration_Private.h */; }; + C82A1A97B02A8D602FE2AE99BB2D770B /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BE2D6D05D2CE3CC0CAB124EAEE4C035 /* Util.swift */; }; + C8D843767B4F1F3CB92F22979B29E5BD /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F28CD9831D16F69ABB47B6B295C10B /* Schema.swift */; }; + C9960A2F0A0647FB6BA1B3F663C69382 /* RLMArray_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 07255E0F2C2E324D44ED065E23A4DC2E /* RLMArray_Private.h */; }; + CA06A76082FFE8DF61AC494AE852491B /* RLMUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = D44AD908506416B6744871CFA76E654F /* RLMUtil.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + CB08008ACA70DF3A43EEC4D289BEBCAC /* list_notifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F16649EDD1D2882F50A2507B4A88FE7C /* list_notifier.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + CC9329E881E95B1D23A741DE88FC01C7 /* RLMMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = B83556211BB55DFE4316B39D0B159D9D /* RLMMigration.h */; }; + D0CF501CE77B53CA611447744C8DDE8F /* RLMResults.h in Headers */ = {isa = PBXBuildFile; fileRef = D095A3DC68EAD70B6FA15C99B9C2570A /* RLMResults.h */; }; + D24F03001F0FA95829EB6297DD65BB75 /* RLMSchema_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF799FF812780838210DEAD1119568C /* RLMSchema_Private.h */; }; + D33C4C4C1C997289B96BCA8167197F30 /* RLMResults_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = B85217406965A6F439FF8370D33C4D13 /* RLMResults_Private.h */; }; + D34068AB912D83AFF35BDE1D7AE87232 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */; }; + D5E0E7FF0FF8AE0478D886F1C9E23849 /* RLMRealm_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AF403B7F9A24F4B457AE9923E5D8876 /* RLMRealm_Private.h */; }; + D6056083A3229AFFF957640D94CB9D09 /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F283594676B2A4DF6D33A154EA8901F /* list.cpp */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + D6DB0CCB00D1420E3A1D393547728493 /* RLMListBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5A233AD6FCDACD9E070CFB9D4958F2 /* RLMListBase.h */; }; + D75B68CE087E46226C56C3813E715C7D /* RLMObjectStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69C168B67B003ACA3755866ED84764F2 /* RLMObjectStore.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + D939AAD994955D51041493A94DA45CFC /* RLMObjectSchema_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5649F569F9DF6A08A2C9A142D69D824F /* RLMObjectSchema_Private.h */; }; + D9AD60825CA18A144B8B20C40A892365 /* RLMSwiftSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DC28458A462E8A1A244E8208B7E5B82 /* RLMSwiftSupport.m */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + D9C927E5079FA87D6631BAEB0492296C /* RLMOptionalBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC8307D2954C2C37FAAC9DA6208AF912 /* RLMOptionalBase.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + E0C012856B2E74E70ECC9C30EF67050D /* RLMRealmConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 866724B2FEEAE5E537FB6AF285FCC55E /* RLMRealmConfiguration.h */; }; + E12D0F8EF2EBFA2D24AFC37D8CD8D838 /* RLMSchema_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = CDF799FF812780838210DEAD1119568C /* RLMSchema_Private.h */; }; + E3B2C64329FBFE0A30FED106D15A0B48 /* RLMObjectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 63A5177E90000F5EB6C5C76970347FC5 /* RLMObjectBase.h */; }; + E60C143D63355A395511926A2F2945F1 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4BA7AF7EB7470B9973A1405CBD337CD /* Error.swift */; }; + E76A289CC3703948E7DEFCF69DCA4AE3 /* RLMConstants.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = F034ED9BDB35D258599BABBB34D1CBA6 /* RLMConstants.h */; }; + EB0E17A2FEB537984FAE64988A56FF73 /* RLMOptionalBase.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = C992B27EB9C3280ECEE250E8812AD166 /* RLMOptionalBase.h */; }; + EFFFDBB58CF6F75068D15192A57FE8E6 /* RLMConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = FD7F1E2026AB909E63867F538CBBAEE2 /* RLMConstants.m */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + F427953007993486CB51D65C7D4FA968 /* RLMObservation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 596E2A5D0C96EB0494F989B63836AFBE /* RLMObservation.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + F53D16512092DEF1D8FCCD8B85E667DB /* RLMRealm_Private.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = 9AF403B7F9A24F4B457AE9923E5D8876 /* RLMRealm_Private.h */; }; + FA4F3DCAEB3EEC17200E1BCF6E20C9AE /* RLMRealm.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = 3B7E3BFDBE836C79F27A3AC600D8A46F /* RLMRealm.h */; }; + FB32D05E369BE7778920B061884E1390 /* RLMProperty.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = A0C6A1ACDD47C654A89E0E1853933B52 /* RLMProperty.h */; }; + FEB9A8A037D395C201C26BC17D6CD0CA /* RLMAccessor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18E6CD119975D929D6B08391B135F8CE /* RLMAccessor.mm */; settings = {COMPILER_FLAGS = "-DREALM_HAVE_CONFIG -DREALM_COCOA_VERSION='@\"1.1.0\"' -D__ASSERTMACROS__"; }; }; + FECA4B3C31292B37322CD9A28D9869E3 /* RLMOptionalBase.h in Copy . Private Headers */ = {isa = PBXBuildFile; fileRef = C992B27EB9C3280ECEE250E8812AD166 /* RLMOptionalBase.h */; }; + FEF4AC5A92B1822CD91FD7FEF0C582DD /* SortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAD97370CADCAD821DFB54939F2EB99 /* SortDescriptor.swift */; }; + FFDC901065954E36107E8FBDA682D8CC /* RLMObject.h in Copy . Public Headers */ = {isa = PBXBuildFile; fileRef = FF3374CF1BA7A1E0981140D0622EEAAC /* RLMObject.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 253455C5D5692DD8F71CE509A88AE94D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C3DC8BA47CF0F184F7CB7AE68C1C2B78; + remoteInfo = RealmSwift; + }; + 2FC044AAD67BD26F03CC9E8489FB65A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = A4FB3931703F06F42536B70DA618087C; + remoteInfo = Realm; + }; + 53C1F1E69BCE212732B5E8C72B0EF408 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C3DC8BA47CF0F184F7CB7AE68C1C2B78; + remoteInfo = RealmSwift; + }; + 9A99346228A5C7D5DF776A3926A43AC1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = A4FB3931703F06F42536B70DA618087C; + remoteInfo = Realm; + }; + AB13B76E2D71F39D47864CA32E55458C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C3DC8BA47CF0F184F7CB7AE68C1C2B78; + remoteInfo = RealmSwift; + }; + BC21C510B6840A068A3612A30808BBA4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = A4FB3931703F06F42536B70DA618087C; + remoteInfo = Realm; + }; + F52A65D75E877738433341638FC83333 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = A4FB3931703F06F42536B70DA618087C; + remoteInfo = Realm; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 5C764F6E56B2D9B9F3E838AFC0FEDB9E /* Copy . Private Headers */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(PRIVATE_HEADERS_FOLDER_PATH)/."; + dstSubfolderSpec = 16; + files = ( + 64724617867E866EBDB3BBDCB74DEA8A /* RLMAccessor.h in Copy . Private Headers */, + C9960A2F0A0647FB6BA1B3F663C69382 /* RLMArray_Private.h in Copy . Private Headers */, + 5D72D32649B32EE66BBC2DEB6750B016 /* RLMListBase.h in Copy . Private Headers */, + 4D649D6A1A75EF8570BEBB6EE11EECB1 /* RLMMigration_Private.h in Copy . Private Headers */, + 170370A76F95C2C3C13FB9F6FC62008A /* RLMObject_Private.h in Copy . Private Headers */, + 15320D1811842F9FEA775373C9BD0033 /* RLMObjectSchema_Private.h in Copy . Private Headers */, + 9B4CF4789C9C60653D5BA59953464A9D /* RLMObjectStore.h in Copy . Private Headers */, + FECA4B3C31292B37322CD9A28D9869E3 /* RLMOptionalBase.h in Copy . Private Headers */, + 386EBD553B521BCA407355DB39C50A4C /* RLMProperty_Private.h in Copy . Private Headers */, + F53D16512092DEF1D8FCCD8B85E667DB /* RLMRealm_Private.h in Copy . Private Headers */, + 6AFC52FA3D9F3A68377A304590151CA1 /* RLMRealmConfiguration_Private.h in Copy . Private Headers */, + D33C4C4C1C997289B96BCA8167197F30 /* RLMResults_Private.h in Copy . Private Headers */, + E12D0F8EF2EBFA2D24AFC37D8CD8D838 /* RLMSchema_Private.h in Copy . Private Headers */, + ); + name = "Copy . Private Headers"; + runOnlyForDeploymentPostprocessing = 0; + }; + A3A99CC8123F708E68CB6D49E7B61476 /* Copy . Public Headers */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(PUBLIC_HEADERS_FOLDER_PATH)/."; + dstSubfolderSpec = 16; + files = ( + 28A6A562B690B7B1A77DD15AAA54308C /* Realm.h in Copy . Public Headers */, + 730ADA732D8A76E1A376ABDA73511194 /* RLMArray.h in Copy . Public Headers */, + 7B1D271DF28EFC73BEF9FA2D5C27A0B8 /* RLMCollection.h in Copy . Public Headers */, + E76A289CC3703948E7DEFCF69DCA4AE3 /* RLMConstants.h in Copy . Public Headers */, + 57112DB3C1568FF688E4A7645B650ED7 /* RLMListBase.h in Copy . Public Headers */, + BAFDED2060875CF9EB61BC477D8153DD /* RLMMigration.h in Copy . Public Headers */, + FFDC901065954E36107E8FBDA682D8CC /* RLMObject.h in Copy . Public Headers */, + 2ABE2EE6F824F681E8C185C250064753 /* RLMObjectBase.h in Copy . Public Headers */, + A8A1ECA0B91515C0B5E1ACAD95906BCC /* RLMObjectBase_Dynamic.h in Copy . Public Headers */, + BAE8E772CFD4454E2F4C215134A29204 /* RLMObjectSchema.h in Copy . Public Headers */, + EB0E17A2FEB537984FAE64988A56FF73 /* RLMOptionalBase.h in Copy . Public Headers */, + 1E4C1B93DD3FA97246C75956C353C218 /* RLMPlatform.h in Copy . Public Headers */, + FB32D05E369BE7778920B061884E1390 /* RLMProperty.h in Copy . Public Headers */, + FA4F3DCAEB3EEC17200E1BCF6E20C9AE /* RLMRealm.h in Copy . Public Headers */, + 7CF963FD4253EA48A6DD699B40EF0EEA /* RLMRealm_Dynamic.h in Copy . Public Headers */, + 3C4AC116155C1A9D10970370C068F1CC /* RLMRealmConfiguration.h in Copy . Public Headers */, + 24881ECA02B40B7ABFD4F7799A668E9F /* RLMResults.h in Copy . Public Headers */, + 69513F2307371DEEDA34CA955F53D1B8 /* RLMSchema.h in Copy . Public Headers */, + ); + name = "Copy . Public Headers"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 00F5598161EF126F7DA69A64C5DB714B /* thread_confined.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = thread_confined.cpp; path = Realm/ObjectStore/src/thread_confined.cpp; sourceTree = ""; }; + 0479CCE8A914E5585FDE2514545FAC8E /* RLMSchema.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMSchema.mm; path = Realm/RLMSchema.mm; sourceTree = ""; }; + 05F1E405B6EE64A4266CF425DD80288A /* RLMCollection.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMCollection.mm; path = Realm/RLMCollection.mm; sourceTree = ""; }; + 06236DB56685E84315B8657E2B46CCFD /* Optional.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Optional.swift; path = RealmSwift/Optional.swift; sourceTree = ""; }; + 07255E0F2C2E324D44ED065E23A4DC2E /* RLMArray_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMArray_Private.h; path = include/RLMArray_Private.h; sourceTree = ""; }; + 08E18F888ED89072D2E3FF4EFCD7F518 /* Pods-Abstract-SiriKitExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Abstract-SiriKitExample-dummy.m"; sourceTree = ""; }; + 08F9E161B6AAB03BF52DA8807936A222 /* ObjectSchema.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObjectSchema.swift; path = RealmSwift/ObjectSchema.swift; sourceTree = ""; }; + 09B6B5D85E4A1957F3684E24623A8D62 /* Realm-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Realm-prefix.pch"; sourceTree = ""; }; + 0AF8951163295E8B49F8C9BCFA16DED8 /* collection_notifications.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = collection_notifications.cpp; path = Realm/ObjectStore/src/collection_notifications.cpp; sourceTree = ""; }; + 0D2DDEF3DA55C4F5335E491E2DB6008B /* RLMObjectBase.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMObjectBase.mm; path = Realm/RLMObjectBase.mm; sourceTree = ""; }; + 143DC32879715A3E635833619C5C546A /* Realm-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Realm-dummy.m"; sourceTree = ""; }; + 1554787024CBFC6C93F615BF7FEBA98C /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 165B902CFE265EB6898DF8F3E3F66F3E /* Pods-Abstract-SiriKitExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Abstract-SiriKitExample-umbrella.h"; sourceTree = ""; }; + 18E6CD119975D929D6B08391B135F8CE /* RLMAccessor.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMAccessor.mm; path = Realm/RLMAccessor.mm; sourceTree = ""; }; + 18EA54D7EBE3C26A6C4D83BD81B8E66B /* Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap"; sourceTree = ""; }; + 18F28CD9831D16F69ABB47B6B295C10B /* Schema.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Schema.swift; path = RealmSwift/Schema.swift; sourceTree = ""; }; + 1909B62FDD4B8F52E6A10315D4D0E3A1 /* Pods-Abstract-SiriKitExampleSiriIntent-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Abstract-SiriKitExampleSiriIntent-dummy.m"; sourceTree = ""; }; + 198A65BDE5F32B4ACAB8478993490991 /* external_commit_helper.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = external_commit_helper.cpp; path = Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp; sourceTree = ""; }; + 1990F65EE5CD3970B95801EC893F7023 /* RLMArray.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMArray.h; path = include/RLMArray.h; sourceTree = ""; }; + 1A6DE5974160987A403ED465DB108BDF /* RLMRealmUtil.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMRealmUtil.mm; path = Realm/RLMRealmUtil.mm; sourceTree = ""; }; + 1BE2D6D05D2CE3CC0CAB124EAEE4C035 /* Util.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Util.swift; path = RealmSwift/Util.swift; sourceTree = ""; }; + 1DC0E56F7C895F089F4FD6E6FFBAE1D8 /* Pods-Abstract-SiriKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExample.release.xcconfig"; sourceTree = ""; }; + 20891FE169B19C05FFD135AD934C7631 /* Pods-Abstract-SiriKitExampleSiriIntent.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExampleSiriIntent.release.xcconfig"; sourceTree = ""; }; + 21094FAC31FEBEACBFC2F9DBE288F387 /* RealmCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RealmCollection.swift; path = RealmSwift/RealmCollection.swift; sourceTree = ""; }; + 21F94D6E9EF8950D73AF9F144678B66A /* Pods-Abstract-SiriKitExampleSiriIntentUI-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-frameworks.sh"; sourceTree = ""; }; + 2293BF38FC39F30DBCB7C7969F325C55 /* Realm.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Realm.modulemap; sourceTree = ""; }; + 22B3A9988AC2D49D500963159791BAB0 /* RLMArrayLinkView.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMArrayLinkView.mm; path = Realm/RLMArrayLinkView.mm; sourceTree = ""; }; + 239892C060F34039563F1E3FEB181204 /* Pods-Abstract-SiriKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExample.debug.xcconfig"; sourceTree = ""; }; + 2529FD63B39AD3AC3E46684AE4528109 /* RLMListBase.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMListBase.mm; path = Realm/RLMListBase.mm; sourceTree = ""; }; + 2C39CCAB7851760C0BDEBE5CE9A5960A /* Migration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Migration.swift; path = RealmSwift/Migration.swift; sourceTree = ""; }; + 2DC28458A462E8A1A244E8208B7E5B82 /* RLMSwiftSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RLMSwiftSupport.m; path = Realm/RLMSwiftSupport.m; sourceTree = ""; }; + 3056258FD0C38D6DCC75B798FA2ABDAC /* Realm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Realm.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 30FBE4A3F8EDEEC5DB82FF979368C837 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 31B0BBCB19A28A16EFB1F585DD5699C0 /* RLMMigration.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMMigration.mm; path = Realm/RLMMigration.mm; sourceTree = ""; }; + 332F5378A49B198028E7C26D3F1B089E /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 362AE13FB374BD686F5F7F04A351BBDF /* Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.plist"; sourceTree = ""; }; + 366F3B848DF7588701BBDCE39BBC072A /* RLMArray.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMArray.mm; path = Realm/RLMArray.mm; sourceTree = ""; }; + 3B7E3BFDBE836C79F27A3AC600D8A46F /* RLMRealm.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMRealm.h; path = include/RLMRealm.h; sourceTree = ""; }; + 3BAD97370CADCAD821DFB54939F2EB99 /* SortDescriptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SortDescriptor.swift; path = RealmSwift/SortDescriptor.swift; sourceTree = ""; }; + 3EE575F7032F45A150314BEBB0DB9423 /* RLMRealmConfiguration.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMRealmConfiguration.mm; path = Realm/RLMRealmConfiguration.mm; sourceTree = ""; }; + 3F283594676B2A4DF6D33A154EA8901F /* list.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = list.cpp; path = Realm/ObjectStore/src/list.cpp; sourceTree = ""; }; + 3F7106D0E5AE0F14B74A9302575B427C /* RealmSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = RealmSwift.modulemap; sourceTree = ""; }; + 4008BCBE7C5C87F38E54502626171CBB /* Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m"; sourceTree = ""; }; + 436ABD7A1A7F658B25967AD37A2AFCA6 /* RLMAnalytics.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMAnalytics.mm; path = Realm/RLMAnalytics.mm; sourceTree = ""; }; + 47DB5419A1875CDABB71BE330FDC2CDB /* Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h"; sourceTree = ""; }; + 49EE2F5DA1E1A1E29B94A21CF861C587 /* placeholder.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = placeholder.cpp; path = Realm/ObjectStore/src/placeholder.cpp; sourceTree = ""; }; + 55108D804B83B5199434A09ED9B306D0 /* results.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = results.cpp; path = Realm/ObjectStore/src/results.cpp; sourceTree = ""; }; + 5590FE1B6ACFE1AAE6F2B3E5587D853E /* collection_change_builder.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = collection_change_builder.cpp; path = Realm/ObjectStore/src/impl/collection_change_builder.cpp; sourceTree = ""; }; + 560E4B5FE192BC60E773FA5A35629991 /* RLMPredicateUtil.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMPredicateUtil.mm; path = Realm/RLMPredicateUtil.mm; sourceTree = ""; }; + 5649F569F9DF6A08A2C9A142D69D824F /* RLMObjectSchema_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObjectSchema_Private.h; path = include/RLMObjectSchema_Private.h; sourceTree = ""; }; + 58611CC7789C0314F5F25E105472E232 /* RLMProperty_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMProperty_Private.h; path = include/RLMProperty_Private.h; sourceTree = ""; }; + 596E2A5D0C96EB0494F989B63836AFBE /* RLMObservation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMObservation.mm; path = Realm/RLMObservation.mm; sourceTree = ""; }; + 5FA006FD3A891D003641A11C01197141 /* Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.markdown"; sourceTree = ""; }; + 621975F8E2D07283D4AFE111B207491C /* RLMSchema.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMSchema.h; path = include/RLMSchema.h; sourceTree = ""; }; + 62C842D884BC347551EF8709C2EFDDCF /* librealm-ios.a */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = archive.ar; name = "librealm-ios.a"; path = "core/librealm-ios.a"; sourceTree = ""; }; + 63A5177E90000F5EB6C5C76970347FC5 /* RLMObjectBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObjectBase.h; path = include/RLMObjectBase.h; sourceTree = ""; }; + 67156F56A6251C094C18417C5E9CAF1C /* RLMMigration_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMMigration_Private.h; path = include/RLMMigration_Private.h; sourceTree = ""; }; + 675CB81A7674FCF89BAD9507F320C809 /* RealmSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RealmSwift-dummy.m"; sourceTree = ""; }; + 68A2015E6F694DEA25FEB75071DBD64F /* Pods-Abstract-SiriKitExample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExample-frameworks.sh"; sourceTree = ""; }; + 69C168B67B003ACA3755866ED84764F2 /* RLMObjectStore.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMObjectStore.mm; path = Realm/RLMObjectStore.mm; sourceTree = ""; }; + 6B179AE470981EC3AA10725491B2C442 /* Property.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Property.swift; path = RealmSwift/Property.swift; sourceTree = ""; }; + 6B396D35C7CD4FBEC47D31EE54A4E324 /* Realm.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Realm.swift; path = RealmSwift/Realm.swift; sourceTree = ""; }; + 6EDF0B3EDC8560C1EB73D58225CBF327 /* RLMObjectStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObjectStore.h; path = include/RLMObjectStore.h; sourceTree = ""; }; + 6F5C9A1BFE4964D63F58EFDAF8603762 /* LinkingObjects.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinkingObjects.swift; path = RealmSwift/LinkingObjects.swift; sourceTree = ""; }; + 70CA05FDBC8B43930550B71713D5582E /* Aliases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Aliases.swift; path = RealmSwift/Aliases.swift; sourceTree = ""; }; + 71693E07A9D0CF55C892C9C1EC92734F /* Pods-Abstract-SiriKitExampleSiriIntentUI.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExampleSiriIntentUI.release.xcconfig"; sourceTree = ""; }; + 7376E1F339A57AF4727A681119324C1F /* Pods-Abstract-SiriKitExampleSiriIntent.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Abstract-SiriKitExampleSiriIntent.modulemap"; sourceTree = ""; }; + 7532539A224F0219EA76B5F5FBCFB0D1 /* List.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = List.swift; path = RealmSwift/List.swift; sourceTree = ""; }; + 7614A7CB5DF19A0C82189B7E57CF145F /* Pods-Abstract-SiriKitExampleSiriIntent-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExampleSiriIntent-resources.sh"; sourceTree = ""; }; + 768105B6775C605838B8F18ADB5965FF /* Pods-Abstract-SiriKitExampleSiriIntent-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExampleSiriIntent-frameworks.sh"; sourceTree = ""; }; + 796154D364E38B24B9890EA21530520D /* RLMResults.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMResults.mm; path = Realm/RLMResults.mm; sourceTree = ""; }; + 7972404FF3C4260EB6A2F72B20C9C8FD /* index_set.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = index_set.cpp; path = Realm/ObjectStore/src/index_set.cpp; sourceTree = ""; }; + 7A09C890040CEBAB8CA57C11861FCF71 /* handover.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = handover.cpp; path = Realm/ObjectStore/src/impl/handover.cpp; sourceTree = ""; }; + 7BBD03FD046CB803E10C3D75763EAEDE /* Pods-Abstract-SiriKitExampleSiriIntentUI.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExampleSiriIntentUI.debug.xcconfig"; sourceTree = ""; }; + 7BDE13C3BAE16C02F1F35157AADDCD0B /* shared_realm.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = shared_realm.cpp; path = Realm/ObjectStore/src/shared_realm.cpp; sourceTree = ""; }; + 7CDFC95ED00B61813F46C15AAA1F2E0E /* RealmSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RealmSwift-prefix.pch"; sourceTree = ""; }; + 7D100467E73BD5628A5FFC41F9006414 /* RLMObjectSchema.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObjectSchema.h; path = include/RLMObjectSchema.h; sourceTree = ""; }; + 7D6341910B1DD7573783B5AE75F972C9 /* Realm.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Realm.xcconfig; sourceTree = ""; }; + 7F06BCF01D58FE275D42F53050091054 /* RLMRealmConfiguration_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMRealmConfiguration_Private.h; path = include/RLMRealmConfiguration_Private.h; sourceTree = ""; }; + 7F7F8AF36B00C7B7206B10B9BBFCC872 /* transact_log_handler.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = transact_log_handler.cpp; path = Realm/ObjectStore/src/impl/transact_log_handler.cpp; sourceTree = ""; }; + 7FBCD7C30E985A21C901AFD03BABA96C /* Realm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Realm.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 866724B2FEEAE5E537FB6AF285FCC55E /* RLMRealmConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMRealmConfiguration.h; path = include/RLMRealmConfiguration.h; sourceTree = ""; }; + 8ADB04329F626A89B9A10FA0908E6961 /* Results.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Results.swift; path = RealmSwift/Results.swift; sourceTree = ""; }; + 8CA3D3AD90FBD2CD96C21AE42C08142E /* Pods_Abstract_SiriKitExampleSiriIntentUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_SiriKitExampleSiriIntentUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D3B92480CF1FA9CEFDCF9E1CBEC7041 /* Pods-Abstract-SiriKitExampleSiriIntent.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Abstract-SiriKitExampleSiriIntent.debug.xcconfig"; sourceTree = ""; }; + 8D753BFF2BCED0FE7BD675D102FBAFEE /* RLMRealm.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMRealm.mm; path = Realm/RLMRealm.mm; sourceTree = ""; }; + 8E20A4F837A27723BBF28AD7DE233AD5 /* RLMObject.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMObject.mm; path = Realm/RLMObject.mm; sourceTree = ""; }; + 8F31EA1001BDDC58A09B8FD12F361B0D /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 90C7D93637C4F5BFDCCC2F9A2B9B9286 /* RLMPlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMPlatform.h; path = include/RLMPlatform.h; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 93A8F1885767083219133992B4349562 /* Pods_Abstract_SiriKitExampleSiriIntent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_SiriKitExampleSiriIntent.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 98F80099DEF4E44E8F77F4971C2195E5 /* object_schema.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = object_schema.cpp; path = Realm/ObjectStore/src/object_schema.cpp; sourceTree = ""; }; + 9AF403B7F9A24F4B457AE9923E5D8876 /* RLMRealm_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMRealm_Private.h; path = include/RLMRealm_Private.h; sourceTree = ""; }; + 9BADDE90620AC871ADC94A08D389C458 /* RLMUpdateChecker.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMUpdateChecker.mm; path = Realm/RLMUpdateChecker.mm; sourceTree = ""; }; + A0C6A1ACDD47C654A89E0E1853933B52 /* RLMProperty.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMProperty.h; path = include/RLMProperty.h; sourceTree = ""; }; + A160C124D3797D418F557BC77D76FA8C /* Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h"; sourceTree = ""; }; + A1D50ABD8B5F4727C844FAEB7141E8B0 /* Realm.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Realm.h; path = include/Realm.h; sourceTree = ""; }; + A34F3725F39D96A0A12E82AFE3C05EE9 /* results_notifier.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = results_notifier.cpp; path = Realm/ObjectStore/src/impl/results_notifier.cpp; sourceTree = ""; }; + A5BD1CC0F3FDC0CBA26A763EEC9AFA56 /* collection_notifier.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = collection_notifier.cpp; path = Realm/ObjectStore/src/impl/collection_notifier.cpp; sourceTree = ""; }; + A7E8A3F2985B387478071F560C1ED4DD /* Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.markdown"; sourceTree = ""; }; + AD8FDA9F9D69AA41E037199C5E1C9123 /* RLMObjectBase_Dynamic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObjectBase_Dynamic.h; path = include/RLMObjectBase_Dynamic.h; sourceTree = ""; }; + B6C4A0DAB2ED319738210B91AED8CBF6 /* RLMProperty.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMProperty.mm; path = Realm/RLMProperty.mm; sourceTree = ""; }; + B7C9195E39B50F15B65918F41965369D /* RLMQueryUtil.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMQueryUtil.mm; path = Realm/RLMQueryUtil.mm; sourceTree = ""; }; + B83556211BB55DFE4316B39D0B159D9D /* RLMMigration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMMigration.h; path = include/RLMMigration.h; sourceTree = ""; }; + B85217406965A6F439FF8370D33C4D13 /* RLMResults_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMResults_Private.h; path = include/RLMResults_Private.h; sourceTree = ""; }; + B9E860CC888D6662669EE9098252D355 /* Object.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Object.swift; path = RealmSwift/Object.swift; sourceTree = ""; }; + BB00326D562DD60AC0D4F1E1BDA599D7 /* RLMCollection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMCollection.h; path = include/RLMCollection.h; sourceTree = ""; }; + BC514B857F8B9E392EB3652FFFD4CA1D /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BC8307D2954C2C37FAAC9DA6208AF912 /* RLMOptionalBase.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMOptionalBase.mm; path = Realm/RLMOptionalBase.mm; sourceTree = ""; }; + C44E32CBCA86DBF2F268050E9BB1C264 /* RLMClassInfo.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMClassInfo.mm; path = Realm/RLMClassInfo.mm; sourceTree = ""; }; + C5DCC8BF3630AF6D49DD2B88CD6E2BF8 /* object_store.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = object_store.cpp; path = Realm/ObjectStore/src/object_store.cpp; sourceTree = ""; }; + C6652EEFE99D613E4AF38C696067C2AC /* RLMObjectSchema.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMObjectSchema.mm; path = Realm/RLMObjectSchema.mm; sourceTree = ""; }; + C7B921A9DD00D6B67CFFB0F717105B93 /* Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.plist"; sourceTree = ""; }; + C9921372EF33E6D7116B4909079F5ADB /* realm_coordinator.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = realm_coordinator.cpp; path = Realm/ObjectStore/src/impl/realm_coordinator.cpp; sourceTree = ""; }; + C992B27EB9C3280ECEE250E8812AD166 /* RLMOptionalBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMOptionalBase.h; path = include/RLMOptionalBase.h; sourceTree = ""; }; + CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + CDBBCF0F9CA76ABE166B0D0CC8F063C8 /* Pods_Abstract_SiriKitExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Abstract_SiriKitExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CDF799FF812780838210DEAD1119568C /* RLMSchema_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMSchema_Private.h; path = include/RLMSchema_Private.h; sourceTree = ""; }; + CE5A233AD6FCDACD9E070CFB9D4958F2 /* RLMListBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMListBase.h; path = include/RLMListBase.h; sourceTree = ""; }; + CFFE0D23E969576A357BF2632E504749 /* RLMObject_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObject_Private.h; path = include/RLMObject_Private.h; sourceTree = ""; }; + D06A6D9B303FABCD01A1767B5A38E455 /* Pods-Abstract-SiriKitExample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExample-resources.sh"; sourceTree = ""; }; + D095A3DC68EAD70B6FA15C99B9C2570A /* RLMResults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMResults.h; path = include/RLMResults.h; sourceTree = ""; }; + D44AD908506416B6744871CFA76E654F /* RLMUtil.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = RLMUtil.mm; path = Realm/RLMUtil.mm; sourceTree = ""; }; + D75B1B8751A4AA764288FF4C735A2E33 /* SwiftVersion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftVersion.swift; path = RealmSwift/SwiftVersion.swift; sourceTree = ""; }; + DA376102351A08E7F18573CD736D1E9A /* format.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = format.cpp; path = Realm/ObjectStore/src/util/format.cpp; sourceTree = ""; }; + E4C718547F82C2630627885D567E0C11 /* RealmSwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RealmSwift.xcconfig; sourceTree = ""; }; + E505CD49FA65F825EF990621961240DB /* Pods-Abstract-SiriKitExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Abstract-SiriKitExample-acknowledgements.plist"; sourceTree = ""; }; + E523BF9B67952F3971734F9317759B48 /* RLMAccessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMAccessor.h; path = include/RLMAccessor.h; sourceTree = ""; }; + E5A4B64719F67BDC7135EA4CC951A3B2 /* Pods-Abstract-SiriKitExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Abstract-SiriKitExample.modulemap"; sourceTree = ""; }; + EBF4905F966A1014FE706940F3523AE8 /* weak_realm_notifier.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = weak_realm_notifier.cpp; path = Realm/ObjectStore/src/impl/weak_realm_notifier.cpp; sourceTree = ""; }; + EE6E60EE3BFD57496D37C387D5D9286F /* Pods-Abstract-SiriKitExampleSiriIntentUI-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Abstract-SiriKitExampleSiriIntentUI-resources.sh"; sourceTree = ""; }; + EEF7197CDB194B4337C9C9B6B25C2CDE /* RealmSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RealmSwift-umbrella.h"; sourceTree = ""; }; + F034ED9BDB35D258599BABBB34D1CBA6 /* RLMConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMConstants.h; path = include/RLMConstants.h; sourceTree = ""; }; + F16649EDD1D2882F50A2507B4A88FE7C /* list_notifier.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = list_notifier.cpp; path = Realm/ObjectStore/src/impl/list_notifier.cpp; sourceTree = ""; }; + F287A91BE127F2A2441F1834D7537E23 /* RealmConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RealmConfiguration.swift; path = RealmSwift/RealmConfiguration.swift; sourceTree = ""; }; + F4BA7AF7EB7470B9973A1405CBD337CD /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = RealmSwift/Error.swift; sourceTree = ""; }; + F57956B8D2A770EBED0BFF7F85B9D29F /* RLMRealm_Dynamic.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMRealm_Dynamic.h; path = include/RLMRealm_Dynamic.h; sourceTree = ""; }; + FCECE08D570F5585268B579F58A7578E /* RealmSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RealmSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FD25AF1E3E42EA405AC6776DE9FB8EC5 /* schema.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = schema.cpp; path = Realm/ObjectStore/src/schema.cpp; sourceTree = ""; }; + FD7F1E2026AB909E63867F538CBBAEE2 /* RLMConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RLMConstants.m; path = Realm/RLMConstants.m; sourceTree = ""; }; + FF3374CF1BA7A1E0981140D0622EEAAC /* RLMObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RLMObject.h; path = include/RLMObject.h; sourceTree = ""; }; + FF48BCC24DBDA415D13C4C752A0A6C51 /* Pods-Abstract-SiriKitExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Abstract-SiriKitExample-acknowledgements.markdown"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 881C57FCEBCCF30E6ED967E837A07997 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 588F364D3C237788E4D9A3353E88FD09 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8B24719331496AA1CDB201D3680B1673 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EE4E578F709A1B41454E3008D08062A /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A95B1CB74C3CE6C82E80AB861E182C00 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D34068AB912D83AFF35BDE1D7AE87232 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4EC443BABB9828FF32487323E8DEED7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 916613D903B90822AEC6D08992FE1BE3 /* Foundation.framework in Frameworks */, + 39780F2254CF9CD9BFF5094E2F78408A /* Realm.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FDE778E3A95DFD08A950B89C6CD6D476 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 65213987CE11AA7CB11C26AEDCF12165 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 167753D8A72AFAF01A5DEA11BE65C588 /* Support Files */ = { + isa = PBXGroup; + children = ( + 1554787024CBFC6C93F615BF7FEBA98C /* Info.plist */, + 3F7106D0E5AE0F14B74A9302575B427C /* RealmSwift.modulemap */, + E4C718547F82C2630627885D567E0C11 /* RealmSwift.xcconfig */, + 675CB81A7674FCF89BAD9507F320C809 /* RealmSwift-dummy.m */, + 7CDFC95ED00B61813F46C15AAA1F2E0E /* RealmSwift-prefix.pch */, + EEF7197CDB194B4337C9C9B6B25C2CDE /* RealmSwift-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/RealmSwift"; + sourceTree = ""; + }; + 34EE6D2A3692B8753B0E88EF4BD06A5D /* iOS */ = { + isa = PBXGroup; + children = ( + CD006B9F0650FEDD9529CFC918187501 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 3B3EB08E9084D6A3C8B1BD46DFD51570 /* Pods-Abstract-SiriKitExampleSiriIntent */ = { + isa = PBXGroup; + children = ( + 8F31EA1001BDDC58A09B8FD12F361B0D /* Info.plist */, + 7376E1F339A57AF4727A681119324C1F /* Pods-Abstract-SiriKitExampleSiriIntent.modulemap */, + A7E8A3F2985B387478071F560C1ED4DD /* Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.markdown */, + 362AE13FB374BD686F5F7F04A351BBDF /* Pods-Abstract-SiriKitExampleSiriIntent-acknowledgements.plist */, + 1909B62FDD4B8F52E6A10315D4D0E3A1 /* Pods-Abstract-SiriKitExampleSiriIntent-dummy.m */, + 768105B6775C605838B8F18ADB5965FF /* Pods-Abstract-SiriKitExampleSiriIntent-frameworks.sh */, + 7614A7CB5DF19A0C82189B7E57CF145F /* Pods-Abstract-SiriKitExampleSiriIntent-resources.sh */, + 47DB5419A1875CDABB71BE330FDC2CDB /* Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h */, + 8D3B92480CF1FA9CEFDCF9E1CBEC7041 /* Pods-Abstract-SiriKitExampleSiriIntent.debug.xcconfig */, + 20891FE169B19C05FFD135AD934C7631 /* Pods-Abstract-SiriKitExampleSiriIntent.release.xcconfig */, + ); + name = "Pods-Abstract-SiriKitExampleSiriIntent"; + path = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent"; + sourceTree = ""; + }; + 5A5266C96B7D563289C14E7956A22672 /* Pods */ = { + isa = PBXGroup; + children = ( + 8679B903323FECAB5E828EEB0B97D636 /* Realm */, + AEF0F58B6E9C356CC3F1DB48ABD172CF /* RealmSwift */, + ); + name = Pods; + sourceTree = ""; + }; + 5E46BC8BC9EBB5CDB0F7BDF996DFBCA1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 62C842D884BC347551EF8709C2EFDDCF /* librealm-ios.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 71FBFDD5CD17BBB51D678E7CE7CE7054 /* Headers */ = { + isa = PBXGroup; + children = ( + A1D50ABD8B5F4727C844FAEB7141E8B0 /* Realm.h */, + 1990F65EE5CD3970B95801EC893F7023 /* RLMArray.h */, + BB00326D562DD60AC0D4F1E1BDA599D7 /* RLMCollection.h */, + F034ED9BDB35D258599BABBB34D1CBA6 /* RLMConstants.h */, + B83556211BB55DFE4316B39D0B159D9D /* RLMMigration.h */, + FF3374CF1BA7A1E0981140D0622EEAAC /* RLMObject.h */, + 63A5177E90000F5EB6C5C76970347FC5 /* RLMObjectBase.h */, + AD8FDA9F9D69AA41E037199C5E1C9123 /* RLMObjectBase_Dynamic.h */, + 7D100467E73BD5628A5FFC41F9006414 /* RLMObjectSchema.h */, + 90C7D93637C4F5BFDCCC2F9A2B9B9286 /* RLMPlatform.h */, + A0C6A1ACDD47C654A89E0E1853933B52 /* RLMProperty.h */, + 3B7E3BFDBE836C79F27A3AC600D8A46F /* RLMRealm.h */, + F57956B8D2A770EBED0BFF7F85B9D29F /* RLMRealm_Dynamic.h */, + 866724B2FEEAE5E537FB6AF285FCC55E /* RLMRealmConfiguration.h */, + D095A3DC68EAD70B6FA15C99B9C2570A /* RLMResults.h */, + 621975F8E2D07283D4AFE111B207491C /* RLMSchema.h */, + ); + name = Headers; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + EC2C06C32C4F57A6CDBE2847A1DF4D87 /* Frameworks */, + 5A5266C96B7D563289C14E7956A22672 /* Pods */, + A0C847CA2EF9531F9FC846929DFD308E /* Products */, + EFF580CCE38943B2BF7CDB7D65E96923 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 8679B903323FECAB5E828EEB0B97D636 /* Realm */ = { + isa = PBXGroup; + children = ( + 5590FE1B6ACFE1AAE6F2B3E5587D853E /* collection_change_builder.cpp */, + 0AF8951163295E8B49F8C9BCFA16DED8 /* collection_notifications.cpp */, + A5BD1CC0F3FDC0CBA26A763EEC9AFA56 /* collection_notifier.cpp */, + 198A65BDE5F32B4ACAB8478993490991 /* external_commit_helper.cpp */, + DA376102351A08E7F18573CD736D1E9A /* format.cpp */, + 7A09C890040CEBAB8CA57C11861FCF71 /* handover.cpp */, + 7972404FF3C4260EB6A2F72B20C9C8FD /* index_set.cpp */, + 3F283594676B2A4DF6D33A154EA8901F /* list.cpp */, + F16649EDD1D2882F50A2507B4A88FE7C /* list_notifier.cpp */, + 98F80099DEF4E44E8F77F4971C2195E5 /* object_schema.cpp */, + C5DCC8BF3630AF6D49DD2B88CD6E2BF8 /* object_store.cpp */, + 49EE2F5DA1E1A1E29B94A21CF861C587 /* placeholder.cpp */, + C9921372EF33E6D7116B4909079F5ADB /* realm_coordinator.cpp */, + 55108D804B83B5199434A09ED9B306D0 /* results.cpp */, + A34F3725F39D96A0A12E82AFE3C05EE9 /* results_notifier.cpp */, + E523BF9B67952F3971734F9317759B48 /* RLMAccessor.h */, + 18E6CD119975D929D6B08391B135F8CE /* RLMAccessor.mm */, + 436ABD7A1A7F658B25967AD37A2AFCA6 /* RLMAnalytics.mm */, + 366F3B848DF7588701BBDCE39BBC072A /* RLMArray.mm */, + 07255E0F2C2E324D44ED065E23A4DC2E /* RLMArray_Private.h */, + 22B3A9988AC2D49D500963159791BAB0 /* RLMArrayLinkView.mm */, + C44E32CBCA86DBF2F268050E9BB1C264 /* RLMClassInfo.mm */, + 05F1E405B6EE64A4266CF425DD80288A /* RLMCollection.mm */, + FD7F1E2026AB909E63867F538CBBAEE2 /* RLMConstants.m */, + CE5A233AD6FCDACD9E070CFB9D4958F2 /* RLMListBase.h */, + 2529FD63B39AD3AC3E46684AE4528109 /* RLMListBase.mm */, + 31B0BBCB19A28A16EFB1F585DD5699C0 /* RLMMigration.mm */, + 67156F56A6251C094C18417C5E9CAF1C /* RLMMigration_Private.h */, + 8E20A4F837A27723BBF28AD7DE233AD5 /* RLMObject.mm */, + CFFE0D23E969576A357BF2632E504749 /* RLMObject_Private.h */, + 0D2DDEF3DA55C4F5335E491E2DB6008B /* RLMObjectBase.mm */, + C6652EEFE99D613E4AF38C696067C2AC /* RLMObjectSchema.mm */, + 5649F569F9DF6A08A2C9A142D69D824F /* RLMObjectSchema_Private.h */, + 6EDF0B3EDC8560C1EB73D58225CBF327 /* RLMObjectStore.h */, + 69C168B67B003ACA3755866ED84764F2 /* RLMObjectStore.mm */, + 596E2A5D0C96EB0494F989B63836AFBE /* RLMObservation.mm */, + C992B27EB9C3280ECEE250E8812AD166 /* RLMOptionalBase.h */, + BC8307D2954C2C37FAAC9DA6208AF912 /* RLMOptionalBase.mm */, + 560E4B5FE192BC60E773FA5A35629991 /* RLMPredicateUtil.mm */, + B6C4A0DAB2ED319738210B91AED8CBF6 /* RLMProperty.mm */, + 58611CC7789C0314F5F25E105472E232 /* RLMProperty_Private.h */, + B7C9195E39B50F15B65918F41965369D /* RLMQueryUtil.mm */, + 8D753BFF2BCED0FE7BD675D102FBAFEE /* RLMRealm.mm */, + 9AF403B7F9A24F4B457AE9923E5D8876 /* RLMRealm_Private.h */, + 3EE575F7032F45A150314BEBB0DB9423 /* RLMRealmConfiguration.mm */, + 7F06BCF01D58FE275D42F53050091054 /* RLMRealmConfiguration_Private.h */, + 1A6DE5974160987A403ED465DB108BDF /* RLMRealmUtil.mm */, + 796154D364E38B24B9890EA21530520D /* RLMResults.mm */, + B85217406965A6F439FF8370D33C4D13 /* RLMResults_Private.h */, + 0479CCE8A914E5585FDE2514545FAC8E /* RLMSchema.mm */, + CDF799FF812780838210DEAD1119568C /* RLMSchema_Private.h */, + 2DC28458A462E8A1A244E8208B7E5B82 /* RLMSwiftSupport.m */, + 9BADDE90620AC871ADC94A08D389C458 /* RLMUpdateChecker.mm */, + D44AD908506416B6744871CFA76E654F /* RLMUtil.mm */, + FD25AF1E3E42EA405AC6776DE9FB8EC5 /* schema.cpp */, + 7BDE13C3BAE16C02F1F35157AADDCD0B /* shared_realm.cpp */, + 00F5598161EF126F7DA69A64C5DB714B /* thread_confined.cpp */, + 7F7F8AF36B00C7B7206B10B9BBFCC872 /* transact_log_handler.cpp */, + EBF4905F966A1014FE706940F3523AE8 /* weak_realm_notifier.cpp */, + 5E46BC8BC9EBB5CDB0F7BDF996DFBCA1 /* Frameworks */, + 71FBFDD5CD17BBB51D678E7CE7CE7054 /* Headers */, + E908423F56F90658662AFC9834729FA8 /* Support Files */, + ); + path = Realm; + sourceTree = ""; + }; + 9B9BC62EB1110384DE038CCC59360ED5 /* Pods-Abstract-SiriKitExample */ = { + isa = PBXGroup; + children = ( + 332F5378A49B198028E7C26D3F1B089E /* Info.plist */, + E5A4B64719F67BDC7135EA4CC951A3B2 /* Pods-Abstract-SiriKitExample.modulemap */, + FF48BCC24DBDA415D13C4C752A0A6C51 /* Pods-Abstract-SiriKitExample-acknowledgements.markdown */, + E505CD49FA65F825EF990621961240DB /* Pods-Abstract-SiriKitExample-acknowledgements.plist */, + 08E18F888ED89072D2E3FF4EFCD7F518 /* Pods-Abstract-SiriKitExample-dummy.m */, + 68A2015E6F694DEA25FEB75071DBD64F /* Pods-Abstract-SiriKitExample-frameworks.sh */, + D06A6D9B303FABCD01A1767B5A38E455 /* Pods-Abstract-SiriKitExample-resources.sh */, + 165B902CFE265EB6898DF8F3E3F66F3E /* Pods-Abstract-SiriKitExample-umbrella.h */, + 239892C060F34039563F1E3FEB181204 /* Pods-Abstract-SiriKitExample.debug.xcconfig */, + 1DC0E56F7C895F089F4FD6E6FFBAE1D8 /* Pods-Abstract-SiriKitExample.release.xcconfig */, + ); + name = "Pods-Abstract-SiriKitExample"; + path = "Target Support Files/Pods-Abstract-SiriKitExample"; + sourceTree = ""; + }; + A0C847CA2EF9531F9FC846929DFD308E /* Products */ = { + isa = PBXGroup; + children = ( + CDBBCF0F9CA76ABE166B0D0CC8F063C8 /* Pods_Abstract_SiriKitExample.framework */, + 93A8F1885767083219133992B4349562 /* Pods_Abstract_SiriKitExampleSiriIntent.framework */, + 8CA3D3AD90FBD2CD96C21AE42C08142E /* Pods_Abstract_SiriKitExampleSiriIntentUI.framework */, + 7FBCD7C30E985A21C901AFD03BABA96C /* Realm.framework */, + FCECE08D570F5585268B579F58A7578E /* RealmSwift.framework */, + ); + name = Products; + sourceTree = ""; + }; + AEF0F58B6E9C356CC3F1DB48ABD172CF /* RealmSwift */ = { + isa = PBXGroup; + children = ( + 70CA05FDBC8B43930550B71713D5582E /* Aliases.swift */, + F4BA7AF7EB7470B9973A1405CBD337CD /* Error.swift */, + 6F5C9A1BFE4964D63F58EFDAF8603762 /* LinkingObjects.swift */, + 7532539A224F0219EA76B5F5FBCFB0D1 /* List.swift */, + 2C39CCAB7851760C0BDEBE5CE9A5960A /* Migration.swift */, + B9E860CC888D6662669EE9098252D355 /* Object.swift */, + 08F9E161B6AAB03BF52DA8807936A222 /* ObjectSchema.swift */, + 06236DB56685E84315B8657E2B46CCFD /* Optional.swift */, + 6B179AE470981EC3AA10725491B2C442 /* Property.swift */, + 6B396D35C7CD4FBEC47D31EE54A4E324 /* Realm.swift */, + 21094FAC31FEBEACBFC2F9DBE288F387 /* RealmCollection.swift */, + F287A91BE127F2A2441F1834D7537E23 /* RealmConfiguration.swift */, + 8ADB04329F626A89B9A10FA0908E6961 /* Results.swift */, + 18F28CD9831D16F69ABB47B6B295C10B /* Schema.swift */, + 3BAD97370CADCAD821DFB54939F2EB99 /* SortDescriptor.swift */, + D75B1B8751A4AA764288FF4C735A2E33 /* SwiftVersion.swift */, + 1BE2D6D05D2CE3CC0CAB124EAEE4C035 /* Util.swift */, + 167753D8A72AFAF01A5DEA11BE65C588 /* Support Files */, + ); + path = RealmSwift; + sourceTree = ""; + }; + E0769B3A5FA89A4E96A7F0D977CE6738 /* Pods-Abstract-SiriKitExampleSiriIntentUI */ = { + isa = PBXGroup; + children = ( + BC514B857F8B9E392EB3652FFFD4CA1D /* Info.plist */, + 18EA54D7EBE3C26A6C4D83BD81B8E66B /* Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap */, + 5FA006FD3A891D003641A11C01197141 /* Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.markdown */, + C7B921A9DD00D6B67CFFB0F717105B93 /* Pods-Abstract-SiriKitExampleSiriIntentUI-acknowledgements.plist */, + 4008BCBE7C5C87F38E54502626171CBB /* Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m */, + 21F94D6E9EF8950D73AF9F144678B66A /* Pods-Abstract-SiriKitExampleSiriIntentUI-frameworks.sh */, + EE6E60EE3BFD57496D37C387D5D9286F /* Pods-Abstract-SiriKitExampleSiriIntentUI-resources.sh */, + A160C124D3797D418F557BC77D76FA8C /* Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h */, + 7BBD03FD046CB803E10C3D75763EAEDE /* Pods-Abstract-SiriKitExampleSiriIntentUI.debug.xcconfig */, + 71693E07A9D0CF55C892C9C1EC92734F /* Pods-Abstract-SiriKitExampleSiriIntentUI.release.xcconfig */, + ); + name = "Pods-Abstract-SiriKitExampleSiriIntentUI"; + path = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI"; + sourceTree = ""; + }; + E908423F56F90658662AFC9834729FA8 /* Support Files */ = { + isa = PBXGroup; + children = ( + 30FBE4A3F8EDEEC5DB82FF979368C837 /* Info.plist */, + 2293BF38FC39F30DBCB7C7969F325C55 /* Realm.modulemap */, + 7D6341910B1DD7573783B5AE75F972C9 /* Realm.xcconfig */, + 143DC32879715A3E635833619C5C546A /* Realm-dummy.m */, + 09B6B5D85E4A1957F3684E24623A8D62 /* Realm-prefix.pch */, + ); + name = "Support Files"; + path = "../Target Support Files/Realm"; + sourceTree = ""; + }; + EC2C06C32C4F57A6CDBE2847A1DF4D87 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3056258FD0C38D6DCC75B798FA2ABDAC /* Realm.framework */, + 34EE6D2A3692B8753B0E88EF4BD06A5D /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + EFF580CCE38943B2BF7CDB7D65E96923 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 9B9BC62EB1110384DE038CCC59360ED5 /* Pods-Abstract-SiriKitExample */, + 3B3EB08E9084D6A3C8B1BD46DFD51570 /* Pods-Abstract-SiriKitExampleSiriIntent */, + E0769B3A5FA89A4E96A7F0D977CE6738 /* Pods-Abstract-SiriKitExampleSiriIntentUI */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 0CA3E6CE6389541914CCA3A37800BAF9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6E1FDCF23A17A4B0E4601A81B34DB8AF /* Pods-Abstract-SiriKitExampleSiriIntent-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7F961113EEB878393FDC336CF26FA837 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 579D1F26C25384DD1DB1BE5BC33B72EE /* Pods-Abstract-SiriKitExample-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 977E8640438B516D7D4DC39418934389 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C30F771D4003B95B54FD0BF29ACFD7F /* RealmSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4CB530035AA5F7E44E50B06A6782B5C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 308DBD588CB086F494FD66FD734E0791 /* Realm.h in Headers */, + 06E9608AE8E74C3C2A6F2AC98F3CAA47 /* RLMAccessor.h in Headers */, + C3EACD06F7212B238841CF5614DB3473 /* RLMArray.h in Headers */, + 76B745E1B6ED833C8492EC03D19248C0 /* RLMArray_Private.h in Headers */, + 6213148FB5114B5C8625C4D585849E33 /* RLMCollection.h in Headers */, + 863061D5A181C2E36DD017FD7B6A2962 /* RLMConstants.h in Headers */, + D6DB0CCB00D1420E3A1D393547728493 /* RLMListBase.h in Headers */, + CC9329E881E95B1D23A741DE88FC01C7 /* RLMMigration.h in Headers */, + 50A490D5505F22DADABC331A79544FFB /* RLMMigration_Private.h in Headers */, + 2EBEA5B819D72BB30B3AC954E1311507 /* RLMObject.h in Headers */, + 3F7077F2CAA3CF2024F054302A2313E1 /* RLMObject_Private.h in Headers */, + E3B2C64329FBFE0A30FED106D15A0B48 /* RLMObjectBase.h in Headers */, + 3C1F68A5F2A977F95C3CC225100C7965 /* RLMObjectBase_Dynamic.h in Headers */, + 577C7CAFD9C818A473AF92DF75B689CF /* RLMObjectSchema.h in Headers */, + D939AAD994955D51041493A94DA45CFC /* RLMObjectSchema_Private.h in Headers */, + 3AB39C4EF009A6CFE9C8F7AE0BB00F27 /* RLMObjectStore.h in Headers */, + 7C2DD02FB23E320F4BD001CE5E8FAE68 /* RLMOptionalBase.h in Headers */, + 666629576DF9FBE3C9E114B560474BD0 /* RLMPlatform.h in Headers */, + 9C54B03F15F6F4F9C3F0A42C60BCC705 /* RLMProperty.h in Headers */, + AC7EB4178CD3C18C128C4B03C1C6F498 /* RLMProperty_Private.h in Headers */, + 9250C32107F8179F81513C35EFBEAAFA /* RLMRealm.h in Headers */, + 959B5561711B66B48EAA9FF3AB9DCB98 /* RLMRealm_Dynamic.h in Headers */, + D5E0E7FF0FF8AE0478D886F1C9E23849 /* RLMRealm_Private.h in Headers */, + E0C012856B2E74E70ECC9C30EF67050D /* RLMRealmConfiguration.h in Headers */, + C44EE1C50FF5FD5C40F0A0EC768B371B /* RLMRealmConfiguration_Private.h in Headers */, + D0CF501CE77B53CA611447744C8DDE8F /* RLMResults.h in Headers */, + 0032CE35FD56A9809E13FE36112D4A67 /* RLMResults_Private.h in Headers */, + 0757ACA979B39BC77B19DB23F9BAF7D3 /* RLMSchema.h in Headers */, + D24F03001F0FA95829EB6297DD65BB75 /* RLMSchema_Private.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D721D293DD203BE76D51A52983246F5F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CAD46B805FD287D2F16A351067A3E7A /* Pods-Abstract-SiriKitExampleSiriIntentUI-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 19C89E67C17D30F2A9B6217E0B0FA48D /* Pods-Abstract-SiriKitExampleSiriIntentUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7C62DF290E0E9996E05F5DB2FDA999E5 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExampleSiriIntentUI" */; + buildPhases = ( + 023C32C6686A41E1A6E86A2B7F210C05 /* Sources */, + A95B1CB74C3CE6C82E80AB861E182C00 /* Frameworks */, + D721D293DD203BE76D51A52983246F5F /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + BEB8C343775E002EF0457D25CC1220CD /* PBXTargetDependency */, + CF8E39EF567721A02F81F0694625B83C /* PBXTargetDependency */, + ); + name = "Pods-Abstract-SiriKitExampleSiriIntentUI"; + productName = "Pods-Abstract-SiriKitExampleSiriIntentUI"; + productReference = 8CA3D3AD90FBD2CD96C21AE42C08142E /* Pods_Abstract_SiriKitExampleSiriIntentUI.framework */; + productType = "com.apple.product-type.framework"; + }; + A4FB3931703F06F42536B70DA618087C /* Realm */ = { + isa = PBXNativeTarget; + buildConfigurationList = E6EA2603BA678BDE7A033B8693C0C15C /* Build configuration list for PBXNativeTarget "Realm" */; + buildPhases = ( + 1C302490B9511818967CF923B81FDFE8 /* Sources */, + 881C57FCEBCCF30E6ED967E837A07997 /* Frameworks */, + B4CB530035AA5F7E44E50B06A6782B5C /* Headers */, + 5C764F6E56B2D9B9F3E838AFC0FEDB9E /* Copy . Private Headers */, + A3A99CC8123F708E68CB6D49E7B61476 /* Copy . Public Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Realm; + productName = Realm; + productReference = 7FBCD7C30E985A21C901AFD03BABA96C /* Realm.framework */; + productType = "com.apple.product-type.framework"; + }; + AF8CE39DD00E8E7B8F40645C2B0AB46E /* Pods-Abstract-SiriKitExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8E246DDA33720BFB4768CE99C2A09C2 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExample" */; + buildPhases = ( + 0D5417B4ADE21DFDF1D018FC84803A6B /* Sources */, + FDE778E3A95DFD08A950B89C6CD6D476 /* Frameworks */, + 7F961113EEB878393FDC336CF26FA837 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 4B08259CC1A636484F1B7DD793476874 /* PBXTargetDependency */, + 7DE2EC736D151FED6C8684BFFC701AE0 /* PBXTargetDependency */, + ); + name = "Pods-Abstract-SiriKitExample"; + productName = "Pods-Abstract-SiriKitExample"; + productReference = CDBBCF0F9CA76ABE166B0D0CC8F063C8 /* Pods_Abstract_SiriKitExample.framework */; + productType = "com.apple.product-type.framework"; + }; + C3DC8BA47CF0F184F7CB7AE68C1C2B78 /* RealmSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = FADF72CA5BCD7AAD6500DEB4D8EB6A79 /* Build configuration list for PBXNativeTarget "RealmSwift" */; + buildPhases = ( + 5308FB5333B139FD09E5455C29E7EBCF /* Sources */, + E4EC443BABB9828FF32487323E8DEED7 /* Frameworks */, + 977E8640438B516D7D4DC39418934389 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + B280637E7ED8D89183B5AF20C9DA82C1 /* PBXTargetDependency */, + ); + name = RealmSwift; + productName = RealmSwift; + productReference = FCECE08D570F5585268B579F58A7578E /* RealmSwift.framework */; + productType = "com.apple.product-type.framework"; + }; + DCDC6A5221D049CAD97576D797FD9570 /* Pods-Abstract-SiriKitExampleSiriIntent */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0D9CD811535EBD909EDEE8DA0105D201 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExampleSiriIntent" */; + buildPhases = ( + 14AD765DD5C1FD1F4CDA041058E19A38 /* Sources */, + 8B24719331496AA1CDB201D3680B1673 /* Frameworks */, + 0CA3E6CE6389541914CCA3A37800BAF9 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + C452487E3F779588DE04847568611180 /* PBXTargetDependency */, + 32D133063E43981B018416FCC2AE4A82 /* PBXTargetDependency */, + ); + name = "Pods-Abstract-SiriKitExampleSiriIntent"; + productName = "Pods-Abstract-SiriKitExampleSiriIntent"; + productReference = 93A8F1885767083219133992B4349562 /* Pods_Abstract_SiriKitExampleSiriIntent.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = A0C847CA2EF9531F9FC846929DFD308E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + AF8CE39DD00E8E7B8F40645C2B0AB46E /* Pods-Abstract-SiriKitExample */, + DCDC6A5221D049CAD97576D797FD9570 /* Pods-Abstract-SiriKitExampleSiriIntent */, + 19C89E67C17D30F2A9B6217E0B0FA48D /* Pods-Abstract-SiriKitExampleSiriIntentUI */, + A4FB3931703F06F42536B70DA618087C /* Realm */, + C3DC8BA47CF0F184F7CB7AE68C1C2B78 /* RealmSwift */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 023C32C6686A41E1A6E86A2B7F210C05 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 68F7A0C1742C3E95661570A956703360 /* Pods-Abstract-SiriKitExampleSiriIntentUI-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0D5417B4ADE21DFDF1D018FC84803A6B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3301C49F45060513DEC43EDA3F0BBEE0 /* Pods-Abstract-SiriKitExample-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 14AD765DD5C1FD1F4CDA041058E19A38 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5456A76985ACE8F58DB10DC139D9A321 /* Pods-Abstract-SiriKitExampleSiriIntent-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1C302490B9511818967CF923B81FDFE8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 60AA25A9AEDC5828041641B69BBF8049 /* collection_change_builder.cpp in Sources */, + 5BC67B848FE9E757410073CF20D1B003 /* collection_notifications.cpp in Sources */, + B3B2C90E174C903EE92B71536DC711F7 /* collection_notifier.cpp in Sources */, + 6DBEDA0734A6AD7B35EA9ABAAB63CC25 /* external_commit_helper.cpp in Sources */, + AF281E48CF94DA6A3F1DBA53CBEB9527 /* format.cpp in Sources */, + 91E760FFDCCA6D56578DE27EFAE778C5 /* handover.cpp in Sources */, + 686A203451FB59581664B3B43C59D53B /* index_set.cpp in Sources */, + D6056083A3229AFFF957640D94CB9D09 /* list.cpp in Sources */, + CB08008ACA70DF3A43EEC4D289BEBCAC /* list_notifier.cpp in Sources */, + 60C531BAE48A0A5B35302809CB84CA1D /* object_schema.cpp in Sources */, + 70114BD12454E3BB6E6787CCBB3432D9 /* object_store.cpp in Sources */, + 660E7F5B8AED1B3301F2E38347D2CD2B /* placeholder.cpp in Sources */, + 2582147E6FC78D914D28C4A301D385E3 /* Realm-dummy.m in Sources */, + AFD5AE9BBA7C00419A380F2158B9751E /* realm_coordinator.cpp in Sources */, + 4B161B734697381360EBB4B800394ABF /* results.cpp in Sources */, + ABE2ACCAC3F1C043AEA19476C2045C78 /* results_notifier.cpp in Sources */, + FEB9A8A037D395C201C26BC17D6CD0CA /* RLMAccessor.mm in Sources */, + 30D089762C6D1158000EAF58FBEE81A2 /* RLMAnalytics.mm in Sources */, + 61C11AA4752CBC5BBD26108003D73BA6 /* RLMArray.mm in Sources */, + 090E3BF32CACCCDA18635B5EFA3F6773 /* RLMArrayLinkView.mm in Sources */, + 56EF6E8267B5C456E87841396E46A602 /* RLMClassInfo.mm in Sources */, + 2BF488A853A7ED449E21A57037593252 /* RLMCollection.mm in Sources */, + EFFFDBB58CF6F75068D15192A57FE8E6 /* RLMConstants.m in Sources */, + 48721CD9685E6C4E1619FFA82BE1DCF8 /* RLMListBase.mm in Sources */, + 5BE23D2809AFB0B1D84AED71E9C258D2 /* RLMMigration.mm in Sources */, + 885585F019357D659C6615ECEF5EEF87 /* RLMObject.mm in Sources */, + 4F6AFE53BCCA4C549B3B849541B7C723 /* RLMObjectBase.mm in Sources */, + B9044FF42638E18A0A24FBE292E28D55 /* RLMObjectSchema.mm in Sources */, + D75B68CE087E46226C56C3813E715C7D /* RLMObjectStore.mm in Sources */, + F427953007993486CB51D65C7D4FA968 /* RLMObservation.mm in Sources */, + D9C927E5079FA87D6631BAEB0492296C /* RLMOptionalBase.mm in Sources */, + A840C6C2E8A3B6A5B4768852307FE256 /* RLMPredicateUtil.mm in Sources */, + 90A61FACBF66C8AEDFECBD8E452C6664 /* RLMProperty.mm in Sources */, + 159C243AAFA2525170BAD64C82A030F2 /* RLMQueryUtil.mm in Sources */, + AE70367ACC6ECEAAD093D279CB5D2983 /* RLMRealm.mm in Sources */, + ACFB67331C772F990B5AE2F85CF39C46 /* RLMRealmConfiguration.mm in Sources */, + 6A95EA452F3E3262197CC9C95FC7BD84 /* RLMRealmUtil.mm in Sources */, + 09190384DB804249A521861B0D013309 /* RLMResults.mm in Sources */, + 389DDD3F94482813BB443A124A087708 /* RLMSchema.mm in Sources */, + D9AD60825CA18A144B8B20C40A892365 /* RLMSwiftSupport.m in Sources */, + 54FC7E1578A81A8FDB69A5E73A755873 /* RLMUpdateChecker.mm in Sources */, + CA06A76082FFE8DF61AC494AE852491B /* RLMUtil.mm in Sources */, + 97A9A1EA6B0956C42524A2FC0F0C7F0A /* schema.cpp in Sources */, + 93E6469A8EE3566AACF849928F06A137 /* shared_realm.cpp in Sources */, + AA36C7D6BA0E8A5AAC7A69C6AFF82AAC /* thread_confined.cpp in Sources */, + 109F4E72BC4880D226C9263224FECB2C /* transact_log_handler.cpp in Sources */, + 8EA127C34BB787BFB823383FA051E6E5 /* weak_realm_notifier.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5308FB5333B139FD09E5455C29E7EBCF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AFC3B8025AAAC7333FAB641FBCB01C3 /* Aliases.swift in Sources */, + E60C143D63355A395511926A2F2945F1 /* Error.swift in Sources */, + 60CBEA8A37D3CE527F732EC7E346B519 /* LinkingObjects.swift in Sources */, + 1618AA5ABA295D086860863BB5CF7A7C /* List.swift in Sources */, + 7D5C974E9775B7CC7E2A3BC644EF0B54 /* Migration.swift in Sources */, + 379DBAA26A6534AF62C49F5A94F97E22 /* Object.swift in Sources */, + 7239C68D18BB84959ED6513D26B33F5D /* ObjectSchema.swift in Sources */, + 81E99760E1FEF42B2A90BF10F1071609 /* Optional.swift in Sources */, + 7799DBD9DB4A7A983D6AB2F54DB4292A /* Property.swift in Sources */, + 8533A869F364D653A51ACBED102D4CD1 /* Realm.swift in Sources */, + 4D3B0A0477202370A065534A610AC13B /* RealmCollection.swift in Sources */, + 20B778958110774A871B70FC97031224 /* RealmConfiguration.swift in Sources */, + B4D568BA269A4AF0B209DC22E3DB2A80 /* RealmSwift-dummy.m in Sources */, + 8CB9BFB7AC42857B58D9A96114C56EF5 /* Results.swift in Sources */, + C8D843767B4F1F3CB92F22979B29E5BD /* Schema.swift in Sources */, + FEF4AC5A92B1822CD91FD7FEF0C582DD /* SortDescriptor.swift in Sources */, + 0E6097E6182D1D3722A52056543791C0 /* SwiftVersion.swift in Sources */, + C82A1A97B02A8D602FE2AE99BB2D770B /* Util.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 32D133063E43981B018416FCC2AE4A82 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RealmSwift; + target = C3DC8BA47CF0F184F7CB7AE68C1C2B78 /* RealmSwift */; + targetProxy = 253455C5D5692DD8F71CE509A88AE94D /* PBXContainerItemProxy */; + }; + 4B08259CC1A636484F1B7DD793476874 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Realm; + target = A4FB3931703F06F42536B70DA618087C /* Realm */; + targetProxy = F52A65D75E877738433341638FC83333 /* PBXContainerItemProxy */; + }; + 7DE2EC736D151FED6C8684BFFC701AE0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RealmSwift; + target = C3DC8BA47CF0F184F7CB7AE68C1C2B78 /* RealmSwift */; + targetProxy = AB13B76E2D71F39D47864CA32E55458C /* PBXContainerItemProxy */; + }; + B280637E7ED8D89183B5AF20C9DA82C1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Realm; + target = A4FB3931703F06F42536B70DA618087C /* Realm */; + targetProxy = 9A99346228A5C7D5DF776A3926A43AC1 /* PBXContainerItemProxy */; + }; + BEB8C343775E002EF0457D25CC1220CD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Realm; + target = A4FB3931703F06F42536B70DA618087C /* Realm */; + targetProxy = BC21C510B6840A068A3612A30808BBA4 /* PBXContainerItemProxy */; + }; + C452487E3F779588DE04847568611180 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Realm; + target = A4FB3931703F06F42536B70DA618087C /* Realm */; + targetProxy = 2FC044AAD67BD26F03CC9E8489FB65A1 /* PBXContainerItemProxy */; + }; + CF8E39EF567721A02F81F0694625B83C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RealmSwift; + target = C3DC8BA47CF0F184F7CB7AE68C1C2B78 /* RealmSwift */; + targetProxy = 53C1F1E69BCE212732B5E8C72B0EF408 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1821A8D05F9859D8ABD47C43CADC1677 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D6341910B1DD7573783B5AE75F972C9 /* Realm.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Realm/Realm-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Realm/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Realm/Realm.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = Realm; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 1C08F610D26C79D5FED3CE659F9DA415 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1DC0E56F7C895F089F4FD6E6FFBAE1D8 /* Pods-Abstract-SiriKitExample.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 54962CCE9CC1327A9790CE6F57BFD918 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 20891FE169B19C05FFD135AD934C7631 /* Pods-Abstract-SiriKitExampleSiriIntent.release.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExampleSiriIntent; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 7C4EE29BBB081225AE02EBFE29B06AC7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 71693E07A9D0CF55C892C9C1EC92734F /* Pods-Abstract-SiriKitExampleSiriIntentUI.release.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExampleSiriIntentUI; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 9E3D6685FABD6A9379F5D596412BD21E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E4C718547F82C2630627885D567E0C11 /* RealmSwift.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/RealmSwift/RealmSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RealmSwift/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/RealmSwift/RealmSwift.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = RealmSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B9F85F87D03A7483077518D4B7C091FD /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8D3B92480CF1FA9CEFDCF9E1CBEC7041 /* Pods-Abstract-SiriKitExampleSiriIntent.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntent/Pods-Abstract-SiriKitExampleSiriIntent.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExampleSiriIntent; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D560687C2EAA7604298B56AEE78343D9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E4991CF44605AE560E5FFEDBC2F1B62F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E4C718547F82C2630627885D567E0C11 /* RealmSwift.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/RealmSwift/RealmSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/RealmSwift/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/RealmSwift/RealmSwift.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = RealmSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + EBE27D088974ADA84D4C7C74610B9105 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7BBD03FD046CB803E10C3D75763EAEDE /* Pods-Abstract-SiriKitExampleSiriIntentUI.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExampleSiriIntentUI/Pods-Abstract-SiriKitExampleSiriIntentUI.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExampleSiriIntentUI; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F1CACC81189ECB1BB82CE47F73EBE3D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + ONLY_ACTIVE_ARCH = YES; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + F26C0F0AE5AB57E74D3BF7571F0B1D16 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 239892C060F34039563F1E3FEB181204 /* Pods-Abstract-SiriKitExample.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-Abstract-SiriKitExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Abstract-SiriKitExample/Pods-Abstract-SiriKitExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_Abstract_SiriKitExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + FAEEB656BCA056A63B81FB230BF8FC32 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7D6341910B1DD7573783B5AE75F972C9 /* Realm.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Realm/Realm-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Realm/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Realm/Realm.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = Realm; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0D9CD811535EBD909EDEE8DA0105D201 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExampleSiriIntent" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B9F85F87D03A7483077518D4B7C091FD /* Debug */, + 54962CCE9CC1327A9790CE6F57BFD918 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F1CACC81189ECB1BB82CE47F73EBE3D1 /* Debug */, + D560687C2EAA7604298B56AEE78343D9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7C62DF290E0E9996E05F5DB2FDA999E5 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExampleSiriIntentUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EBE27D088974ADA84D4C7C74610B9105 /* Debug */, + 7C4EE29BBB081225AE02EBFE29B06AC7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E6EA2603BA678BDE7A033B8693C0C15C /* Build configuration list for PBXNativeTarget "Realm" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1821A8D05F9859D8ABD47C43CADC1677 /* Debug */, + FAEEB656BCA056A63B81FB230BF8FC32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8E246DDA33720BFB4768CE99C2A09C2 /* Build configuration list for PBXNativeTarget "Pods-Abstract-SiriKitExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F26C0F0AE5AB57E74D3BF7571F0B1D16 /* Debug */, + 1C08F610D26C79D5FED3CE659F9DA415 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FADF72CA5BCD7AAD6500DEB4D8EB6A79 /* Build configuration list for PBXNativeTarget "RealmSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E3D6685FABD6A9379F5D596412BD21E /* Debug */, + E4991CF44605AE560E5FFEDBC2F1B62F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/SiriKitExample/Pods/Realm/LICENSE b/SiriKitExample/Pods/Realm/LICENSE new file mode 100644 index 0000000..a194346 --- /dev/null +++ b/SiriKitExample/Pods/Realm/LICENSE @@ -0,0 +1,269 @@ +TABLE OF CONTENTS + +1. Apache License version 2.0 +2. Realm Components +3. Export Compliance + +------------------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +REALM COMPONENTS + +This software contains components with separate copyright and license terms. +Your use of these components is subject to the terms and conditions of the +following licenses. + +For the Realm Core component + + Realm Core Binary License + + Copyright (c) 2011-2014 Realm Inc All rights reserved + + Redistribution and use in binary form, with or without modification, is + permitted provided that the following conditions are met: + + 1. You agree not to attempt to decompile, disassemble, reverse engineer or + otherwise discover the source code from which the binary code was derived. + You may, however, access and obtain a separate license for most of the + source code from which this Software was created, at + http://realm.io/pricing/. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +EXPORT COMPLIANCE + +You understand that the Software may contain cryptographic functions that may be +subject to export restrictions, and you represent and warrant that you are not +located in a country that is subject to United States export restriction or embargo, +including Cuba, Iran, North Korea, Sudan, Syria or the Crimea region, and that you +are not on the Department of Commerce list of Denied Persons, Unverified Parties, +or affiliated with a Restricted Entity. + +You agree to comply with all export, re-export and import restrictions and +regulations of the Department of Commerce or other agency or authority of the +United States or other applicable countries. You also agree not to transfer, or +authorize the transfer of, directly or indirectly, the Software to any prohibited +country, including Cuba, Iran, North Korea, Sudan, Syria or the Crimea region, +or to any person or organization on or affiliated with the Department of +Commerce lists of Denied Persons, Unverified Parties or Restricted Entities, or +otherwise in violation of any such restrictions or regulations. diff --git a/SiriKitExample/Pods/Realm/README.md b/SiriKitExample/Pods/Realm/README.md new file mode 100644 index 0000000..322ac2d --- /dev/null +++ b/SiriKitExample/Pods/Realm/README.md @@ -0,0 +1,72 @@ +![Realm](https://github.com/realm/realm-cocoa/raw/master/logo.png) + +Realm is a mobile database that runs directly inside phones, tablets or wearables. +This repository holds the source code for the iOS, OS X, watchOS & tvOS versions of Realm Swift & Realm Objective-C. + +## Features + +* **Mobile-first:** Realm is the first database built from the ground up to run directly inside phones, tablets and wearables. +* **Simple:** Data is directly [exposed as objects](https://realm.io/docs/objc/latest/#models) and [queryable by code](https://realm.io/docs/objc/latest/#queries), removing the need for ORM's riddled with performance & maintenance issues. Most of our users pick it up intuitively, getting simple apps up & running in minutes. +* **Modern:** Realm supports relationships, generics, vectorization and even Swift. +* **Fast:** Realm is faster than even raw SQLite on common operations, while maintaining an extremely rich feature set. + +## Getting Started + +Please see the detailed instructions in our docs to add [Realm Objective-C](https://realm.io/docs/objc/latest/#installation) _or_ [Realm Swift](https://realm.io/docs/swift/latest/#installation) to your Xcode project. + +## Documentation + +### Realm Objective-C + +The documentation can be found at [realm.io/docs/objc/latest](https://realm.io/docs/objc/latest). +The API reference is located at [realm.io/docs/objc/latest/api](https://realm.io/docs/objc/latest/api). + +### Realm Swift + +The documentation can be found at [realm.io/docs/swift/latest](https://realm.io/docs/swift/latest). +The API reference is located at [realm.io/docs/swift/latest/api](https://realm.io/docs/swift/latest/api). + +## Getting Help + +- **Need help with your code?**: Look for previous questions on the [#realm tag](https://stackoverflow.com/questions/tagged/realm?sort=newest) — or [ask a new question](https://stackoverflow.com/questions/ask?tags=realm). We actively monitor & answer questions on SO! +- **Have a bug to report?** [Open an issue](https://github.com/realm/realm-cocoa/issues/new). If possible, include the version of Realm, a full log, the Realm file, and a project that shows the issue. +- **Have a feature request?** [Open an issue](https://github.com/realm/realm-cocoa/issues/new). Tell us what the feature should do, and why you want the feature. +- Sign up for our [**Community Newsletter**](http://eepurl.com/VEKCn) to get regular tips, learn about other use-cases and get alerted of blogposts and tutorials about Realm. + +## Building Realm + +In case you don't want to use the precompiled version, you can build Realm yourself from source. + +Prerequisites: + +* Building Realm requires Xcode 7.3. +* Building Realm documentation requires [jazzy](https://github.com/realm/jazzy) + +Once you have all the necessary prerequisites, building Realm.framework just takes a single command: `sh build.sh build`. You'll need an internet connection the first time you build Realm to download the core binary. + +Run `sh build.sh help` to see all the actions you can perform (build ios/osx, generate docs, test, etc.). + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for more details! + +This project adheres to the [Contributor Covenant Code of Conduct](https://realm.io/conduct). +By participating, you are expected to uphold this code. Please report +unacceptable behavior to [info@realm.io](mailto:info@realm.io). + +## License + +Realm Objective-C & Realm Swift are published under the Apache 2.0 license. +The underlying core is available under the [Realm Core Binary License](https://github.com/realm/realm-cocoa/blob/master/LICENSE#L210-L243) while we [work to open-source it under the Apache 2.0 license](https://realm.io/docs/objc/latest/#faq). + +**This product is not being made available to any person located in Cuba, Iran, +North Korea, Sudan, Syria or the Crimea region, or to any other person that is +not eligible to receive the product under U.S. law.** + +## Feedback + +**_If you use Realm and are happy with it, all we ask is that you please consider sending out a tweet mentioning [@realm](https://twitter.com/realm) or email [help@realm.io](mailto:help@realm.io) to share your thoughts!_** + +**_And if you don't like it, please let us know what you would like improved, so we can fix it!_** + +![analytics](https://ga-beacon.appspot.com/UA-50247013-2/realm-cocoa/README?pixel) diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/collection_notifications.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/collection_notifications.cpp new file mode 100644 index 0000000..12fca83 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/collection_notifications.cpp @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "collection_notifications.hpp" + +#include "impl/collection_notifier.hpp" + +using namespace realm; +using namespace realm::_impl; + +NotificationToken::NotificationToken(std::shared_ptr<_impl::CollectionNotifier> notifier, size_t token) +: m_notifier(std::move(notifier)), m_token(token) +{ +} + +NotificationToken::~NotificationToken() +{ + // m_notifier itself (and not just the pointed-to thing) needs to be accessed + // atomically to ensure that there are no data races when the token is + // destroyed after being modified on a different thread. + // This is needed despite the token not being thread-safe in general as + // users find it very surprising for obj-c objects to care about what + // thread they are deallocated on. + if (auto notifier = m_notifier.exchange({})) { + notifier->remove_callback(m_token); + } +} + +NotificationToken::NotificationToken(NotificationToken&&) = default; + +NotificationToken& NotificationToken::operator=(realm::NotificationToken&& rgt) +{ + if (this != &rgt) { + if (auto notifier = m_notifier.exchange({})) { + notifier->remove_callback(m_token); + } + m_notifier = std::move(rgt.m_notifier); + m_token = rgt.m_token; + } + return *this; +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp new file mode 100644 index 0000000..5195a3e --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/apple/external_commit_helper.cpp @@ -0,0 +1,226 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/external_commit_helper.hpp" + +#include "impl/realm_coordinator.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace realm; +using namespace realm::_impl; + +namespace { +// Write a byte to a pipe to notify anyone waiting for data on the pipe +void notify_fd(int fd, int read_fd) +{ + while (true) { + char c = 0; + ssize_t ret = write(fd, &c, 1); + if (ret == 1) { + break; + } + + // If the pipe's buffer is full, we need to read some of the old data in + // it to make space. We don't just read in the code waiting for + // notifications so that we can notify multiple waiters with a single + // write. + assert(ret == -1 && errno == EAGAIN); + char buff[1024]; + read(read_fd, buff, sizeof buff); + } +} +} // anonymous namespace + +void ExternalCommitHelper::FdHolder::close() +{ + if (m_fd != -1) { + ::close(m_fd); + } + m_fd = -1; +} + +// Inter-thread and inter-process notifications of changes are done using a +// named pipe in the filesystem next to the Realm file. Everyone who wants to be +// notified of commits waits for data to become available on the pipe, and anyone +// who commits a write transaction writes data to the pipe after releasing the +// write lock. Note that no one ever actually *reads* from the pipe: the data +// actually written is meaningless, and trying to read from a pipe from multiple +// processes at once is fraught with race conditions. + +// When a RLMRealm instance is created, we add a CFRunLoopSource to the current +// thread's runloop. On each cycle of the run loop, the run loop checks each of +// its sources for work to do, which in the case of CFRunLoopSource is just +// checking if CFRunLoopSourceSignal has been called since the last time it ran, +// and if so invokes the function pointer supplied when the source is created, +// which in our case just invokes `[realm handleExternalChange]`. + +// Listening for external changes is done using kqueue() on a background thread. +// kqueue() lets us efficiently wait until the amount of data which can be read +// from one or more file descriptors has changed, and tells us which of the file +// descriptors it was that changed. We use this to wait on both the shared named +// pipe, and a local anonymous pipe. When data is written to the named pipe, we +// signal the runloop source and wake up the target runloop, and when data is +// written to the anonymous pipe the background thread removes the runloop +// source from the runloop and and shuts down. +ExternalCommitHelper::ExternalCommitHelper(RealmCoordinator& parent) +: m_parent(parent) +{ + m_kq = kqueue(); + if (m_kq == -1) { + throw std::system_error(errno, std::system_category()); + } + +#if !TARGET_OS_TV + auto path = parent.get_path() + ".note"; + + // Create and open the named pipe + int ret = mkfifo(path.c_str(), 0600); + if (ret == -1) { + int err = errno; + if (err == ENOTSUP) { + // Filesystem doesn't support named pipes, so try putting it in tmp instead + // Hash collisions are okay here because they just result in doing + // extra work, as opposed to correctness problems + std::ostringstream ss; + ss << getenv("TMPDIR"); + ss << "realm_" << std::hash()(path) << ".note"; + path = ss.str(); + ret = mkfifo(path.c_str(), 0600); + err = errno; + } + // the fifo already existing isn't an error + if (ret == -1 && err != EEXIST) { + throw std::system_error(err, std::system_category()); + } + } + + m_notify_fd = open(path.c_str(), O_RDWR); + if (m_notify_fd == -1) { + throw std::system_error(errno, std::system_category()); + } + + // Make writing to the pipe return -1 when the pipe's buffer is full + // rather than blocking until there's space available + ret = fcntl(m_notify_fd, F_SETFL, O_NONBLOCK); + if (ret == -1) { + throw std::system_error(errno, std::system_category()); + } + +#else // !TARGET_OS_TV + + // tvOS does not support named pipes, so use an anonymous pipe instead + int notification_pipe[2]; + int ret = pipe(notification_pipe); + if (ret == -1) { + throw std::system_error(errno, std::system_category()); + } + + m_notify_fd = notification_pipe[0]; + m_notify_fd_write = notification_pipe[1]; + +#endif // TARGET_OS_TV + + // Create the anonymous pipe for shutdown notifications + int shutdown_pipe[2]; + ret = pipe(shutdown_pipe); + if (ret == -1) { + throw std::system_error(errno, std::system_category()); + } + + m_shutdown_read_fd = shutdown_pipe[0]; + m_shutdown_write_fd = shutdown_pipe[1]; + + m_thread = std::async(std::launch::async, [=] { + try { + listen(); + } + catch (std::exception const& e) { + fprintf(stderr, "uncaught exception in notifier thread: %s: %s\n", typeid(e).name(), e.what()); + asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "uncaught exception in notifier thread: %s: %s", typeid(e).name(), e.what()); + throw; + } + catch (...) { + fprintf(stderr, "uncaught exception in notifier thread\n"); + asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "uncaught exception in notifier thread"); + throw; + } + }); +} + +ExternalCommitHelper::~ExternalCommitHelper() +{ + notify_fd(m_shutdown_write_fd, m_shutdown_read_fd); + m_thread.wait(); // Wait for the thread to exit +} + +void ExternalCommitHelper::listen() +{ + pthread_setname_np("RLMRealm notification listener"); + + // Set up the kqueue + // EVFILT_READ indicates that we care about data being available to read + // on the given file descriptor. + // EV_CLEAR makes it wait for the amount of data available to be read to + // change rather than just returning when there is any data to read. + struct kevent ke[2]; + EV_SET(&ke[0], m_notify_fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); + EV_SET(&ke[1], m_shutdown_read_fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); + int ret = kevent(m_kq, ke, 2, nullptr, 0, nullptr); + assert(ret == 0); + + while (true) { + struct kevent event; + // Wait for data to become on either fd + // Return code is number of bytes available or -1 on error + ret = kevent(m_kq, nullptr, 0, &event, 1, nullptr); + assert(ret >= 0); + if (ret == 0) { + // Spurious wakeup; just wait again + continue; + } + + // Check which file descriptor had activity: if it's the shutdown + // pipe, then someone called -stop; otherwise it's the named pipe + // and someone committed a write transaction + if (event.ident == (uint32_t)m_shutdown_read_fd) { + return; + } + assert(event.ident == (uint32_t)m_notify_fd); + + m_parent.on_change(); + } +} + +void ExternalCommitHelper::notify_others() +{ + if (m_notify_fd_write != -1) { + notify_fd(m_notify_fd_write, m_notify_fd); + } + else { + notify_fd(m_notify_fd, m_notify_fd); + } +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_change_builder.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_change_builder.cpp new file mode 100644 index 0000000..c413f55 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_change_builder.cpp @@ -0,0 +1,662 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/collection_change_builder.hpp" + +#include +#include + +#include + +using namespace realm; +using namespace realm::_impl; + +CollectionChangeBuilder::CollectionChangeBuilder(IndexSet deletions, + IndexSet insertions, + IndexSet modifications, + std::vector moves) +: CollectionChangeSet({std::move(deletions), std::move(insertions), std::move(modifications), std::move(moves)}) +{ + for (auto&& move : this->moves) { + this->deletions.add(move.from); + this->insertions.add(move.to); + } +} + +void CollectionChangeBuilder::merge(CollectionChangeBuilder&& c) +{ + if (c.empty()) + return; + if (empty()) { + *this = std::move(c); + return; + } + + verify(); + c.verify(); + + // First update any old moves + if (!c.moves.empty() || !c.deletions.empty() || !c.insertions.empty()) { + auto it = std::remove_if(begin(moves), end(moves), [&](auto& old) { + // Check if the moved row was moved again, and if so just update the destination + auto it = find_if(begin(c.moves), end(c.moves), [&](auto const& m) { + return old.to == m.from; + }); + if (it != c.moves.end()) { + if (modifications.contains(it->from)) + c.modifications.add(it->to); + old.to = it->to; + *it = c.moves.back(); + c.moves.pop_back(); + ++it; + return false; + } + + // Check if the destination was deleted + // Removing the insert for this move will happen later + if (c.deletions.contains(old.to)) + return true; + + // Update the destination to adjust for any new insertions and deletions + old.to = c.insertions.shift(c.deletions.unshift(old.to)); + return false; + }); + moves.erase(it, end(moves)); + } + + // Ignore new moves of rows which were previously inserted (the implicit + // delete from the move will remove the insert) + if (!insertions.empty() && !c.moves.empty()) { + c.moves.erase(std::remove_if(begin(c.moves), end(c.moves), + [&](auto const& m) { return insertions.contains(m.from); }), + end(c.moves)); + } + + // Ensure that any previously modified rows which were moved are still modified + if (!modifications.empty() && !c.moves.empty()) { + for (auto const& move : c.moves) { + if (modifications.contains(move.from)) + c.modifications.add(move.to); + } + } + + // Update the source position of new moves to compensate for the changes made + // in the old changeset + if (!deletions.empty() || !insertions.empty()) { + for (auto& move : c.moves) + move.from = deletions.shift(insertions.unshift(move.from)); + } + + moves.insert(end(moves), begin(c.moves), end(c.moves)); + + // New deletion indices have been shifted by the insertions, so unshift them + // before adding + deletions.add_shifted_by(insertions, c.deletions); + + // Drop any inserted-then-deleted rows, then merge in new insertions + insertions.erase_at(c.deletions); + insertions.insert_at(c.insertions); + + clean_up_stale_moves(); + + modifications.erase_at(c.deletions); + modifications.shift_for_insert_at(c.insertions); + modifications.add(c.modifications); + + c = {}; + verify(); +} + +void CollectionChangeBuilder::clean_up_stale_moves() +{ + // Look for moves which are now no-ops, and remove them plus the associated + // insert+delete. Note that this isn't just checking for from == to due to + // that rows can also be shifted by other inserts and deletes + moves.erase(std::remove_if(begin(moves), end(moves), [&](auto const& move) { + if (move.from - deletions.count(0, move.from) != move.to - insertions.count(0, move.to)) + return false; + deletions.remove(move.from); + insertions.remove(move.to); + return true; + }), end(moves)); +} + +void CollectionChangeBuilder::parse_complete() +{ + moves.reserve(m_move_mapping.size()); + for (auto move : m_move_mapping) { + REALM_ASSERT_DEBUG(deletions.contains(move.second)); + REALM_ASSERT_DEBUG(insertions.contains(move.first)); + moves.push_back({move.second, move.first}); + } + m_move_mapping.clear(); + std::sort(begin(moves), end(moves), + [](auto const& a, auto const& b) { return a.from < b.from; }); +} + +void CollectionChangeBuilder::modify(size_t ndx) +{ + modifications.add(ndx); +} + +void CollectionChangeBuilder::insert(size_t index, size_t count, bool track_moves) +{ + modifications.shift_for_insert_at(index, count); + if (!track_moves) + return; + + insertions.insert_at(index, count); + + for (auto& move : moves) { + if (move.to >= index) + ++move.to; + } +} + +void CollectionChangeBuilder::erase(size_t index) +{ + modifications.erase_at(index); + size_t unshifted = insertions.erase_or_unshift(index); + if (unshifted != IndexSet::npos) + deletions.add_shifted(unshifted); + + for (size_t i = 0; i < moves.size(); ++i) { + auto& move = moves[i]; + if (move.to == index) { + moves.erase(moves.begin() + i); + --i; + } + else if (move.to > index) + --move.to; + } +} + +void CollectionChangeBuilder::clear(size_t old_size) +{ + if (old_size != std::numeric_limits::max()) { + for (auto range : deletions) + old_size += range.second - range.first; + for (auto range : insertions) + old_size -= range.second - range.first; + } + + modifications.clear(); + insertions.clear(); + moves.clear(); + m_move_mapping.clear(); + deletions.set(old_size); +} + +void CollectionChangeBuilder::move(size_t from, size_t to) +{ + REALM_ASSERT(from != to); + + bool updated_existing_move = false; + for (auto& move : moves) { + if (move.to != from) { + // Shift other moves if this row is moving from one side of them + // to the other + if (move.to >= to && move.to < from) + ++move.to; + else if (move.to <= to && move.to > from) + --move.to; + continue; + } + REALM_ASSERT(!updated_existing_move); + + // Collapse A -> B, B -> C into a single A -> C move + move.to = to; + updated_existing_move = true; + + insertions.erase_at(from); + insertions.insert_at(to); + } + + if (!updated_existing_move) { + auto shifted_from = insertions.erase_or_unshift(from); + insertions.insert_at(to); + + // Don't report deletions/moves for newly inserted rows + if (shifted_from != IndexSet::npos) { + shifted_from = deletions.add_shifted(shifted_from); + moves.push_back({shifted_from, to}); + } + } + + bool modified = modifications.contains(from); + modifications.erase_at(from); + + if (modified) + modifications.insert_at(to); + else + modifications.shift_for_insert_at(to); +} + +void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row, bool track_moves) +{ + REALM_ASSERT(row_ndx <= last_row); + REALM_ASSERT(insertions.empty() || prev(insertions.end())->second - 1 <= last_row); + REALM_ASSERT(modifications.empty() || prev(modifications.end())->second - 1 <= last_row); + + if (row_ndx == last_row) { + if (track_moves) { + auto shifted_from = insertions.erase_or_unshift(row_ndx); + if (shifted_from != IndexSet::npos) + deletions.add_shifted(shifted_from); + m_move_mapping.erase(row_ndx); + } + modifications.remove(row_ndx); + return; + } + + bool modified = modifications.contains(last_row); + if (modified) { + modifications.remove(last_row); + modifications.add(row_ndx); + } + else + modifications.remove(row_ndx); + + if (!track_moves) + return; + + bool row_is_insertion = insertions.contains(row_ndx); + bool last_is_insertion = !insertions.empty() && prev(insertions.end())->second == last_row + 1; + REALM_ASSERT_DEBUG(insertions.empty() || prev(insertions.end())->second <= last_row + 1); + + // Collapse A -> B, B -> C into a single A -> C move + bool last_was_already_moved = false; + if (last_is_insertion) { + auto it = m_move_mapping.find(last_row); + if (it != m_move_mapping.end() && it->first == last_row) { + m_move_mapping[row_ndx] = it->second; + m_move_mapping.erase(it); + last_was_already_moved = true; + } + } + + // Remove moves to the row being deleted + if (row_is_insertion && !last_was_already_moved) { + auto it = m_move_mapping.find(row_ndx); + if (it != m_move_mapping.end() && it->first == row_ndx) + m_move_mapping.erase(it); + } + + // Don't report deletions/moves if last_row is newly inserted + if (last_is_insertion) { + insertions.remove(last_row); + } + // If it was previously moved, the unshifted source row has already been marked as deleted + else if (!last_was_already_moved) { + auto shifted_last_row = insertions.unshift(last_row); + shifted_last_row = deletions.add_shifted(shifted_last_row); + m_move_mapping[row_ndx] = shifted_last_row; + } + + // Don't mark the moved-over row as deleted if it was a new insertion + if (!row_is_insertion) { + deletions.add_shifted(insertions.unshift(row_ndx)); + insertions.add(row_ndx); + } + verify(); +} + +void CollectionChangeBuilder::verify() +{ +#ifdef REALM_DEBUG + for (auto&& move : moves) { + REALM_ASSERT(deletions.contains(move.from)); + REALM_ASSERT(insertions.contains(move.to)); + } +#endif +} + +namespace { +struct RowInfo { + size_t row_index; + size_t prev_tv_index; + size_t tv_index; + size_t shifted_tv_index; +}; + +void calculate_moves_unsorted(std::vector& new_rows, IndexSet& removed, CollectionChangeSet& changeset) +{ + size_t expected = 0; + for (auto& row : new_rows) { + // With unsorted queries rows only move due to move_last_over(), which + // inherently can only move a row to earlier in the table. + REALM_ASSERT(row.shifted_tv_index >= expected); + if (row.shifted_tv_index == expected) { + ++expected; + continue; + } + + // This row isn't just the row after the previous one, but it still may + // not be a move if there were rows deleted between the two, so next + // calcuate what row should be here taking those in to account + size_t calc_expected = row.tv_index - changeset.insertions.count(0, row.tv_index) + removed.count(0, row.prev_tv_index); + if (row.shifted_tv_index == calc_expected) { + expected = calc_expected + 1; + continue; + } + + // The row still isn't the expected one, so it's a move + changeset.moves.push_back({row.prev_tv_index, row.tv_index}); + changeset.insertions.add(row.tv_index); + removed.add(row.prev_tv_index); + } +} + +class LongestCommonSubsequenceCalculator { +public: + // A pair of an index in the table and an index in the table view + struct Row { + size_t row_index; + size_t tv_index; + }; + + struct Match { + // The index in `a` at which this match begins + size_t i; + // The index in `b` at which this match begins + size_t j; + // The length of this match + size_t size; + // The number of rows in this block which were modified + size_t modified; + }; + std::vector m_longest_matches; + + LongestCommonSubsequenceCalculator(std::vector& a, std::vector& b, + size_t start_index, + IndexSet const& modifications) + : m_modified(modifications) + , a(a), b(b) + { + find_longest_matches(start_index, a.size(), + start_index, b.size()); + m_longest_matches.push_back({a.size(), b.size(), 0}); + } + +private: + IndexSet const& m_modified; + + // The two arrays of rows being diffed + // a is sorted by tv_index, b is sorted by row_index + std::vector &a, &b; + + // Find the longest matching range in (a + begin1, a + end1) and (b + begin2, b + end2) + // "Matching" is defined as "has the same row index"; the TV index is just + // there to let us turn an index in a/b into an index which can be reported + // in the output changeset. + // + // This is done with the O(N) space variant of the dynamic programming + // algorithm for longest common subsequence, where N is the maximum number + // of the most common row index (which for everything but linkview-derived + // TVs will be 1). + Match find_longest_match(size_t begin1, size_t end1, size_t begin2, size_t end2) + { + struct Length { + size_t j, len; + }; + // The length of the matching block for each `j` for the previously checked row + std::vector prev; + // The length of the matching block for each `j` for the row currently being checked + std::vector cur; + + // Calculate the length of the matching block *ending* at b[j], which + // is 1 if b[j - 1] did not match, and b[j - 1] + 1 otherwise. + auto length = [&](size_t j) -> size_t { + for (auto const& pair : prev) { + if (pair.j + 1 == j) + return pair.len + 1; + } + return 1; + }; + + // Iterate over each `j` which has the same row index as a[i] and falls + // within the range begin2 <= j < end2 + auto for_each_b_match = [&](size_t i, auto&& f) { + size_t ai = a[i].row_index; + // Find the TV indicies at which this row appears in the new results + // There should always be at least one (or it would have been + // filtered out earlier), but there can be multiple if there are dupes + auto it = lower_bound(begin(b), end(b), ai, + [](auto lft, auto rgt) { return lft.row_index < rgt; }); + REALM_ASSERT(it != end(b) && it->row_index == ai); + for (; it != end(b) && it->row_index == ai; ++it) { + size_t j = it->tv_index; + if (j < begin2) + continue; + if (j >= end2) + break; // b is sorted by tv_index so this can't transition from false to true + f(j); + } + }; + + Match best = {begin1, begin2, 0, 0}; + for (size_t i = begin1; i < end1; ++i) { + // prev = std::move(cur), but avoids discarding prev's heap allocation + cur.swap(prev); + cur.clear(); + + for_each_b_match(i, [&](size_t j) { + size_t size = length(j); + + cur.push_back({j, size}); + + // If the matching block ending at a[i] and b[j] is longer than + // the previous one, select it as the best + if (size > best.size) + best = {i - size + 1, j - size + 1, size, IndexSet::npos}; + // Given two equal-length matches, prefer the one with fewer modified rows + else if (size == best.size) { + if (best.modified == IndexSet::npos) + best.modified = m_modified.count(best.j - size + 1, best.j + 1); + auto count = m_modified.count(j - size + 1, j + 1); + if (count < best.modified) + best = {i - size + 1, j - size + 1, size, count}; + } + + // The best block should always fall within the range being searched + REALM_ASSERT(best.i >= begin1 && best.i + best.size <= end1); + REALM_ASSERT(best.j >= begin2 && best.j + best.size <= end2); + }); + } + return best; + } + + void find_longest_matches(size_t begin1, size_t end1, size_t begin2, size_t end2) + { + // FIXME: recursion could get too deep here + // recursion depth worst case is currently O(N) and each recursion uses 320 bytes of stack + // could reduce worst case to O(sqrt(N)) (and typical case to O(log N)) + // biasing equal selections towards the middle, but that's still + // insufficient for Android's 8 KB stacks + auto m = find_longest_match(begin1, end1, begin2, end2); + if (!m.size) + return; + if (m.i > begin1 && m.j > begin2) + find_longest_matches(begin1, m.i, begin2, m.j); + m_longest_matches.push_back(m); + if (m.i + m.size < end2 && m.j + m.size < end2) + find_longest_matches(m.i + m.size, end1, m.j + m.size, end2); + } +}; + +void calculate_moves_sorted(std::vector& rows, CollectionChangeSet& changeset) +{ + // The RowInfo array contains information about the old and new TV indices of + // each row, which we need to turn into two sequences of rows, which we'll + // then find matches in + std::vector a, b; + + a.reserve(rows.size()); + for (auto& row : rows) { + a.push_back({row.row_index, row.prev_tv_index}); + } + std::sort(begin(a), end(a), [](auto lft, auto rgt) { + return std::tie(lft.tv_index, lft.row_index) < std::tie(rgt.tv_index, rgt.row_index); + }); + + // Before constructing `b`, first find the first index in `a` which will + // actually differ in `b`, and skip everything else if there aren't any + size_t first_difference = IndexSet::npos; + for (size_t i = 0; i < a.size(); ++i) { + if (a[i].row_index != rows[i].row_index) { + first_difference = i; + break; + } + } + if (first_difference == IndexSet::npos) + return; + + // Note that `b` is sorted by row_index, while `a` is sorted by tv_index + b.reserve(rows.size()); + for (size_t i = 0; i < rows.size(); ++i) + b.push_back({rows[i].row_index, i}); + std::sort(begin(b), end(b), [](auto lft, auto rgt) { + return std::tie(lft.row_index, lft.tv_index) < std::tie(rgt.row_index, rgt.tv_index); + }); + + // Calculate the LCS of the two sequences + auto matches = LongestCommonSubsequenceCalculator(a, b, first_difference, + changeset.modifications).m_longest_matches; + + // And then insert and delete rows as needed to align them + size_t i = first_difference, j = first_difference; + for (auto match : matches) { + for (; i < match.i; ++i) + changeset.deletions.add(a[i].tv_index); + for (; j < match.j; ++j) + changeset.insertions.add(rows[j].tv_index); + i += match.size; + j += match.size; + } +} + +} // Anonymous namespace + +CollectionChangeBuilder CollectionChangeBuilder::calculate(std::vector const& prev_rows, + std::vector const& next_rows, + std::function row_did_change, + bool rows_are_in_table_order) +{ + REALM_ASSERT_DEBUG(!rows_are_in_table_order || std::is_sorted(begin(next_rows), end(next_rows))); + + CollectionChangeBuilder ret; + + size_t deleted = 0; + std::vector old_rows; + old_rows.reserve(prev_rows.size()); + for (size_t i = 0; i < prev_rows.size(); ++i) { + if (prev_rows[i] == IndexSet::npos) { + ++deleted; + ret.deletions.add(i); + } + else + old_rows.push_back({prev_rows[i], IndexSet::npos, i, i - deleted}); + } + std::sort(begin(old_rows), end(old_rows), [](auto& lft, auto& rgt) { + return lft.row_index < rgt.row_index; + }); + + std::vector new_rows; + new_rows.reserve(next_rows.size()); + for (size_t i = 0; i < next_rows.size(); ++i) { + new_rows.push_back({next_rows[i], IndexSet::npos, i, 0}); + } + std::sort(begin(new_rows), end(new_rows), [](auto& lft, auto& rgt) { + return lft.row_index < rgt.row_index; + }); + + // Don't add rows which were modified to not match the query to `deletions` + // immediately because the unsorted move logic needs to be able to + // distinguish them from rows which were outright deleted + IndexSet removed; + + // Now that our old and new sets of rows are sorted by row index, we can + // iterate over them and either record old+new TV indices for rows present + // in both, or mark them as inserted/deleted if they appear only in one + size_t i = 0, j = 0; + while (i < old_rows.size() && j < new_rows.size()) { + auto old_index = old_rows[i]; + auto new_index = new_rows[j]; + if (old_index.row_index == new_index.row_index) { + new_rows[j].prev_tv_index = old_rows[i].tv_index; + new_rows[j].shifted_tv_index = old_rows[i].shifted_tv_index; + ++i; + ++j; + } + else if (old_index.row_index < new_index.row_index) { + removed.add(old_index.tv_index); + ++i; + } + else { + ret.insertions.add(new_index.tv_index); + ++j; + } + } + + for (; i < old_rows.size(); ++i) + removed.add(old_rows[i].tv_index); + for (; j < new_rows.size(); ++j) + ret.insertions.add(new_rows[j].tv_index); + + // Filter out the new insertions since we don't need them for any of the + // further calculations + new_rows.erase(std::remove_if(begin(new_rows), end(new_rows), + [](auto& row) { return row.prev_tv_index == IndexSet::npos; }), + end(new_rows)); + std::sort(begin(new_rows), end(new_rows), + [](auto& lft, auto& rgt) { return lft.tv_index < rgt.tv_index; }); + + for (auto& row : new_rows) { + if (row_did_change(row.row_index)) { + ret.modifications.add(row.tv_index); + } + } + + if (!rows_are_in_table_order) { + calculate_moves_sorted(new_rows, ret); + } + else { + calculate_moves_unsorted(new_rows, removed, ret); + } + ret.deletions.add(removed); + ret.verify(); + +#ifdef REALM_DEBUG + { // Verify that applying the calculated change to prev_rows actually produces next_rows + auto rows = prev_rows; + auto it = util::make_reverse_iterator(ret.deletions.end()); + auto end = util::make_reverse_iterator(ret.deletions.begin()); + for (; it != end; ++it) { + rows.erase(rows.begin() + it->first, rows.begin() + it->second); + } + + for (auto i : ret.insertions.as_indexes()) { + rows.insert(rows.begin() + i, next_rows[i]); + } + + REALM_ASSERT(rows == next_rows); + } +#endif + + return ret; +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_notifier.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_notifier.cpp new file mode 100644 index 0000000..7751c3a --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/collection_notifier.cpp @@ -0,0 +1,344 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/collection_notifier.hpp" + +#include "impl/realm_coordinator.hpp" +#include "shared_realm.hpp" + +#include + +using namespace realm; +using namespace realm::_impl; + +std::function +CollectionNotifier::get_modification_checker(TransactionChangeInfo const& info, + Table const& root_table) +{ + // First check if any of the tables accessible from the root table were + // actually modified. This can be false if there were only insertions, or + // deletions which were not linked to by any row in the linking table + auto table_modified = [&](auto& tbl) { + return tbl.table_ndx < info.tables.size() + && !info.tables[tbl.table_ndx].modifications.empty(); + }; + if (!any_of(begin(m_related_tables), end(m_related_tables), table_modified)) { + return [](size_t) { return false; }; + } + + return DeepChangeChecker(info, root_table, m_related_tables); +} + +void DeepChangeChecker::find_related_tables(std::vector& out, Table const& table) +{ + auto table_ndx = table.get_index_in_group(); + if (any_of(begin(out), end(out), [=](auto& tbl) { return tbl.table_ndx == table_ndx; })) + return; + + // We need to add this table to `out` before recurring so that the check + // above works, but we can't store a pointer to the thing being populated + // because the recursive calls may resize `out`, so instead look it up by + // index every time + size_t out_index = out.size(); + out.push_back({table_ndx, {}}); + + for (size_t i = 0, count = table.get_column_count(); i != count; ++i) { + auto type = table.get_column_type(i); + if (type == type_Link || type == type_LinkList) { + out[out_index].links.push_back({i, type == type_LinkList}); + find_related_tables(out, *table.get_link_target(i)); + } + } +} + +DeepChangeChecker::DeepChangeChecker(TransactionChangeInfo const& info, + Table const& root_table, + std::vector const& related_tables) +: m_info(info) +, m_root_table(root_table) +, m_root_table_ndx(root_table.get_index_in_group()) +, m_root_modifications(m_root_table_ndx < info.tables.size() ? &info.tables[m_root_table_ndx].modifications : nullptr) +, m_related_tables(related_tables) +{ +} + +bool DeepChangeChecker::check_outgoing_links(size_t table_ndx, + Table const& table, + size_t row_ndx, size_t depth) +{ + auto it = find_if(begin(m_related_tables), end(m_related_tables), + [&](auto&& tbl) { return tbl.table_ndx == table_ndx; }); + if (it == m_related_tables.end()) + return false; + + // Check if we're already checking if the destination of the link is + // modified, and if not add it to the stack + auto already_checking = [&](size_t col) { + for (auto p = m_current_path.begin(); p < m_current_path.begin() + depth; ++p) { + if (p->table == table_ndx && p->row == row_ndx && p->col == col) + return true; + } + m_current_path[depth] = {table_ndx, row_ndx, col, false}; + return false; + }; + + for (auto const& link : it->links) { + if (already_checking(link.col_ndx)) + continue; + if (!link.is_list) { + if (table.is_null_link(link.col_ndx, row_ndx)) + continue; + auto dst = table.get_link(link.col_ndx, row_ndx); + return check_row(*table.get_link_target(link.col_ndx), dst, depth + 1); + } + + auto& target = *table.get_link_target(link.col_ndx); + auto lvr = table.get_linklist(link.col_ndx, row_ndx); + for (size_t j = 0, size = lvr->size(); j < size; ++j) { + size_t dst = lvr->get(j).get_index(); + if (check_row(target, dst, depth + 1)) + return true; + } + } + + return false; +} + +bool DeepChangeChecker::check_row(Table const& table, size_t idx, size_t depth) +{ + // Arbitrary upper limit on the maximum depth to search + if (depth >= m_current_path.size()) { + // Don't mark any of the intermediate rows checked along the path as + // not modified, as a search starting from them might hit a modification + for (size_t i = 1; i < m_current_path.size(); ++i) + m_current_path[i].depth_exceeded = true; + return false; + } + + size_t table_ndx = table.get_index_in_group(); + if (depth > 0 && table_ndx < m_info.tables.size() && m_info.tables[table_ndx].modifications.contains(idx)) + return true; + + if (m_not_modified.size() <= table_ndx) + m_not_modified.resize(table_ndx + 1); + if (m_not_modified[table_ndx].contains(idx)) + return false; + + bool ret = check_outgoing_links(table_ndx, table, idx, depth); + if (!ret && !m_current_path[depth].depth_exceeded) + m_not_modified[table_ndx].add(idx); + return ret; +} + +bool DeepChangeChecker::operator()(size_t ndx) +{ + if (m_root_modifications && m_root_modifications->contains(ndx)) + return true; + return check_row(m_root_table, ndx, 0); +} + +CollectionNotifier::CollectionNotifier(std::shared_ptr realm) +: m_realm(std::move(realm)) +, m_sg_version(Realm::Internal::get_shared_group(*m_realm).get_version_of_current_transaction()) +{ +} + +CollectionNotifier::~CollectionNotifier() +{ + // Need to do this explicitly to ensure m_realm is destroyed with the mutex + // held to avoid potential double-deletion + unregister(); +} + +size_t CollectionNotifier::add_callback(CollectionChangeCallback callback) +{ + m_realm->verify_thread(); + + auto next_token = [=] { + size_t token = 0; + for (auto& callback : m_callbacks) { + if (token <= callback.token) { + token = callback.token + 1; + } + } + return token; + }; + + std::lock_guard lock(m_callback_mutex); + auto token = next_token(); + m_callbacks.push_back({std::move(callback), token, false}); + if (m_callback_index == npos) { // Don't need to wake up if we're already sending notifications + Realm::Internal::get_coordinator(*m_realm).send_commit_notifications(); + m_have_callbacks = true; + } + return token; +} + +void CollectionNotifier::remove_callback(size_t token) +{ + Callback old; + { + std::lock_guard lock(m_callback_mutex); + REALM_ASSERT(m_error || m_callbacks.size() > 0); + + auto it = find_if(begin(m_callbacks), end(m_callbacks), + [=](const auto& c) { return c.token == token; }); + // We should only fail to find the callback if it was removed due to an error + REALM_ASSERT(m_error || it != end(m_callbacks)); + if (it == end(m_callbacks)) { + return; + } + + size_t idx = distance(begin(m_callbacks), it); + if (m_callback_index != npos && m_callback_index >= idx) { + --m_callback_index; + } + + old = std::move(*it); + m_callbacks.erase(it); + + m_have_callbacks = !m_callbacks.empty(); + } +} + +void CollectionNotifier::unregister() noexcept +{ + std::lock_guard lock(m_realm_mutex); + m_realm = nullptr; +} + +bool CollectionNotifier::is_alive() const noexcept +{ + std::lock_guard lock(m_realm_mutex); + return m_realm != nullptr; +} + +std::unique_lock CollectionNotifier::lock_target() +{ + return std::unique_lock{m_realm_mutex}; +} + +void CollectionNotifier::set_table(Table const& table) +{ + m_related_tables.clear(); + DeepChangeChecker::find_related_tables(m_related_tables, table); +} + +void CollectionNotifier::add_required_change_info(TransactionChangeInfo& info) +{ + if (!do_add_required_change_info(info)) { + return; + } + + auto max = max_element(begin(m_related_tables), end(m_related_tables), + [](auto&& a, auto&& b) { return a.table_ndx < b.table_ndx; }); + + if (max->table_ndx >= info.table_modifications_needed.size()) + info.table_modifications_needed.resize(max->table_ndx + 1, false); + for (auto& tbl : m_related_tables) { + info.table_modifications_needed[tbl.table_ndx] = true; + } +} + +void CollectionNotifier::prepare_handover() +{ + REALM_ASSERT(m_sg); + m_sg_version = m_sg->get_version_of_current_transaction(); + do_prepare_handover(*m_sg); +} + +bool CollectionNotifier::deliver(Realm& realm, SharedGroup& sg, std::exception_ptr err) +{ + { + std::lock_guard lock(m_realm_mutex); + if (m_realm.get() != &realm) { + return false; + } + } + + if (err) { + m_error = err; + return have_callbacks(); + } + + auto realm_sg_version = sg.get_version_of_current_transaction(); + if (version() != realm_sg_version) { + // Realm version can be newer if a commit was made on our thread or the + // user manually called refresh(), or older if a commit was made on a + // different thread and we ran *really* fast in between the check for + // if the shared group has changed and when we pick up async results + return false; + } + + bool should_call_callbacks = do_deliver(sg); + m_changes_to_deliver = std::move(m_accumulated_changes); + + // fixup modifications to be source rows rather than dest rows + // FIXME: the actual change calculations should be updated to just calculate + // the correct thing instead + m_changes_to_deliver.modifications.erase_at(m_changes_to_deliver.insertions); + m_changes_to_deliver.modifications.shift_for_insert_at(m_changes_to_deliver.deletions); + + return should_call_callbacks && have_callbacks(); +} + +void CollectionNotifier::call_callbacks() +{ + while (auto fn = next_callback()) { + fn(m_changes_to_deliver, m_error); + } + + if (m_error) { + // Remove all the callbacks as we never need to call anything ever again + // after delivering an error + std::lock_guard callback_lock(m_callback_mutex); + m_callbacks.clear(); + } +} + +CollectionChangeCallback CollectionNotifier::next_callback() +{ + std::lock_guard callback_lock(m_callback_mutex); + + for (++m_callback_index; m_callback_index < m_callbacks.size(); ++m_callback_index) { + auto& callback = m_callbacks[m_callback_index]; + if (!m_error && callback.initial_delivered && m_changes_to_deliver.empty()) { + continue; + } + callback.initial_delivered = true; + return callback.fn; + } + + m_callback_index = npos; + return nullptr; +} + +void CollectionNotifier::attach_to(SharedGroup& sg) +{ + REALM_ASSERT(!m_sg); + + m_sg = &sg; + do_attach_to(sg); +} + +void CollectionNotifier::detach() +{ + REALM_ASSERT(m_sg); + do_detach_from(*m_sg); + m_sg = nullptr; +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/handover.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/handover.cpp new file mode 100644 index 0000000..41a8a0e --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/handover.cpp @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/handover.hpp" + +using namespace realm; +using namespace realm::_impl; + +AnyHandover::AnyHandover(AnyHandover&& handover) +{ + switch (handover.m_type) { + case AnyThreadConfined::Type::Object: + new (&m_object.row_handover) RowHandover(std::move(handover.m_object.row_handover)); + new (&m_object.object_schema_name) std::string(std::move(handover.m_object.object_schema_name)); + break; + + case AnyThreadConfined::Type::List: + new (&m_list.link_view_handover) LinkViewHandover(std::move(handover.m_list.link_view_handover)); + break; + + case AnyThreadConfined::Type::Results: + new (&m_results.query_handover) QueryHandover(std::move(handover.m_results.query_handover)); + new (&m_results.sort_order) SortDescriptor::HandoverPatch(std::move(handover.m_results.sort_order)); + break; + } + new (&m_type) AnyThreadConfined::Type(handover.m_type); +} + +AnyHandover& AnyHandover::operator=(AnyHandover&& handover) +{ + this->~AnyHandover(); + new (this) AnyHandover(std::move(handover)); + return *this; +} + +AnyHandover::~AnyHandover() +{ + switch (m_type) { + case AnyThreadConfined::Type::Object: + m_object.row_handover.~unique_ptr(); + break; + + case AnyThreadConfined::Type::List: + m_list.link_view_handover.~unique_ptr(); + break; + + case AnyThreadConfined::Type::Results: + m_results.query_handover.~unique_ptr(); + m_results.sort_order.~unique_ptr(); + break; + } +} + +AnyThreadConfined AnyHandover::import_from_handover(SharedRealm realm) && +{ + SharedGroup& shared_group = Realm::Internal::get_shared_group(*realm); + switch (m_type) { + case AnyThreadConfined::Type::Object: { + auto row = shared_group.import_from_handover(std::move(m_object.row_handover)); + auto object_schema = realm->schema().find(m_object.object_schema_name); + REALM_ASSERT_DEBUG(object_schema != realm->schema().end()); + return AnyThreadConfined(Object(std::move(realm), *object_schema, std::move(*row))); + } + case AnyThreadConfined::Type::List: { + auto link_view_ref = shared_group.import_linkview_from_handover(std::move(m_list.link_view_handover)); + return AnyThreadConfined(List(std::move(realm), std::move(link_view_ref))); + } + case AnyThreadConfined::Type::Results: { + auto query = shared_group.import_from_handover(std::move(m_results.query_handover)); + auto& table = *query->get_table(); + return AnyThreadConfined(Results(std::move(realm), std::move(*query), + SortDescriptor::create_from_and_consume_patch(m_results.sort_order, table))); + } + } + REALM_UNREACHABLE(); +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/list_notifier.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/list_notifier.cpp new file mode 100644 index 0000000..beec1d5 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/list_notifier.cpp @@ -0,0 +1,119 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/list_notifier.hpp" + +#include "shared_realm.hpp" + +#include + +using namespace realm; +using namespace realm::_impl; + +ListNotifier::ListNotifier(LinkViewRef lv, std::shared_ptr realm) +: CollectionNotifier(std::move(realm)) +, m_prev_size(lv->size()) +{ + set_table(lv->get_target_table()); + + auto& sg = Realm::Internal::get_shared_group(*get_realm()); + m_lv_handover = sg.export_linkview_for_handover(lv); +} + +void ListNotifier::release_data() noexcept +{ + m_lv.reset(); +} + +void ListNotifier::do_attach_to(SharedGroup& sg) +{ + REALM_ASSERT(m_lv_handover); + REALM_ASSERT(!m_lv); + m_lv = sg.import_linkview_from_handover(std::move(m_lv_handover)); +} + +void ListNotifier::do_detach_from(SharedGroup& sg) +{ + REALM_ASSERT(!m_lv_handover); + if (m_lv) { + m_lv_handover = sg.export_linkview_for_handover(m_lv); + m_lv = {}; + } +} + +bool ListNotifier::do_add_required_change_info(TransactionChangeInfo& info) +{ + REALM_ASSERT(!m_lv_handover); + if (!m_lv || !m_lv->is_attached()) { + return false; // origin row was deleted after the notification was added + } + + // Find the lv's column, since that isn't tracked directly + auto& table = m_lv->get_origin_table(); + size_t row_ndx = m_lv->get_origin_row_index(); + size_t col_ndx = not_found; + for (size_t i = 0, count = table.get_column_count(); i != count; ++i) { + if (table.get_column_type(i) == type_LinkList && table.get_linklist(i, row_ndx) == m_lv) { + col_ndx = i; + break; + } + } + REALM_ASSERT(col_ndx != not_found); + info.lists.push_back({table.get_index_in_group(), row_ndx, col_ndx, &m_change}); + + m_info = &info; + return true; +} + +void ListNotifier::run() +{ + if (!m_lv || !m_lv->is_attached()) { + // LV was deleted, so report all of the rows being removed if this is + // the first run after that + if (m_prev_size) { + m_change.deletions.set(m_prev_size); + m_prev_size = 0; + } + else { + m_change = {}; + } + return; + } + + auto row_did_change = get_modification_checker(*m_info, m_lv->get_target_table()); + for (size_t i = 0; i < m_lv->size(); ++i) { + if (m_change.modifications.contains(i)) + continue; + if (row_did_change(m_lv->get(i).get_index())) + m_change.modifications.add(i); + } + + for (auto const& move : m_change.moves) { + if (m_change.modifications.contains(move.to)) + continue; + if (row_did_change(m_lv->get(move.to).get_index())) + m_change.modifications.add(move.to); + } + + m_prev_size = m_lv->size(); +} + +void ListNotifier::do_prepare_handover(SharedGroup&) +{ + add_changes(std::move(m_change)); +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/realm_coordinator.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/realm_coordinator.cpp new file mode 100644 index 0000000..0258d21 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/realm_coordinator.cpp @@ -0,0 +1,603 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/realm_coordinator.hpp" + +#include "impl/collection_notifier.hpp" +#include "impl/external_commit_helper.hpp" +#include "impl/transact_log_handler.hpp" +#include "impl/weak_realm_notifier.hpp" +#include "object_schema.hpp" +#include "object_store.hpp" +#include "schema.hpp" + +#include +#include +#include +#include + +#include +#include + +using namespace realm; +using namespace realm::_impl; + +static std::mutex s_coordinator_mutex; +static std::unordered_map> s_coordinators_per_path; + +std::shared_ptr RealmCoordinator::get_coordinator(StringData path) +{ + std::lock_guard lock(s_coordinator_mutex); + + auto& weak_coordinator = s_coordinators_per_path[path]; + if (auto coordinator = weak_coordinator.lock()) { + return coordinator; + } + + auto coordinator = std::make_shared(); + weak_coordinator = coordinator; + return coordinator; +} + +std::shared_ptr RealmCoordinator::get_existing_coordinator(StringData path) +{ + std::lock_guard lock(s_coordinator_mutex); + auto it = s_coordinators_per_path.find(path); + return it == s_coordinators_per_path.end() ? nullptr : it->second.lock(); +} + +std::shared_ptr RealmCoordinator::get_realm(Realm::Config config) +{ + std::lock_guard lock(m_realm_mutex); + if ((!m_config.read_only() && !m_notifier) || (m_config.read_only() && m_weak_realm_notifiers.empty())) { + m_config = config; + } + else { + if (m_config.read_only() != config.read_only()) { + throw MismatchedConfigException("Realm at path '%1' already opened with different read permissions.", config.path); + } + if (m_config.in_memory != config.in_memory) { + throw MismatchedConfigException("Realm at path '%1' already opened with different inMemory settings.", config.path); + } + if (m_config.encryption_key != config.encryption_key) { + throw MismatchedConfigException("Realm at path '%1' already opened with a different encryption key.", config.path); + } + if (m_config.schema_mode != config.schema_mode) { + throw MismatchedConfigException("Realm at path '%1' already opened with a different schema mode.", config.path); + } + if (m_config.schema_version != config.schema_version && config.schema_version != ObjectStore::NotVersioned) { + throw MismatchedConfigException("Realm at path '%1' already opened with different schema version.", config.path); + } + // Realm::update_schema() handles complaining about schema mismatches + } + + if (config.cache) { + for (auto& cached_realm : m_weak_realm_notifiers) { + if (cached_realm.is_cached_for_current_thread()) { + // can be null if we jumped in between ref count hitting zero and + // unregister_realm() getting the lock + if (auto realm = cached_realm.realm()) { + return realm; + } + } + } + } + + auto realm = Realm::make_shared_realm(std::move(config)); + if (!config.read_only() && !m_notifier && config.automatic_change_notifications) { + try { + m_notifier = std::make_unique(*this); + } + catch (std::system_error const& ex) { + throw RealmFileException(RealmFileException::Kind::AccessError, config.path, ex.code().message(), ""); + } + } + realm->init(shared_from_this()); + + m_weak_realm_notifiers.emplace_back(realm, m_config.cache); + return realm; +} + +std::shared_ptr RealmCoordinator::get_realm() +{ + return get_realm(m_config); +} + +const Schema* RealmCoordinator::get_schema() const noexcept +{ + return m_schema_version == uint64_t(-1) ? nullptr : &m_schema; +} + +void RealmCoordinator::update_schema(Schema const& schema, uint64_t schema_version) +{ + if (m_schema_version != uint64_t(-1) && m_schema_version != schema_version && m_weak_realm_notifiers.size() > 1) { + throw MismatchedConfigException("Realm at path '%1' already opened with a different schema version.", m_config.path); + } + + m_schema = schema; + m_schema_version = schema_version; + + // FIXME: notify realms of the schema change +} + +RealmCoordinator::RealmCoordinator() = default; + +RealmCoordinator::~RealmCoordinator() +{ + std::lock_guard coordinator_lock(s_coordinator_mutex); + for (auto it = s_coordinators_per_path.begin(); it != s_coordinators_per_path.end(); ) { + if (it->second.expired()) { + it = s_coordinators_per_path.erase(it); + } + else { + ++it; + } + } +} + +void RealmCoordinator::unregister_realm(Realm* realm) +{ + std::lock_guard lock(m_realm_mutex); + auto new_end = remove_if(begin(m_weak_realm_notifiers), end(m_weak_realm_notifiers), + [=](auto& notifier) { return notifier.expired() || notifier.is_for_realm(realm); }); + m_weak_realm_notifiers.erase(new_end, end(m_weak_realm_notifiers)); +} + +void RealmCoordinator::clear_cache() +{ + std::vector realms_to_close; + { + std::lock_guard lock(s_coordinator_mutex); + + for (auto& weak_coordinator : s_coordinators_per_path) { + auto coordinator = weak_coordinator.second.lock(); + if (!coordinator) { + continue; + } + + coordinator->m_notifier = nullptr; + + // Gather a list of all of the realms which will be removed + for (auto& weak_realm_notifier : coordinator->m_weak_realm_notifiers) { + if (auto realm = weak_realm_notifier.realm()) { + realms_to_close.push_back(realm); + } + } + } + + s_coordinators_per_path.clear(); + } + + // Close all of the previously cached Realms. This can't be done while + // s_coordinator_mutex is held as it may try to re-lock it. + for (auto& weak_realm : realms_to_close) { + if (auto realm = weak_realm.lock()) { + realm->close(); + } + } +} + +void RealmCoordinator::clear_all_caches() +{ + std::vector> to_clear; + { + std::lock_guard lock(s_coordinator_mutex); + for (auto iter : s_coordinators_per_path) { + to_clear.push_back(iter.second); + } + } + for (auto weak_coordinator : to_clear) { + if (auto coordinator = weak_coordinator.lock()) { + coordinator->clear_cache(); + } + } +} + +void RealmCoordinator::send_commit_notifications() +{ + REALM_ASSERT(!m_config.read_only()); + if (m_notifier) { + m_notifier->notify_others(); + } +} + +void RealmCoordinator::pin_version(uint_fast64_t version, uint_fast32_t index) +{ + if (m_async_error) { + return; + } + + SharedGroup::VersionID versionid(version, index); + if (!m_advancer_sg) { + try { + std::unique_ptr read_only_group; + Realm::open_with_config(m_config, m_advancer_history, m_advancer_sg, read_only_group, nullptr); + REALM_ASSERT(!read_only_group); + m_advancer_sg->begin_read(versionid); + } + catch (...) { + m_async_error = std::current_exception(); + m_advancer_sg = nullptr; + m_advancer_history = nullptr; + } + } + else if (m_new_notifiers.empty()) { + // If this is the first notifier then we don't already have a read transaction + REALM_ASSERT_3(m_advancer_sg->get_transact_stage(), ==, SharedGroup::transact_Ready); + m_advancer_sg->begin_read(versionid); + } + else { + REALM_ASSERT_3(m_advancer_sg->get_transact_stage(), ==, SharedGroup::transact_Reading); + if (versionid < m_advancer_sg->get_version_of_current_transaction()) { + // Ensure we're holding a readlock on the oldest version we have a + // handover object for, as handover objects don't + m_advancer_sg->end_read(); + m_advancer_sg->begin_read(versionid); + } + } +} + +void RealmCoordinator::register_notifier(std::shared_ptr notifier) +{ + auto version = notifier->version(); + auto& self = Realm::Internal::get_coordinator(*notifier->get_realm()); + { + std::lock_guard lock(self.m_notifier_mutex); + self.pin_version(version.version, version.index); + self.m_new_notifiers.push_back(std::move(notifier)); + } +} + +void RealmCoordinator::clean_up_dead_notifiers() +{ + auto swap_remove = [&](auto& container) { + bool did_remove = false; + for (size_t i = 0; i < container.size(); ++i) { + if (container[i]->is_alive()) + continue; + + // Ensure the notifier is destroyed here even if there's lingering refs + // to the async notifier elsewhere + container[i]->release_data(); + + if (container.size() > i + 1) + container[i] = std::move(container.back()); + container.pop_back(); + --i; + did_remove = true; + } + return did_remove; + }; + + if (swap_remove(m_notifiers)) { + // Make sure we aren't holding on to read versions needlessly if there + // are no notifiers left, but don't close them entirely as opening shared + // groups is expensive + if (m_notifiers.empty() && m_notifier_sg) { + REALM_ASSERT_3(m_notifier_sg->get_transact_stage(), ==, SharedGroup::transact_Reading); + m_notifier_sg->end_read(); + } + } + if (swap_remove(m_new_notifiers)) { + REALM_ASSERT_3(m_advancer_sg->get_transact_stage(), ==, SharedGroup::transact_Reading); + if (m_new_notifiers.empty() && m_advancer_sg) { + m_advancer_sg->end_read(); + } + } +} + +void RealmCoordinator::on_change() +{ + run_async_notifiers(); + + std::lock_guard lock(m_realm_mutex); + for (auto& realm : m_weak_realm_notifiers) { + realm.notify(); + } +} + +namespace { +class IncrementalChangeInfo { +public: + IncrementalChangeInfo(SharedGroup& sg, + SchemaMode schema_mode, + std::vector>& notifiers) + : m_sg(sg), m_schema_mode(schema_mode) + { + if (notifiers.empty()) + return; + + auto cmp = [&](auto&& lft, auto&& rgt) { + return lft->version() < rgt->version(); + }; + + // Sort the notifiers by their source version so that we can pull them + // all forward to the latest version in a single pass over the transaction log + std::sort(notifiers.begin(), notifiers.end(), cmp); + + // Preallocate the required amount of space in the vector so that we can + // safely give out pointers to within the vector + size_t count = 1; + for (auto it = notifiers.begin(), next = it + 1; next != notifiers.end(); ++it, ++next) { + if (cmp(*it, *next)) + ++count; + } + m_info.reserve(count); + m_info.resize(1); + m_current = &m_info[0]; + } + + TransactionChangeInfo& current() const { return *m_current; } + + bool advance_incremental(SharedGroup::VersionID version) + { + if (version != m_sg.get_version_of_current_transaction()) { + transaction::advance(m_sg, *m_current, version); + m_info.push_back({ + m_current->table_modifications_needed, + m_current->table_moves_needed, + std::move(m_current->lists)}); + m_current = &m_info.back(); + return true; + } + return false; + } + + void advance_to_final(SharedGroup::VersionID version) + { + if (!m_current) { + transaction::advance(m_sg, nullptr, m_schema_mode, version); + return; + } + + transaction::advance(m_sg, *m_current, version); + + // We now need to combine the transaction change info objects so that all of + // the notifiers see the complete set of changes from their first version to + // the most recent one + for (size_t i = m_info.size() - 1; i > 0; --i) { + auto& cur = m_info[i]; + if (cur.tables.empty()) + continue; + auto& prev = m_info[i - 1]; + if (prev.tables.empty()) { + prev.tables = cur.tables; + continue; + } + + for (size_t j = 0; j < prev.tables.size() && j < cur.tables.size(); ++j) { + prev.tables[j].merge(CollectionChangeBuilder{cur.tables[j]}); + } + prev.tables.reserve(cur.tables.size()); + while (prev.tables.size() < cur.tables.size()) { + prev.tables.push_back(cur.tables[prev.tables.size()]); + } + } + + // Copy the list change info if there are multiple LinkViews for the same LinkList + auto id = [](auto const& list) { return std::tie(list.table_ndx, list.col_ndx, list.row_ndx); }; + for (size_t i = 1; i < m_current->lists.size(); ++i) { + for (size_t j = i; j > 0; --j) { + if (id(m_current->lists[i]) == id(m_current->lists[j - 1])) { + m_current->lists[j - 1].changes->merge(CollectionChangeBuilder{*m_current->lists[i].changes}); + } + } + } + } + +private: + std::vector m_info; + TransactionChangeInfo* m_current = nullptr; + SharedGroup& m_sg; + SchemaMode m_schema_mode; +}; +} // anonymous namespace + +void RealmCoordinator::run_async_notifiers() +{ + std::unique_lock lock(m_notifier_mutex); + + clean_up_dead_notifiers(); + + if (m_notifiers.empty() && m_new_notifiers.empty()) { + return; + } + + if (!m_async_error) { + open_helper_shared_group(); + } + + if (m_async_error) { + std::move(m_new_notifiers.begin(), m_new_notifiers.end(), std::back_inserter(m_notifiers)); + m_new_notifiers.clear(); + return; + } + + SharedGroup::VersionID version; + + // Advance all of the new notifiers to the most recent version, if any + auto new_notifiers = std::move(m_new_notifiers); + IncrementalChangeInfo new_notifier_change_info(*m_advancer_sg, m_config.schema_mode, new_notifiers); + + if (!new_notifiers.empty()) { + REALM_ASSERT_3(m_advancer_sg->get_transact_stage(), ==, SharedGroup::transact_Reading); + REALM_ASSERT_3(m_advancer_sg->get_version_of_current_transaction().version, + <=, new_notifiers.front()->version().version); + + // The advancer SG can be at an older version than the oldest new notifier + // if a notifier was added and then removed before it ever got the chance + // to run, as we don't move the pin forward when removing dead notifiers + transaction::advance(*m_advancer_sg, nullptr, m_config.schema_mode, new_notifiers.front()->version()); + + // Advance each of the new notifiers to the latest version, attaching them + // to the SG at their handover version. This requires a unique + // TransactionChangeInfo for each source version, so that things don't + // see changes from before the version they were handed over from. + // Each Info has all of the changes between that source version and the + // next source version, and they'll be merged together later after + // releasing the lock + for (auto& notifier : new_notifiers) { + new_notifier_change_info.advance_incremental(notifier->version()); + notifier->attach_to(*m_advancer_sg); + notifier->add_required_change_info(new_notifier_change_info.current()); + } + new_notifier_change_info.advance_to_final(SharedGroup::VersionID{}); + + for (auto& notifier : new_notifiers) { + notifier->detach(); + } + version = m_advancer_sg->get_version_of_current_transaction(); + m_advancer_sg->end_read(); + } + REALM_ASSERT_3(m_advancer_sg->get_transact_stage(), ==, SharedGroup::transact_Ready); + + // Make a copy of the notifiers vector and then release the lock to avoid + // blocking other threads trying to register or unregister notifiers while we run them + auto notifiers = m_notifiers; + lock.unlock(); + + // Advance the non-new notifiers to the same version as we advanced the new + // ones to (or the latest if there were no new ones) + IncrementalChangeInfo change_info(*m_notifier_sg, m_config.schema_mode, notifiers); + for (auto& notifier : notifiers) { + notifier->add_required_change_info(change_info.current()); + } + change_info.advance_to_final(version); + + // Attach the new notifiers to the main SG and move them to the main list + for (auto& notifier : new_notifiers) { + notifier->attach_to(*m_notifier_sg); + } + std::move(new_notifiers.begin(), new_notifiers.end(), std::back_inserter(notifiers)); + + // Change info is now all ready, so the notifiers can now perform their + // background work + for (auto& notifier : notifiers) { + notifier->run(); + } + + // Reacquire the lock while updating the fields that are actually read on + // other threads + lock.lock(); + for (auto& notifier : notifiers) { + notifier->prepare_handover(); + } + m_notifiers = std::move(notifiers); + clean_up_dead_notifiers(); +} + +void RealmCoordinator::open_helper_shared_group() +{ + if (!m_notifier_sg) { + try { + std::unique_ptr read_only_group; + Realm::open_with_config(m_config, m_notifier_history, m_notifier_sg, read_only_group, nullptr); + REALM_ASSERT(!read_only_group); + m_notifier_sg->begin_read(); + } + catch (...) { + // Store the error to be passed to the async notifiers + m_async_error = std::current_exception(); + m_notifier_sg = nullptr; + m_notifier_history = nullptr; + } + } + else if (m_notifiers.empty()) { + m_notifier_sg->begin_read(); + } +} + +void RealmCoordinator::advance_to_ready(Realm& realm) +{ + decltype(m_notifiers) notifiers; + + auto& sg = Realm::Internal::get_shared_group(realm); + + auto get_notifier_version = [&] { + for (auto& notifier : m_notifiers) { + auto version = notifier->version(); + if (version != SharedGroup::VersionID{}) { + return version; + } + } + return SharedGroup::VersionID{}; + }; + + SharedGroup::VersionID version; + { + std::lock_guard lock(m_notifier_mutex); + version = get_notifier_version(); + } + + // no async notifiers; just advance to latest + if (version.version == std::numeric_limits::max()) { + transaction::advance(sg, realm.m_binding_context.get(), m_config.schema_mode); + return; + } + + // async results are out of date; ignore + if (version < sg.get_version_of_current_transaction()) { + return; + } + + while (true) { + // Advance to the ready version without holding any locks because it + // may end up calling user code (in did_change() notifications) + transaction::advance(sg, realm.m_binding_context.get(), m_config.schema_mode, version); + + // Reacquire the lock and recheck the notifier version, as the notifiers may + // have advanced to a later version while we didn't hold the lock. If + // so, we need to release the lock and re-advance + std::lock_guard lock(m_notifier_mutex); + version = get_notifier_version(); + if (version.version == std::numeric_limits::max()) + return; + if (version != sg.get_version_of_current_transaction()) + continue; + + // Query version now matches the SG version, so we can deliver them + for (auto& notifier : m_notifiers) { + if (notifier->deliver(realm, sg, m_async_error)) { + notifiers.push_back(notifier); + } + } + break; + } + + for (auto& notifier : notifiers) { + notifier->call_callbacks(); + } +} + +void RealmCoordinator::process_available_async(Realm& realm) +{ + auto& sg = Realm::Internal::get_shared_group(realm); + decltype(m_notifiers) notifiers; + { + std::lock_guard lock(m_notifier_mutex); + for (auto& notifier : m_notifiers) { + if (notifier->deliver(realm, sg, m_async_error)) { + notifiers.push_back(notifier); + } + } + } + + for (auto& notifier : notifiers) { + notifier->call_callbacks(); + } +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/results_notifier.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/results_notifier.cpp new file mode 100644 index 0000000..70645ee --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/results_notifier.cpp @@ -0,0 +1,219 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/results_notifier.hpp" + +using namespace realm; +using namespace realm::_impl; + +ResultsNotifier::ResultsNotifier(Results& target) +: CollectionNotifier(target.get_realm()) +, m_target_results(&target) +, m_target_is_in_table_order(target.is_in_table_order()) +{ + Query q = target.get_query(); + set_table(*q.get_table()); + m_query_handover = Realm::Internal::get_shared_group(*get_realm()).export_for_handover(q, MutableSourcePayload::Move); + SortDescriptor::generate_patch(target.get_sort(), m_sort_handover); +} + +void ResultsNotifier::target_results_moved(Results& old_target, Results& new_target) +{ + auto lock = lock_target(); + + REALM_ASSERT(m_target_results == &old_target); + m_target_results = &new_target; +} + +void ResultsNotifier::release_data() noexcept +{ + m_query = nullptr; +} + +// Most of the inter-thread synchronization for run(), prepare_handover(), +// attach_to(), detach(), release_data() and deliver() is done by +// RealmCoordinator external to this code, which has some potentially +// non-obvious results on which members are and are not safe to use without +// holding a lock. +// +// add_required_change_info(), attach_to(), detach(), run(), +// prepare_handover(), and release_data() are all only ever called on a single +// background worker thread. call_callbacks() and deliver() are called on the +// target thread. Calls to prepare_handover() and deliver() are guarded by a +// lock. +// +// In total, this means that the safe data flow is as follows: +// - add_Required_change_info(), prepare_handover(), attach_to(), detach() and +// release_data() can read members written by each other +// - deliver() can read members written to in prepare_handover(), deliver(), +// and call_callbacks() +// - call_callbacks() and read members written to in deliver() +// +// Separately from the handover data flow, m_target_results is guarded by the target lock + +bool ResultsNotifier::do_add_required_change_info(TransactionChangeInfo& info) +{ + REALM_ASSERT(m_query); + m_info = &info; + + auto table_ndx = m_query->get_table()->get_index_in_group(); + if (info.table_moves_needed.size() <= table_ndx) + info.table_moves_needed.resize(table_ndx + 1); + info.table_moves_needed[table_ndx] = true; + + return m_initial_run_complete && have_callbacks(); +} + +bool ResultsNotifier::need_to_run() +{ + REALM_ASSERT(m_info); + REALM_ASSERT(!m_tv.is_attached()); + + { + auto lock = lock_target(); + // Don't run the query if the results aren't actually going to be used + if (!get_realm() || (!have_callbacks() && !m_target_results->wants_background_updates())) { + return false; + } + } + + // If we've run previously, check if we need to rerun + if (m_initial_run_complete && m_query->sync_view_if_needed() == m_last_seen_version) { + return false; + } + + return true; +} + +void ResultsNotifier::calculate_changes() +{ + size_t table_ndx = m_query->get_table()->get_index_in_group(); + if (m_initial_run_complete) { + auto changes = table_ndx < m_info->tables.size() ? &m_info->tables[table_ndx] : nullptr; + + std::vector next_rows; + next_rows.reserve(m_tv.size()); + for (size_t i = 0; i < m_tv.size(); ++i) + next_rows.push_back(m_tv[i].get_index()); + + if (changes) { + auto const& moves = changes->moves; + for (auto& idx : m_previous_rows) { + auto it = lower_bound(begin(moves), end(moves), idx, + [](auto const& a, auto b) { return a.from < b; }); + if (it != moves.end() && it->from == idx) + idx = it->to; + else if (changes->deletions.contains(idx)) + idx = npos; + else + REALM_ASSERT_DEBUG(!changes->insertions.contains(idx)); + } + } + + m_changes = CollectionChangeBuilder::calculate(m_previous_rows, next_rows, + get_modification_checker(*m_info, *m_query->get_table()), + m_target_is_in_table_order && !m_sort); + + m_previous_rows = std::move(next_rows); + } + else { + m_previous_rows.resize(m_tv.size()); + for (size_t i = 0; i < m_tv.size(); ++i) + m_previous_rows[i] = m_tv[i].get_index(); + } +} + +void ResultsNotifier::run() +{ + if (!need_to_run()) + return; + + m_query->sync_view_if_needed(); + m_tv = m_query->find_all(); + if (m_sort) { + m_tv.sort(m_sort); + } + m_last_seen_version = m_tv.sync_if_needed(); + + calculate_changes(); +} + +void ResultsNotifier::do_prepare_handover(SharedGroup& sg) +{ + if (!m_tv.is_attached()) { + return; + } + + REALM_ASSERT(m_tv.is_in_sync()); + + m_initial_run_complete = true; + m_tv_handover = sg.export_for_handover(m_tv, MutableSourcePayload::Move); + + add_changes(std::move(m_changes)); + REALM_ASSERT(m_changes.empty()); + + // detach the TableView as we won't need it again and keeping it around + // makes advance_read() much more expensive + m_tv = {}; +} + +bool ResultsNotifier::do_deliver(SharedGroup& sg) +{ + auto lock = lock_target(); + + // Target realm being null here indicates that we were unregistered while we + // were in the process of advancing the Realm version and preparing for + // delivery, i.e. the results was destroyed from the "wrong" thread + if (!get_realm()) { + return false; + } + + // We can get called before the query has actually had the chance to run if + // we're added immediately before a different set of async results are + // delivered + if (!m_initial_run_complete) { + return false; + } + + REALM_ASSERT(!m_query_handover); + + if (m_tv_handover) { + m_tv_handover->version = version(); + Results::Internal::set_table_view(*m_target_results, + std::move(*sg.import_from_handover(std::move(m_tv_handover)))); + } + REALM_ASSERT(!m_tv_handover); + return true; +} + +void ResultsNotifier::do_attach_to(SharedGroup& sg) +{ + REALM_ASSERT(m_query_handover); + m_query = sg.import_from_handover(std::move(m_query_handover)); + m_sort = SortDescriptor::create_from_and_consume_patch(m_sort_handover, *m_query->get_table()); +} + +void ResultsNotifier::do_detach_from(SharedGroup& sg) +{ + REALM_ASSERT(m_query); + REALM_ASSERT(!m_tv.is_attached()); + + SortDescriptor::generate_patch(m_sort, m_sort_handover); + m_query_handover = sg.export_for_handover(*m_query, MutableSourcePayload::Move); + m_query = nullptr; +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/transact_log_handler.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/transact_log_handler.cpp new file mode 100644 index 0000000..748bc84 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/transact_log_handler.cpp @@ -0,0 +1,773 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/transact_log_handler.hpp" + +#include "binding_context.hpp" +#include "impl/collection_notifier.hpp" +#include "index_set.hpp" +#include "shared_realm.hpp" + +#include +#include +#include + +using namespace realm; + +namespace { +template +struct MarkDirtyMixin { + bool mark_dirty(size_t row, size_t col) { static_cast(this)->mark_dirty(row, col); return true; } + +#if REALM_VER_MAJOR >= 2 + bool set_int(size_t col, size_t row, int_fast64_t, _impl::Instruction, size_t) { return mark_dirty(row, col); } + bool set_bool(size_t col, size_t row, bool, _impl::Instruction) { return mark_dirty(row, col); } + bool set_float(size_t col, size_t row, float, _impl::Instruction) { return mark_dirty(row, col); } + bool set_double(size_t col, size_t row, double, _impl::Instruction) { return mark_dirty(row, col); } + bool set_string(size_t col, size_t row, StringData, _impl::Instruction, size_t) { return mark_dirty(row, col); } + bool set_binary(size_t col, size_t row, BinaryData, _impl::Instruction) { return mark_dirty(row, col); } + bool set_olddatetime(size_t col, size_t row, OldDateTime, _impl::Instruction) { return mark_dirty(row, col); } + bool set_timestamp(size_t col, size_t row, Timestamp, _impl::Instruction) { return mark_dirty(row, col); } + bool set_table(size_t col, size_t row, _impl::Instruction) { return mark_dirty(row, col); } + bool set_mixed(size_t col, size_t row, const Mixed&, _impl::Instruction) { return mark_dirty(row, col); } + bool set_link(size_t col, size_t row, size_t, size_t, _impl::Instruction) { return mark_dirty(row, col); } + bool set_null(size_t col, size_t row, _impl::Instruction, size_t) { return mark_dirty(row, col); } +#else + bool set_int(size_t col, size_t row, int_fast64_t) { return mark_dirty(row, col); } + bool set_bool(size_t col, size_t row, bool) { return mark_dirty(row, col); } + bool set_float(size_t col, size_t row, float) { return mark_dirty(row, col); } + bool set_double(size_t col, size_t row, double) { return mark_dirty(row, col); } + bool set_string(size_t col, size_t row, StringData) { return mark_dirty(row, col); } + bool set_binary(size_t col, size_t row, BinaryData) { return mark_dirty(row, col); } + bool set_olddatetime(size_t col, size_t row, OldDateTime) { return mark_dirty(row, col); } + bool set_timestamp(size_t col, size_t row, Timestamp) { return mark_dirty(row, col); } + bool set_table(size_t col, size_t row) { return mark_dirty(row, col); } + bool set_mixed(size_t col, size_t row, const Mixed&) { return mark_dirty(row, col); } + bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); } + bool set_null(size_t col, size_t row) { return mark_dirty(row, col); } +#endif + bool nullify_link(size_t col, size_t row, size_t) { return mark_dirty(row, col); } + bool set_int_unique(size_t col, size_t row, size_t, int_fast64_t) { return mark_dirty(row, col); } + bool set_string_unique(size_t col, size_t row, size_t, StringData) { return mark_dirty(row, col); } + bool insert_substring(size_t col, size_t row, size_t, StringData) { return mark_dirty(row, col); } + bool erase_substring(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); } +}; + +class TransactLogValidationMixin { + // Index of currently selected table + size_t m_current_table = 0; + + // Tables which were created during the transaction being processed, which + // can have columns inserted without a schema version bump + std::vector m_new_tables; + + REALM_NORETURN + REALM_NOINLINE + void schema_error() + { + throw std::logic_error("Schema mismatch detected: another process has modified the Realm file's schema in an incompatible way"); + } + + // Throw an exception if the currently modified table already existed before + // the current set of modifications + bool schema_error_unless_new_table() + { + if (schema_mode == SchemaMode::Additive) { + return true; + } + if (std::find(begin(m_new_tables), end(m_new_tables), m_current_table) != end(m_new_tables)) { + return true; + } + schema_error(); + } + +protected: + size_t current_table() const noexcept { return m_current_table; } + +public: + SchemaMode schema_mode; + + // Schema changes which don't involve a change in the schema version are + // allowed + bool add_search_index(size_t) { return true; } + bool remove_search_index(size_t) { return true; } + + // Creating entirely new tables without a schema version bump is allowed, so + // we need to track if new columns are being added to a new table or an + // existing one + bool insert_group_level_table(size_t table_ndx, size_t, StringData) + { + // Shift any previously added tables after the new one + for (auto& table : m_new_tables) { + if (table >= table_ndx) + ++table; + } + m_new_tables.push_back(table_ndx); + m_current_table = table_ndx; + return true; + } + bool insert_column(size_t, DataType, StringData, bool) { return schema_error_unless_new_table(); } + bool insert_link_column(size_t, DataType, StringData, size_t, size_t) { return schema_error_unless_new_table(); } + bool set_link_type(size_t, LinkType) { return schema_error_unless_new_table(); } + bool move_column(size_t, size_t) { return schema_error_unless_new_table(); } + bool move_group_level_table(size_t, size_t) { return schema_error_unless_new_table(); } + + // Removing or renaming things while a Realm is open is never supported + bool erase_group_level_table(size_t, size_t) { schema_error(); } + bool rename_group_level_table(size_t, StringData) { schema_error(); } + bool erase_column(size_t) { schema_error(); } + bool erase_link_column(size_t, size_t, size_t) { schema_error(); } + bool rename_column(size_t, StringData) { schema_error(); } + + bool select_descriptor(int levels, const size_t*) + { + // subtables not supported + return levels == 0; + } + + bool select_table(size_t group_level_ndx, int, const size_t*) noexcept + { + m_current_table = group_level_ndx; + return true; + } + + bool select_link_list(size_t, size_t, size_t) { return true; } + + // Non-schema changes are all allowed + void parse_complete() { } + bool insert_empty_rows(size_t, size_t, size_t, bool) { return true; } + bool erase_rows(size_t, size_t, size_t, bool) { return true; } + bool swap_rows(size_t, size_t) { return true; } + bool clear_table() noexcept { return true; } + bool link_list_set(size_t, size_t, size_t) { return true; } + bool link_list_insert(size_t, size_t, size_t) { return true; } + bool link_list_erase(size_t, size_t) { return true; } + bool link_list_nullify(size_t, size_t) { return true; } + bool link_list_clear(size_t) { return true; } + bool link_list_move(size_t, size_t) { return true; } + bool link_list_swap(size_t, size_t) { return true; } + bool change_link_targets(size_t, size_t) { return true; } + bool optimize_table() { return true; } + +#if REALM_VER_MAJOR < 2 + // Translate calls into their modern equivalents, relying on the fact that we do not + // care about the value of the new `prior_size` argument. + bool link_list_set(size_t index, size_t value) { return link_list_set(index, value, npos); } + bool link_list_insert(size_t index, size_t value) { return link_list_insert(index, value, npos); } + bool link_list_erase(size_t index) { return link_list_erase(index, npos); } + bool link_list_nullify(size_t index) { return link_list_nullify(index, npos); } +#endif +}; + + +// A transaction log handler that just validates that all operations made are +// ones supported by the object store +struct TransactLogValidator : public TransactLogValidationMixin, public MarkDirtyMixin { + TransactLogValidator(SchemaMode schema_mode) { this->schema_mode = schema_mode; } + void mark_dirty(size_t, size_t) { } +}; + +// Move the value at container[from] to container[to], shifting everything in +// between, or do nothing if either are out of bounds +template +void rotate(Container& container, size_t from, size_t to) +{ + REALM_ASSERT(from != to); + if (from >= container.size() && to >= container.size()) + return; + if (from >= container.size() || to >= container.size()) + container.resize(std::max(from, to) + 1); + if (from < to) + std::rotate(begin(container) + from, begin(container) + to, begin(container) + to + 1); + else + std::rotate(begin(container) + to, begin(container) + from, begin(container) + from + 1); +} + +// Insert a default-initialized value at pos if there is anything after pos in the container. +template +void insert_empty_at(Container& container, size_t pos) +{ + if (pos < container.size()) + container.insert(container.begin() + pos, typename Container::value_type{}); +} + +// Shift `value` to reflect a move from `from` to `to` +void adjust_for_move(size_t& value, size_t from, size_t to) +{ + if (value == from) + value = to; + else if (value > from && value < to) + --value; + else if (value < from && value > to) + ++value; +} + +// Extends TransactLogValidator to also track changes and report it to the +// binding context if any properties are being observed +class TransactLogObserver : public TransactLogValidationMixin, public MarkDirtyMixin { + using ColumnInfo = BindingContext::ColumnInfo; + using ObserverState = BindingContext::ObserverState; + + // Observed table rows which need change information + std::vector m_observers; + // Userdata pointers for rows which have been deleted + std::vector invalidated; + // Delegate to send change information to + BindingContext* m_context; + + // Change information for the currently selected LinkList, if any + ColumnInfo* m_active_linklist = nullptr; + + // Get the change info for the given column, creating it if needed + static ColumnInfo& get_change(ObserverState& state, size_t i) + { + expand_to(state, i); + return state.changes[i]; + } + + static void expand_to(ObserverState& state, size_t i) + { + auto old_size = state.changes.size(); + if (old_size <= i) { + auto new_size = std::max(state.changes.size() * 2, i + 1); + state.changes.resize(new_size); + size_t base = old_size == 0 ? 0 : state.changes[old_size - 1].initial_column_index + 1; + for (size_t i = old_size; i < new_size; ++i) + state.changes[i].initial_column_index = i - old_size + base; + } + } + + // Remove the given observer from the list of observed objects and add it + // to the listed of invalidated objects + void invalidate(ObserverState *o) + { + invalidated.push_back(o->info); + m_observers.erase(m_observers.begin() + (o - &m_observers[0])); + } + +public: + template + TransactLogObserver(BindingContext* context, SharedGroup& sg, Func&& func, util::Optional schema_mode) + : m_context(context) + { + auto old_version = sg.get_version_of_current_transaction(); + if (context) { + m_observers = context->get_observed_rows(); + } + if (m_observers.empty()) { + if (schema_mode) { + func(TransactLogValidator(*schema_mode)); + } + else { + func(); + } + if (context && old_version != sg.get_version_of_current_transaction()) { + context->did_change({}, {}); + } + return; + } + + func(*this); + context->did_change(m_observers, invalidated); + } + + // Mark the given row/col as needing notifications sent + void mark_dirty(size_t row_ndx, size_t col_ndx) + { + auto it = lower_bound(begin(m_observers), end(m_observers), ObserverState{current_table(), row_ndx, nullptr}); + if (it != end(m_observers) && it->table_ndx == current_table() && it->row_ndx == row_ndx) { + get_change(*it, col_ndx).kind = ColumnInfo::Kind::Set; + } + } + + // Called at the end of the transaction log immediately before the version + // is advanced + void parse_complete() + { + m_context->will_change(m_observers, invalidated); + } + + bool insert_group_level_table(size_t table_ndx, size_t prior_size, StringData name) + { + for (auto& observer : m_observers) { + if (observer.table_ndx >= table_ndx) + ++observer.table_ndx; + } + TransactLogValidationMixin::insert_group_level_table(table_ndx, prior_size, name); + return true; + } + + bool insert_empty_rows(size_t row_ndx, size_t num_rows, size_t prior_size, bool) + { + if (row_ndx != prior_size) { + for (auto& observer : m_observers) { + if (observer.row_ndx >= row_ndx) + observer.row_ndx += num_rows; + } + } + return true; + } + + bool erase_rows(size_t row_ndx, size_t, size_t last_row_ndx, bool unordered) + { + for (size_t i = 0; i < m_observers.size(); ++i) { + auto& o = m_observers[i]; + if (o.table_ndx == current_table()) { + if (o.row_ndx == row_ndx) { + invalidate(&o); + --i; + } + else if (unordered && o.row_ndx == last_row_ndx) { + o.row_ndx = row_ndx; + } + else if (!unordered && o.row_ndx > row_ndx) { + o.row_ndx -= 1; + } + } + } + return true; + } + + bool clear_table() + { + for (size_t i = 0; i < m_observers.size(); ) { + auto& o = m_observers[i]; + if (o.table_ndx == current_table()) { + invalidate(&o); + } + else { + ++i; + } + } + return true; + } + + bool select_link_list(size_t col, size_t row, size_t) + { + m_active_linklist = nullptr; + for (auto& o : m_observers) { + if (o.table_ndx == current_table() && o.row_ndx == row) { + m_active_linklist = &get_change(o, col); + break; + } + } + return true; + } + + void append_link_list_change(ColumnInfo::Kind kind, size_t index) { + ColumnInfo *o = m_active_linklist; + if (!o || o->kind == ColumnInfo::Kind::SetAll) { + // Active LinkList isn't observed or already has multiple kinds of changes + return; + } + + if (o->kind == ColumnInfo::Kind::None) { + o->kind = kind; + o->indices.add(index); + } + else if (o->kind == kind) { + if (kind == ColumnInfo::Kind::Remove) { + o->indices.add_shifted(index); + } + else if (kind == ColumnInfo::Kind::Insert) { + o->indices.insert_at(index); + } + else { + o->indices.add(index); + } + } + else { + // Array KVO can only send a single kind of change at a time, so + // if there are multiple just give up and send "Set" + o->indices.set(0); + o->kind = ColumnInfo::Kind::SetAll; + } + } + + bool link_list_set(size_t index, size_t, size_t) + { + append_link_list_change(ColumnInfo::Kind::Set, index); + return true; + } + + bool link_list_insert(size_t index, size_t, size_t) + { + append_link_list_change(ColumnInfo::Kind::Insert, index); + return true; + } + + bool link_list_erase(size_t index, size_t) + { + append_link_list_change(ColumnInfo::Kind::Remove, index); + return true; + } + + bool link_list_nullify(size_t index, size_t) + { + append_link_list_change(ColumnInfo::Kind::Remove, index); + return true; + } + + bool link_list_swap(size_t index1, size_t index2) + { + append_link_list_change(ColumnInfo::Kind::Set, index1); + append_link_list_change(ColumnInfo::Kind::Set, index2); + return true; + } + + bool link_list_clear(size_t old_size) + { + ColumnInfo *o = m_active_linklist; + if (!o || o->kind == ColumnInfo::Kind::SetAll) { + return true; + } + + if (o->kind == ColumnInfo::Kind::Remove) + old_size += o->indices.count(); + else if (o->kind == ColumnInfo::Kind::Insert) + old_size -= o->indices.count(); + + o->indices.set(old_size); + + o->kind = ColumnInfo::Kind::Remove; + return true; + } + + bool link_list_move(size_t from, size_t to) + { + ColumnInfo *o = m_active_linklist; + if (!o || o->kind == ColumnInfo::Kind::SetAll) { + return true; + } + if (from > to) { + std::swap(from, to); + } + + if (o->kind == ColumnInfo::Kind::None) { + o->kind = ColumnInfo::Kind::Set; + } + if (o->kind == ColumnInfo::Kind::Set) { + for (size_t i = from; i <= to; ++i) + o->indices.add(i); + } + else { + o->indices.set(0); + o->kind = ColumnInfo::Kind::SetAll; + } + return true; + } + + bool insert_column(size_t ndx, DataType, StringData, bool) + { + for (auto& observer : m_observers) { + if (observer.table_ndx == current_table()) { + expand_to(observer, ndx); + insert_empty_at(observer.changes, ndx); + } + } + return true; + } + + bool move_column(size_t from, size_t to) + { + for (auto& observer : m_observers) { + if (observer.table_ndx == current_table()) { + // have to initialize the columns one past the moved one so that + // we can later initialize any more columns after that + expand_to(observer, std::max(from, to) + 1); + rotate(observer.changes, from, to); + } + } + return true; + } + + bool move_group_level_table(size_t from, size_t to) + { + for (auto& observer : m_observers) + adjust_for_move(observer.table_ndx, from, to); + return true; + } + + bool insert_link_column(size_t ndx, DataType type, StringData name, size_t, size_t) { return insert_column(ndx, type, name, false); } + +#if REALM_VER_MAJOR < 2 + // Translate calls into their modern equivalents, relying on the fact that we do not + // care about the value of the new `prior_size` argument. + bool link_list_set(size_t index, size_t value) { return link_list_set(index, value, npos); } + bool link_list_insert(size_t index, size_t value) { return link_list_insert(index, value, npos); } + bool link_list_erase(size_t index) { return link_list_erase(index, npos); } + bool link_list_nullify(size_t index) { return link_list_nullify(index, npos); } +#endif +}; + +// Extends TransactLogValidator to track changes made to LinkViews +class LinkViewObserver : public TransactLogValidationMixin, public MarkDirtyMixin { + _impl::TransactionChangeInfo& m_info; + _impl::CollectionChangeBuilder* m_active = nullptr; + + _impl::CollectionChangeBuilder* get_change() + { + auto tbl_ndx = current_table(); + if (tbl_ndx >= m_info.table_modifications_needed.size() || !m_info.table_modifications_needed[tbl_ndx]) + return nullptr; + if (m_info.tables.size() <= tbl_ndx) { + m_info.tables.resize(std::max(m_info.tables.size() * 2, tbl_ndx + 1)); + } + return &m_info.tables[tbl_ndx]; + } + + bool need_move_info() const + { + auto tbl_ndx = current_table(); + return tbl_ndx < m_info.table_moves_needed.size() && m_info.table_moves_needed[tbl_ndx]; + } + +public: + LinkViewObserver(_impl::TransactionChangeInfo& info) + : m_info(info) { } + + void mark_dirty(size_t row, size_t) + { + if (auto change = get_change()) + change->modify(row); + } + + void parse_complete() + { + for (auto& table : m_info.tables) { + table.parse_complete(); + } + for (auto& list : m_info.lists) { + list.changes->clean_up_stale_moves(); + } + } + + bool select_link_list(size_t col, size_t row, size_t) + { + mark_dirty(row, col); + + m_active = nullptr; + // When there are multiple source versions there could be multiple + // change objects for a single LinkView, in which case we need to use + // the last one + for (auto it = m_info.lists.rbegin(), end = m_info.lists.rend(); it != end; ++it) { + if (it->table_ndx == current_table() && it->row_ndx == row && it->col_ndx == col) { + m_active = it->changes; + break; + } + } + return true; + } + + bool link_list_set(size_t index, size_t, size_t) + { + if (m_active) + m_active->modify(index); + return true; + } + + bool link_list_insert(size_t index, size_t, size_t) + { + if (m_active) + m_active->insert(index); + return true; + } + + bool link_list_erase(size_t index, size_t) + { + if (m_active) + m_active->erase(index); + return true; + } + + bool link_list_nullify(size_t index, size_t prior_size) + { + return link_list_erase(index, prior_size); + } + + bool link_list_swap(size_t index1, size_t index2) + { + link_list_set(index1, 0, npos); + link_list_set(index2, 0, npos); + return true; + } + + bool link_list_clear(size_t old_size) + { + if (m_active) + m_active->clear(old_size); + return true; + } + + bool link_list_move(size_t from, size_t to) + { + if (m_active) + m_active->move(from, to); + return true; + } + + bool insert_empty_rows(size_t row_ndx, size_t num_rows_to_insert, size_t, bool unordered) + { + REALM_ASSERT(!unordered); + if (auto change = get_change()) + change->insert(row_ndx, num_rows_to_insert, need_move_info()); + + return true; + } + + bool erase_rows(size_t row_ndx, size_t, size_t prior_num_rows, bool unordered) + { + REALM_ASSERT(unordered); + size_t last_row = prior_num_rows - 1; + + for (auto it = begin(m_info.lists); it != end(m_info.lists); ) { + if (it->table_ndx == current_table()) { + if (it->row_ndx == row_ndx) { + *it = std::move(m_info.lists.back()); + m_info.lists.pop_back(); + continue; + } + if (it->row_ndx == last_row - 1) + it->row_ndx = row_ndx; + } + ++it; + } + + if (auto change = get_change()) + change->move_over(row_ndx, last_row, need_move_info()); + return true; + } + + bool clear_table() + { + auto tbl_ndx = current_table(); + auto it = remove_if(begin(m_info.lists), end(m_info.lists), + [&](auto const& lv) { return lv.table_ndx == tbl_ndx; }); + m_info.lists.erase(it, end(m_info.lists)); + if (auto change = get_change()) + change->clear(std::numeric_limits::max()); + return true; + } + + bool insert_column(size_t ndx, DataType, StringData, bool) + { + for (auto& list : m_info.lists) { + if (list.table_ndx == current_table() && list.col_ndx >= ndx) + ++list.col_ndx; + } + return true; + } + + bool insert_group_level_table(size_t ndx, size_t, StringData) + { + for (auto& list : m_info.lists) { + if (list.table_ndx >= ndx) + ++list.table_ndx; + } + insert_empty_at(m_info.tables, ndx); + insert_empty_at(m_info.table_moves_needed, ndx); + insert_empty_at(m_info.table_modifications_needed, ndx); + return true; + } + + bool move_column(size_t from, size_t to) + { + for (auto& list : m_info.lists) { + if (list.table_ndx == current_table()) + adjust_for_move(list.col_ndx, from, to); + } + return true; + } + + bool move_group_level_table(size_t from, size_t to) + { + for (auto& list : m_info.lists) + adjust_for_move(list.table_ndx, from, to); + rotate(m_info.tables, from, to); + rotate(m_info.table_modifications_needed, from, to); + rotate(m_info.table_moves_needed, from, to); + return true; + } + + bool insert_link_column(size_t ndx, DataType type, StringData name, size_t, size_t) { return insert_column(ndx, type, name, false); } + +#if REALM_VER_MAJOR < 2 + // Translate calls into their modern equivalents, relying on the fact that we do not + // care about the value of the new `prior_size` argument. + bool link_list_set(size_t index, size_t value) { return link_list_set(index, value, npos); } + bool link_list_insert(size_t index, size_t value) { return link_list_insert(index, value, npos); } + bool link_list_erase(size_t index) { return link_list_erase(index, npos); } + bool link_list_nullify(size_t index) { return link_list_nullify(index, npos); } +#endif +}; +} // anonymous namespace + +namespace realm { +namespace _impl { +namespace transaction { +void advance(SharedGroup& sg, BindingContext* context, SchemaMode schema_mode, SharedGroup::VersionID version) +{ + TransactLogObserver(context, sg, [&](auto&&... args) { + LangBindHelper::advance_read(sg, std::move(args)..., version); + }, schema_mode); +} + +void begin_without_validation(SharedGroup& sg) +{ + LangBindHelper::promote_to_write(sg); +} + +void begin(SharedGroup& sg, BindingContext* context, SchemaMode schema_mode) +{ + TransactLogObserver(context, sg, [&](auto&&... args) { + LangBindHelper::promote_to_write(sg, std::move(args)...); + }, schema_mode); +} + +void commit(SharedGroup& sg, BindingContext* context) +{ + LangBindHelper::commit_and_continue_as_read(sg); + + if (context) { + context->did_change({}, {}); + } +} + +void cancel(SharedGroup& sg, BindingContext* context) +{ + TransactLogObserver(context, sg, [&](auto&&... args) { + LangBindHelper::rollback_and_continue_as_read(sg, std::move(args)...); + }, util::none); +} + +void advance(SharedGroup& sg, + TransactionChangeInfo& info, + SharedGroup::VersionID version) +{ + if (info.table_modifications_needed.empty() && info.lists.empty()) { + LangBindHelper::advance_read(sg, version); + } + else { + LangBindHelper::advance_read(sg, LinkViewObserver(info), version); + } + +} + +} // namespace transaction +} // namespace _impl +} // namespace realm diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp new file mode 100644 index 0000000..d181667 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/impl/weak_realm_notifier.cpp @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "impl/weak_realm_notifier.hpp" + +#include "shared_realm.hpp" +#include "util/event_loop_signal.hpp" + +using namespace realm; +using namespace realm::_impl; + +WeakRealmNotifier::WeakRealmNotifier(const std::shared_ptr& realm, bool cache) +: m_realm(realm) +, m_realm_key(realm.get()) +, m_cache(cache) +, m_signal(std::make_shared>(Callback{realm})) +{ +} + +WeakRealmNotifier::~WeakRealmNotifier() = default; + +void WeakRealmNotifier::Callback::operator()() +{ + if (auto realm = weak_realm.lock()) { + realm->notify(); + } +} + +void WeakRealmNotifier::notify() +{ + m_signal->notify(); +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/index_set.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/index_set.cpp new file mode 100644 index 0000000..a5c30c2 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/index_set.cpp @@ -0,0 +1,707 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "index_set.hpp" + +#include + +#include + +using namespace realm; +using namespace realm::_impl; + +const size_t IndexSet::npos; + +template +void MutableChunkedRangeVectorIterator::set(size_t front, size_t back) +{ + this->m_outer->count -= this->m_inner->second - this->m_inner->first; + if (this->offset() == 0) { + this->m_outer->begin = front; + } + if (this->m_inner == &this->m_outer->data.back()) { + this->m_outer->end = back; + } + this->m_outer->count += back - front; + this->m_inner->first = front; + this->m_inner->second = back; +} + +template +void MutableChunkedRangeVectorIterator::adjust(ptrdiff_t front, ptrdiff_t back) +{ + if (this->offset() == 0) { + this->m_outer->begin += front; + } + if (this->m_inner == &this->m_outer->data.back()) { + this->m_outer->end += back; + } + this->m_outer->count += -front + back; + this->m_inner->first += front; + this->m_inner->second += back; +} + +template +void MutableChunkedRangeVectorIterator::shift(ptrdiff_t distance) +{ + if (this->offset() == 0) { + this->m_outer->begin += distance; + } + if (this->m_inner == &this->m_outer->data.back()) { + this->m_outer->end += distance; + } + this->m_inner->first += distance; + this->m_inner->second += distance; +} + +void ChunkedRangeVector::push_back(value_type value) +{ + if (!empty() && m_data.back().data.size() < max_size) { + auto& range = m_data.back(); + REALM_ASSERT(range.end <= value.first); + + range.data.push_back(value); + range.count += value.second - value.first; + range.end = value.second; + } + else { + m_data.push_back({{std::move(value)}, value.first, value.second, value.second - value.first}); + } + verify(); +} + +ChunkedRangeVector::iterator ChunkedRangeVector::insert(iterator pos, value_type value) +{ + if (pos.m_outer == m_data.end()) { + push_back(std::move(value)); + return std::prev(end()); + } + + pos = ensure_space(pos); + auto& chunk = *pos.m_outer; + pos.m_inner = &*chunk.data.insert(pos.m_outer->data.begin() + pos.offset(), value); + chunk.count += value.second - value.first; + chunk.begin = std::min(chunk.begin, value.first); + chunk.end = std::max(chunk.end, value.second); + + verify(); + return pos; +} + +ChunkedRangeVector::iterator ChunkedRangeVector::ensure_space(iterator pos) +{ + if (pos.m_outer->data.size() + 1 <= max_size) + return pos; + + auto offset = pos.offset(); + + // Split the chunk in half to make space for the new insertion + auto new_pos = m_data.insert(pos.m_outer + 1, Chunk{}); + auto prev = new_pos - 1; + auto to_move = max_size / 2; + new_pos->data.reserve(to_move); + new_pos->data.assign(prev->data.end() - to_move, prev->data.end()); + prev->data.resize(prev->data.size() - to_move); + + size_t moved_count = 0; + for (auto range : new_pos->data) + moved_count += range.second - range.first; + + prev->end = prev->data.back().second; + prev->count -= moved_count; + new_pos->begin = new_pos->data.front().first; + new_pos->end = new_pos->data.back().second; + new_pos->count = moved_count; + + if (offset >= to_move) { + pos.m_outer = new_pos; + offset -= to_move; + } + else { + pos.m_outer = prev; + } + pos.m_end = m_data.end(); + pos.m_inner = &pos.m_outer->data[offset]; + verify(); + return pos; +} + +ChunkedRangeVector::iterator ChunkedRangeVector::erase(iterator pos) +{ + auto offset = pos.offset(); + auto& chunk = *pos.m_outer; + chunk.count -= pos->second - pos->first; + chunk.data.erase(chunk.data.begin() + offset); + + if (chunk.data.size() == 0) { + pos.m_outer = m_data.erase(pos.m_outer); + pos.m_end = m_data.end(); + pos.m_inner = pos.m_outer == m_data.end() ? nullptr : &pos.m_outer->data.front(); + verify(); + return pos; + } + + chunk.begin = chunk.data.front().first; + chunk.end = chunk.data.back().second; + if (offset < chunk.data.size()) + pos.m_inner = &chunk.data[offset]; + else { + ++pos.m_outer; + pos.m_inner = pos.m_outer == pos.m_end ? nullptr : &pos.m_outer->data.front(); + } + + verify(); + return pos; +} + +void ChunkedRangeVector::verify() const noexcept +{ +#ifdef REALM_DEBUG + size_t prev_end = -1; + for (auto range : *this) { + REALM_ASSERT(range.first < range.second); + REALM_ASSERT(prev_end == size_t(-1) || range.first > prev_end); + prev_end = range.second; + } + + for (auto& chunk : m_data) { + REALM_ASSERT(!chunk.data.empty()); + REALM_ASSERT(chunk.data.front().first == chunk.begin); + REALM_ASSERT(chunk.data.back().second == chunk.end); + REALM_ASSERT(chunk.count <= chunk.end - chunk.begin); + size_t count = 0; + for (auto range : chunk.data) + count += range.second - range.first; + REALM_ASSERT(count == chunk.count); + } +#endif +} + +namespace { +class ChunkedRangeVectorBuilder { +public: + using value_type = std::pair; + + ChunkedRangeVectorBuilder(ChunkedRangeVector const& expected); + void push_back(size_t index); + void push_back(std::pair range); + std::vector finalize(); +private: + std::vector m_data; + size_t m_outer_pos = 0; +}; + +ChunkedRangeVectorBuilder::ChunkedRangeVectorBuilder(ChunkedRangeVector const& expected) +{ + size_t size = 0; + for (auto const& chunk : expected.m_data) + size += chunk.data.size(); + m_data.resize(size / ChunkedRangeVector::max_size + 1); + for (size_t i = 0; i < m_data.size() - 1; ++i) + m_data[i].data.reserve(ChunkedRangeVector::max_size); +} + +void ChunkedRangeVectorBuilder::push_back(size_t index) +{ + push_back({index, index + 1}); +} + +void ChunkedRangeVectorBuilder::push_back(std::pair range) +{ + auto& chunk = m_data[m_outer_pos]; + if (chunk.data.empty()) { + chunk.data.push_back(range); + chunk.count = range.second - range.first; + chunk.begin = range.first; + } + else if (range.first == chunk.data.back().second) { + chunk.data.back().second = range.second; + chunk.count += range.second - range.first; + } + else if (chunk.data.size() < ChunkedRangeVector::max_size) { + chunk.data.push_back(range); + chunk.count += range.second - range.first; + } + else { + chunk.end = chunk.data.back().second; + ++m_outer_pos; + if (m_outer_pos >= m_data.size()) + m_data.push_back({{range}, range.first, 0, 1}); + else { + auto& chunk = m_data[m_outer_pos]; + chunk.data.push_back(range); + chunk.begin = range.first; + chunk.count = range.second - range.first; + } + } +} + +std::vector ChunkedRangeVectorBuilder::finalize() +{ + if (!m_data.empty()) { + m_data.resize(m_outer_pos + 1); + if (m_data.back().data.empty()) + m_data.pop_back(); + else + m_data.back().end = m_data.back().data.back().second; + } + return std::move(m_data); +} +} + +IndexSet::IndexSet(std::initializer_list values) +{ + for (size_t v : values) + add(v); +} + +bool IndexSet::contains(size_t index) const +{ + auto it = const_cast(this)->find(index); + return it != end() && it->first <= index; +} + +size_t IndexSet::count(size_t start_index, size_t end_index) const +{ + auto it = const_cast(this)->find(start_index); + const auto end = this->end(); + if (it == end || it->first >= end_index) { + return 0; + } + if (it->second >= end_index) + return std::min(it->second, end_index) - std::max(it->first, start_index); + + size_t ret = 0; + + if (start_index > it->first || it.offset() != 0) { + // Start index is in the middle of a chunk, so start by counting the + // rest of that chunk + ret = it->second - std::max(it->first, start_index); + for (++it; it != end && it->second < end_index && it.offset() != 0; ++it) { + ret += it->second - it->first; + } + if (it != end && it->first < end_index && it.offset() != 0) + ret += end_index - it->first; + if (it == end || it->second >= end_index) + return ret; + } + + // Now count all complete chunks that fall within the range + while (it != end && it.outer()->end <= end_index) { + REALM_ASSERT_DEBUG(it.offset() == 0); + ret += it.outer()->count; + it.next_chunk(); + } + + // Cound all complete ranges within the last chunk + while (it != end && it->second <= end_index) { + ret += it->second - it->first; + ++it; + } + + // And finally add in the partial last range + if (it != end && it->first < end_index) + ret += end_index - it->first; + return ret; +} + +IndexSet::iterator IndexSet::find(size_t index) +{ + return find(index, begin()); +} + +IndexSet::iterator IndexSet::find(size_t index, iterator begin) +{ + auto it = std::find_if(begin.outer(), m_data.end(), + [&](auto const& lft) { return lft.end > index; }); + if (it == m_data.end()) + return end(); + if (index < it->begin) + return iterator(it, m_data.end(), &it->data[0]); + auto inner_begin = it->data.begin(); + if (it == begin.outer()) + inner_begin += begin.offset(); + auto inner = std::lower_bound(inner_begin, it->data.end(), index, + [&](auto const& lft, auto) { return lft.second <= index; }); + REALM_ASSERT_DEBUG(inner != it->data.end()); + + return iterator(it, m_data.end(), &*inner); +} + +void IndexSet::add(size_t index) +{ + do_add(find(index), index); +} + +void IndexSet::add(IndexSet const& other) +{ + auto it = begin(); + for (size_t index : other.as_indexes()) { + it = do_add(find(index, it), index); + } +} + +size_t IndexSet::add_shifted(size_t index) +{ + iterator it = begin(), end = this->end(); + + // Shift for any complete chunks before the target + for (; it != end && it.outer()->end <= index; it.next_chunk()) + index += it.outer()->count; + + // And any ranges within the last partial chunk + for (; it != end && it->first <= index; ++it) + index += it->second - it->first; + + do_add(it, index); + return index; +} + +void IndexSet::add_shifted_by(IndexSet const& shifted_by, IndexSet const& values) +{ + if (values.empty()) + return; + +#ifdef REALM_DEBUG + size_t expected = std::distance(as_indexes().begin(), as_indexes().end()); + for (auto index : values.as_indexes()) { + if (!shifted_by.contains(index)) + ++expected; + } +#endif + + ChunkedRangeVectorBuilder builder(*this); + + auto old_it = cbegin(), old_end = cend(); + auto shift_it = shifted_by.cbegin(), shift_end = shifted_by.cend(); + + size_t skip_until = 0; + size_t old_shift = 0; + size_t new_shift = 0; + for (size_t index : values.as_indexes()) { + for (; shift_it != shift_end && shift_it->first <= index; ++shift_it) { + new_shift += shift_it->second - shift_it->first; + skip_until = shift_it->second; + } + if (index < skip_until) + continue; + + for (; old_it != old_end && old_it->first <= index - new_shift + old_shift; ++old_it) { + for (size_t i = old_it->first; i < old_it->second; ++i) + builder.push_back(i); + old_shift += old_it->second - old_it->first; + } + + REALM_ASSERT(index >= new_shift); + builder.push_back(index - new_shift + old_shift); + } + + copy(old_it, old_end, std::back_inserter(builder)); + m_data = builder.finalize(); + +#ifdef REALM_DEBUG + REALM_ASSERT((size_t)std::distance(as_indexes().begin(), as_indexes().end()) == expected); +#endif +} + +void IndexSet::set(size_t len) +{ + clear(); + if (len) { + push_back({0, len}); + } +} + +void IndexSet::insert_at(size_t index, size_t count) +{ + REALM_ASSERT(count > 0); + + auto pos = find(index); + auto end = this->end(); + bool in_existing = false; + if (pos != end) { + if (pos->first <= index) { + in_existing = true; + pos.adjust(0, count); + } + else { + pos.shift(count); + } + for (auto it = std::next(pos); it != end; ++it) + it.shift(count); + } + if (!in_existing) { + for (size_t i = 0; i < count; ++i) + pos = std::next(do_add(pos, index + i)); + } + + verify(); +} + +void IndexSet::insert_at(IndexSet const& positions) +{ + if (positions.empty()) + return; + if (empty()) { + *this = positions; + return; + } + + IndexIterator begin1 = cbegin(), begin2 = positions.cbegin(); + IndexIterator end1 = cend(), end2 = positions.cend(); + + ChunkedRangeVectorBuilder builder(*this); + size_t shift = 0; + while (begin1 != end1 && begin2 != end2) { + if (*begin1 + shift < *begin2) { + builder.push_back(*begin1++ + shift); + } + else { + ++shift; + builder.push_back(*begin2++); + } + } + for (; begin1 != end1; ++begin1) + builder.push_back(*begin1 + shift); + for (; begin2 != end2; ++begin2) + builder.push_back(*begin2); + + m_data = builder.finalize(); +} + +void IndexSet::shift_for_insert_at(size_t index, size_t count) +{ + REALM_ASSERT(count > 0); + + auto it = find(index); + if (it == end()) + return; + + for (auto pos = it, end = this->end(); pos != end; ++pos) + pos.shift(count); + + // If the range contained the insertion point, split the range and move + // the part of it before the insertion point back + if (it->first < index + count) { + auto old_second = it->second; + it.set(it->first - count, index); + insert(std::next(it), {index + count, old_second}); + } + verify(); +} + +void IndexSet::shift_for_insert_at(realm::IndexSet const& values) +{ + if (empty() || values.empty()) + return; + if (values.m_data.front().begin >= m_data.back().end) + return; + + IndexIterator begin1 = cbegin(), begin2 = values.cbegin(); + IndexIterator end1 = cend(), end2 = values.cend(); + + ChunkedRangeVectorBuilder builder(*this); + size_t shift = 0; + while (begin1 != end1 && begin2 != end2) { + if (*begin1 + shift < *begin2) { + builder.push_back(*begin1++ + shift); + } + else { + ++shift; + begin2++; + } + } + for (; begin1 != end1; ++begin1) + builder.push_back(*begin1 + shift); + + m_data = builder.finalize(); +} + +void IndexSet::erase_at(size_t index) +{ + auto it = find(index); + if (it != end()) + do_erase(it, index); +} + +void IndexSet::erase_at(IndexSet const& positions) +{ + if (empty() || positions.empty()) + return; + + ChunkedRangeVectorBuilder builder(*this); + + IndexIterator begin1 = cbegin(), begin2 = positions.cbegin(); + IndexIterator end1 = cend(), end2 = positions.cend(); + + size_t shift = 0; + while (begin1 != end1 && begin2 != end2) { + if (*begin1 < *begin2) { + builder.push_back(*begin1++ - shift); + } + else if (*begin1 == *begin2) { + ++shift; + ++begin1; + ++begin2; + } + else { + ++shift; + ++begin2; + } + } + for (; begin1 != end1; ++begin1) + builder.push_back(*begin1 - shift); + + m_data = builder.finalize(); +} + +size_t IndexSet::erase_or_unshift(size_t index) +{ + auto shifted = index; + iterator it = begin(), end = this->end(); + + // Shift for any complete chunks before the target + for (; it != end && it.outer()->end <= index; it.next_chunk()) + shifted -= it.outer()->count; + + // And any ranges within the last partial chunk + for (; it != end && it->second <= index; ++it) + shifted -= it->second - it->first; + + if (it == end) + return shifted; + + if (it->first <= index) + shifted = npos; + + do_erase(it, index); + + return shifted; +} + +void IndexSet::do_erase(iterator it, size_t index) +{ + if (it->first <= index) { + if (it->first + 1 == it->second) { + it = erase(it); + } + else { + it.adjust(0, -1); + ++it; + } + } + else if (it != begin() && std::prev(it)->second + 1 == it->first) { + std::prev(it).adjust(0, it->second - it->first); + it = erase(it); + } + + for (; it != end(); ++it) + it.shift(-1); +} + +IndexSet::iterator IndexSet::do_remove(iterator it, size_t begin, size_t end) +{ + for (it = find(begin, it); it != this->end() && it->first < end; it = find(begin, it)) { + // Trim off any part of the range to remove that's before the matching range + begin = std::max(it->first, begin); + + // If the matching range extends to both sides of the range to remove, + // split it on the range to remove + if (it->first < begin && it->second > end) { + auto old_second = it->second; + it.set(it->first, begin); + it = std::prev(insert(std::next(it), {end, old_second})); + } + // Range to delete now coverages (at least) one end of the matching range + else if (begin == it->first && end >= it->second) + it = erase(it); + else if (begin == it->first) + it.set(end, it->second); + else + it.set(it->first, begin); + } + return it; +} + +void IndexSet::remove(size_t index, size_t count) +{ + do_remove(find(index), index, index + count); +} + +void IndexSet::remove(realm::IndexSet const& values) +{ + auto it = begin(); + for (auto range : values) { + it = do_remove(it, range.first, range.second); + if (it == end()) + return; + } +} + +size_t IndexSet::shift(size_t index) const +{ + // FIXME: optimize + for (auto range : *this) { + if (range.first > index) + break; + index += range.second - range.first; + } + return index; +} + +size_t IndexSet::unshift(size_t index) const +{ + REALM_ASSERT_DEBUG(!contains(index)); + return index - count(0, index); +} + +void IndexSet::clear() +{ + m_data.clear(); +} + +IndexSet::iterator IndexSet::do_add(iterator it, size_t index) +{ + verify(); + bool more_before = it != begin(), valid = it != end(); + REALM_ASSERT(!more_before || index >= std::prev(it)->second); + if (valid && it->first <= index && it->second > index) { + // index is already in set + return it; + } + if (more_before && std::prev(it)->second == index) { + auto prev = std::prev(it); + // index is immediately after an existing range + prev.adjust(0, 1); + + if (valid && prev->second == it->first) { + // index joins two existing ranges + prev.adjust(0, it->second - it->first); + return std::prev(erase(it)); + } + return prev; + } + if (valid && it->first == index + 1) { + // index is immediately before an existing range + it.adjust(-1, 0); + return it; + } + + // index is not next to an existing range + return insert(it, {index, index + 1}); +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/list.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/list.cpp new file mode 100644 index 0000000..4bab43a --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/list.cpp @@ -0,0 +1,229 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "list.hpp" + +#include "impl/list_notifier.hpp" +#include "impl/realm_coordinator.hpp" +#include "object_store.hpp" +#include "results.hpp" +#include "schema.hpp" +#include "shared_realm.hpp" +#include "util/format.hpp" + +#include + +using namespace realm; +using namespace realm::_impl; + +List::List() noexcept = default; +List::~List() = default; + +List::List(const List&) = default; +List& List::operator=(const List&) = default; +List::List(List&&) = default; +List& List::operator=(List&&) = default; + +List::List(std::shared_ptr r, LinkViewRef l) noexcept +: m_realm(std::move(r)) +, m_link_view(std::move(l)) +{ +} + +const ObjectSchema& List::get_object_schema() const +{ + verify_attached(); + + if (!m_object_schema) { + auto object_type = ObjectStore::object_type_for_table_name(m_link_view->get_target_table().get_name()); + auto it = m_realm->schema().find(object_type); + REALM_ASSERT(it != m_realm->schema().end()); + m_object_schema = &*it; + } + return *m_object_schema; +} + +Query List::get_query() const +{ + verify_attached(); + return m_link_view->get_target_table().where(m_link_view); +} + +size_t List::get_origin_row_index() const +{ + verify_attached(); + return m_link_view->get_origin_row_index(); +} + +void List::verify_valid_row(size_t row_ndx, bool insertion) const +{ + size_t size = m_link_view->size(); + if (row_ndx > size || (!insertion && row_ndx == size)) { + throw OutOfBoundsIndexException{row_ndx, size + insertion}; + } +} + +bool List::is_valid() const +{ + m_realm->verify_thread(); + return m_link_view && m_link_view->is_attached(); +} + +void List::verify_attached() const +{ + if (!is_valid()) { + throw InvalidatedException(); + } +} + +void List::verify_in_transaction() const +{ + verify_attached(); + if (!m_realm->is_in_transaction()) { + throw InvalidTransactionException("Must be in a write transaction"); + } +} + +size_t List::size() const +{ + verify_attached(); + return m_link_view->size(); +} + +RowExpr List::get(size_t row_ndx) const +{ + verify_attached(); + verify_valid_row(row_ndx); + return m_link_view->get(row_ndx); +} + +size_t List::get_unchecked(size_t row_ndx) const noexcept +{ + return m_link_view->get(row_ndx).get_index(); +} + +size_t List::find(ConstRow const& row) const +{ + verify_attached(); + + if (!row.is_attached() || row.get_table() != &m_link_view->get_target_table()) { + return not_found; + } + + return m_link_view->find(row.get_index()); +} + +void List::add(size_t target_row_ndx) +{ + verify_in_transaction(); + m_link_view->add(target_row_ndx); +} + +void List::insert(size_t row_ndx, size_t target_row_ndx) +{ + verify_in_transaction(); + verify_valid_row(row_ndx, true); + m_link_view->insert(row_ndx, target_row_ndx); +} + +void List::move(size_t source_ndx, size_t dest_ndx) +{ + verify_in_transaction(); + verify_valid_row(source_ndx); + verify_valid_row(dest_ndx); // Can't be one past end due to removing one earlier + m_link_view->move(source_ndx, dest_ndx); +} + +void List::remove(size_t row_ndx) +{ + verify_in_transaction(); + verify_valid_row(row_ndx); + m_link_view->remove(row_ndx); +} + +void List::remove_all() +{ + verify_in_transaction(); + m_link_view->clear(); +} + +void List::set(size_t row_ndx, size_t target_row_ndx) +{ + verify_in_transaction(); + verify_valid_row(row_ndx); + m_link_view->set(row_ndx, target_row_ndx); +} + +void List::swap(size_t ndx1, size_t ndx2) +{ + verify_in_transaction(); + verify_valid_row(ndx1); + verify_valid_row(ndx2); + m_link_view->swap(ndx1, ndx2); +} + +void List::delete_all() +{ + verify_in_transaction(); + m_link_view->remove_all_target_rows(); +} + +Results List::sort(SortDescriptor order) +{ + verify_attached(); + return Results(m_realm, m_link_view, util::none, std::move(order)); +} + +Results List::filter(Query q) +{ + verify_attached(); + return Results(m_realm, m_link_view, get_query().and_query(std::move(q))); +} + +Results List::snapshot() const +{ + verify_attached(); + return Results(m_realm, m_link_view).snapshot(); +} + +// These definitions rely on that LinkViews are interned by core +bool List::operator==(List const& rgt) const noexcept +{ + return m_link_view.get() == rgt.m_link_view.get(); +} + +namespace std { +size_t hash::operator()(realm::List const& list) const +{ + return std::hash()(list.m_link_view.get()); +} +} + +NotificationToken List::add_notification_callback(CollectionChangeCallback cb) +{ + verify_attached(); + if (!m_notifier) { + m_notifier = std::make_shared(m_link_view, m_realm); + RealmCoordinator::register_notifier(m_notifier); + } + return {m_notifier, m_notifier->add_callback(std::move(cb))}; +} + +List::OutOfBoundsIndexException::OutOfBoundsIndexException(size_t r, size_t c) +: std::out_of_range(util::format("Requested index %1 greater than max %2", r, c)) +, requested(r), valid_count(c) {} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_schema.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_schema.cpp new file mode 100644 index 0000000..dee4f44 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_schema.cpp @@ -0,0 +1,222 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "object_schema.hpp" + +#include "object_store.hpp" +#include "property.hpp" +#include "schema.hpp" + +#include "util/format.hpp" + +#include +#include +#include + +using namespace realm; + +#define ASSERT_PROPERTY_TYPE_VALUE(property, type) \ + static_assert(static_cast(PropertyType::property) == type_##type, \ + "PropertyType and DataType must have the same values") + +ASSERT_PROPERTY_TYPE_VALUE(Int, Int); +ASSERT_PROPERTY_TYPE_VALUE(Bool, Bool); +ASSERT_PROPERTY_TYPE_VALUE(Float, Float); +ASSERT_PROPERTY_TYPE_VALUE(Double, Double); +ASSERT_PROPERTY_TYPE_VALUE(Data, Binary); +ASSERT_PROPERTY_TYPE_VALUE(Date, Timestamp); +ASSERT_PROPERTY_TYPE_VALUE(Any, Mixed); +ASSERT_PROPERTY_TYPE_VALUE(Object, Link); +ASSERT_PROPERTY_TYPE_VALUE(Array, LinkList); + +ObjectSchema::ObjectSchema() = default; +ObjectSchema::~ObjectSchema() = default; + +ObjectSchema::ObjectSchema(std::string name, std::initializer_list persisted_properties) +: name(std::move(name)) +, persisted_properties(persisted_properties) +{ + for (auto const& prop : persisted_properties) { + if (prop.is_primary) { + primary_key = prop.name; + } + } +} + +ObjectSchema::ObjectSchema(Group const& group, StringData name, size_t index) : name(name) { + ConstTableRef table; + if (index < group.size()) { + table = group.get_table(index); + } + else { + table = ObjectStore::table_for_object_type(group, name); + } + + size_t count = table->get_column_count(); + persisted_properties.reserve(count); + for (size_t col = 0; col < count; col++) { + Property property; + property.name = table->get_column_name(col).data(); + property.type = (PropertyType)table->get_column_type(col); + property.is_indexed = table->has_search_index(col); + property.is_nullable = table->is_nullable(col) || property.type == PropertyType::Object; + property.table_column = col; + if (property.type == PropertyType::Object || property.type == PropertyType::Array) { + // set link type for objects and arrays + ConstTableRef linkTable = table->get_link_target(col); + property.object_type = ObjectStore::object_type_for_table_name(linkTable->get_name().data()); + } + persisted_properties.push_back(std::move(property)); + } + + primary_key = realm::ObjectStore::get_primary_key_for_object(group, name); + set_primary_key_property(); +} + +Property *ObjectSchema::property_for_name(StringData name) { + for (auto& prop : persisted_properties) { + if (StringData(prop.name) == name) { + return ∝ + } + } + for (auto& prop : computed_properties) { + if (StringData(prop.name) == name) { + return ∝ + } + } + return nullptr; +} + +const Property *ObjectSchema::property_for_name(StringData name) const { + return const_cast(this)->property_for_name(name); +} + +void ObjectSchema::set_primary_key_property() +{ + if (primary_key.length()) { + if (auto primary_key_prop = primary_key_property()) { + primary_key_prop->is_primary = true; + } + } +} + +static void validate_property(Schema const& schema, + std::string const& object_name, + Property const& prop, + Property const** primary, + std::vector& exceptions) +{ + // check nullablity + if (prop.is_nullable && !prop.type_is_nullable()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' cannot be nullable.", + object_name, prop.name, string_for_property_type(prop.type)); + } + else if (prop.type == PropertyType::Object && !prop.is_nullable) { + exceptions.emplace_back("Property '%1.%2' of type 'Object' must be nullable.", object_name, prop.name); + } + + // check primary keys + if (prop.is_primary) { + if (!prop.is_indexable()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' cannot be made the primary key.", + object_name, prop.name, string_for_property_type(prop.type)); + } + if (*primary) { + exceptions.emplace_back("Properties'%1' and '%2' are both marked as the primary key of '%3'.", + prop.name, (*primary)->name, object_name); + } + *primary = ∝ + } + + // check indexable + if (prop.is_indexed && !prop.is_indexable()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' cannot be indexed.", + object_name, prop.name, string_for_property_type(prop.type)); + } + + // check that only link properties have object types + if (prop.type != PropertyType::LinkingObjects && !prop.link_origin_property_name.empty()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' cannot have an origin property name.", + object_name, prop.name, string_for_property_type(prop.type)); + } + else if (prop.type == PropertyType::LinkingObjects && prop.link_origin_property_name.empty()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' must have an origin property name.", + object_name, prop.name, string_for_property_type(prop.type)); + } + + if (prop.type != PropertyType::Object && prop.type != PropertyType::Array && prop.type != PropertyType::LinkingObjects) { + if (!prop.object_type.empty()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' cannot have an object type.", + object_name, prop.name, string_for_property_type(prop.type)); + } + return; + } + + + // check that the object_type is valid for link properties + auto it = schema.find(prop.object_type); + if (it == schema.end()) { + exceptions.emplace_back("Property '%1.%2' of type '%3' has unknown object type '%4'", + object_name, prop.name, string_for_property_type(prop.type), prop.object_type); + return; + } + if (prop.type != PropertyType::LinkingObjects) { + return; + } + + const Property *origin_property = it->property_for_name(prop.link_origin_property_name); + if (!origin_property) { + exceptions.emplace_back("Property '%1.%2' declared as origin of linking objects property '%3.%4' does not exist", + prop.object_type, prop.link_origin_property_name, + object_name, prop.name); + } + else if (origin_property->type != PropertyType::Object && origin_property->type != PropertyType::Array) { + exceptions.emplace_back("Property '%1.%2' declared as origin of linking objects property '%3.%4' is not a link", + prop.object_type, prop.link_origin_property_name, + object_name, prop.name); + } + else if (origin_property->object_type != object_name) { + exceptions.emplace_back("Property '%1.%2' declared as origin of linking objects property '%3.%4' links to type '%5'", + prop.object_type, prop.link_origin_property_name, + object_name, prop.name, origin_property->object_type); + } +} + +void ObjectSchema::validate(Schema const& schema, std::vector& exceptions) const +{ + const Property *primary = nullptr; + for (auto const& prop : persisted_properties) { + validate_property(schema, name, prop, &primary, exceptions); + } + for (auto const& prop : computed_properties) { + validate_property(schema, name, prop, &primary, exceptions); + } + + if (!primary_key.empty() && !primary && !primary_key_property()) { + exceptions.emplace_back("Specified primary key '%1.%2' does not exist.", name, primary_key); + } +} + +namespace realm { +bool operator==(ObjectSchema const& a, ObjectSchema const& b) +{ + return std::tie(a.name, a.primary_key, a.persisted_properties, a.computed_properties) + == std::tie(b.name, b.primary_key, b.persisted_properties, b.computed_properties); + +} +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_store.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_store.cpp new file mode 100644 index 0000000..9f82492 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/object_store.cpp @@ -0,0 +1,813 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "object_store.hpp" + +#include "object_schema.hpp" +#include "schema.hpp" +#include "shared_realm.hpp" +#include "util/format.hpp" + +#include +#include +#include +#include + +#include + +using namespace realm; + +const uint64_t ObjectStore::NotVersioned = std::numeric_limits::max(); + +namespace { +const char * const c_metadataTableName = "metadata"; +const char * const c_versionColumnName = "version"; +const size_t c_versionColumnIndex = 0; + +const char * const c_primaryKeyTableName = "pk"; +const char * const c_primaryKeyObjectClassColumnName = "pk_table"; +const size_t c_primaryKeyObjectClassColumnIndex = 0; +const char * const c_primaryKeyPropertyNameColumnName = "pk_property"; +const size_t c_primaryKeyPropertyNameColumnIndex = 1; + +const size_t c_zeroRowIndex = 0; + +const char c_object_table_prefix[] = "class_"; + +void create_metadata_tables(Group& group) { + TableRef table = group.get_or_add_table(c_primaryKeyTableName); + if (table->get_column_count() == 0) { + table->add_column(type_String, c_primaryKeyObjectClassColumnName); + table->add_column(type_String, c_primaryKeyPropertyNameColumnName); + } + + table = group.get_or_add_table(c_metadataTableName); + if (table->get_column_count() == 0) { + table->add_column(type_Int, c_versionColumnName); + + // set initial version + table->add_empty_row(); + table->set_int(c_versionColumnIndex, c_zeroRowIndex, ObjectStore::NotVersioned); + } +} + +void set_schema_version(Group& group, uint64_t version) { + TableRef table = group.get_or_add_table(c_metadataTableName); + table->set_int(c_versionColumnIndex, c_zeroRowIndex, version); +} + +template +auto table_for_object_schema(Group& group, ObjectSchema const& object_schema) +{ + return ObjectStore::table_for_object_type(group, object_schema.name); +} + +void add_index(Table& table, size_t col) +{ + try { + table.add_search_index(col); + } + catch (LogicError const&) { + throw std::logic_error(util::format("Cannot index property '%1.%2': indexing properties of type '%3' is not yet implemented.", + ObjectStore::object_type_for_table_name(table.get_name()), + table.get_column_name(col), + string_for_property_type((PropertyType)table.get_column_type(col)))); + } +} + +void insert_column(Group& group, Table& table, Property const& property, size_t col_ndx) +{ + if (property.type == PropertyType::Object || property.type == PropertyType::Array) { + auto target_name = ObjectStore::table_name_for_object_type(property.object_type); + TableRef link_table = group.get_or_add_table(target_name); + table.insert_column_link(col_ndx, DataType(property.type), property.name, *link_table); + } + else { + table.insert_column(col_ndx, DataType(property.type), property.name, property.is_nullable); + if (property.requires_index()) + add_index(table, col_ndx); + } +} + +void add_column(Group& group, Table& table, Property const& property) +{ + insert_column(group, table, property, table.get_column_count()); +} + +void replace_column(Group& group, Table& table, Property const& old_property, Property const& new_property) +{ + insert_column(group, table, new_property, old_property.table_column); + table.remove_column(old_property.table_column + 1); +} + +TableRef create_table(Group& group, ObjectSchema const& object_schema) +{ + auto name = ObjectStore::table_name_for_object_type(object_schema.name); + auto table = group.get_or_add_table(name); + if (table->get_column_count() > 0) { + return table; + } + + for (auto const& prop : object_schema.persisted_properties) { + add_column(group, *table, prop); + } + + ObjectStore::set_primary_key_for_object(group, object_schema.name, object_schema.primary_key); + + return table; +} + +void copy_property_values(Property const& prop, Table& table) +{ + auto copy_property_values = [&](auto getter, auto setter) { + for (size_t i = 0, count = table.size(); i < count; i++) { +#if REALM_VER_MAJOR >= 2 + bool is_default = false; + (table.*setter)(prop.table_column, i, (table.*getter)(prop.table_column + 1, i), + is_default); +#else + (table.*setter)(prop.table_column, i, (table.*getter)(prop.table_column + 1, i)); +#endif + } + }; + + switch (prop.type) { + case PropertyType::Int: + copy_property_values(&Table::get_int, &Table::set_int); + break; + case PropertyType::Bool: + copy_property_values(&Table::get_bool, &Table::set_bool); + break; + case PropertyType::Float: + copy_property_values(&Table::get_float, &Table::set_float); + break; + case PropertyType::Double: + copy_property_values(&Table::get_double, &Table::set_double); + break; + case PropertyType::String: + copy_property_values(&Table::get_string, &Table::set_string); + break; + case PropertyType::Data: + copy_property_values(&Table::get_binary, &Table::set_binary); + break; + case PropertyType::Date: + copy_property_values(&Table::get_timestamp, &Table::set_timestamp); + break; + default: + break; + } +} + +void make_property_optional(Group& group, Table& table, Property property) +{ + property.is_nullable = true; + insert_column(group, table, property, property.table_column); + copy_property_values(property, table); + table.remove_column(property.table_column + 1); +} + +void make_property_required(Group& group, Table& table, Property property) +{ + property.is_nullable = false; + insert_column(group, table, property, property.table_column); + table.remove_column(property.table_column + 1); +} + +void validate_primary_column_uniqueness(Group const& group, StringData object_type, StringData primary_property) +{ + auto table = ObjectStore::table_for_object_type(group, object_type); + if (table->get_distinct_view(table->get_column_index(primary_property)).size() != table->size()) { + throw DuplicatePrimaryKeyValueException(object_type, primary_property); + } +} + +void validate_primary_column_uniqueness(Group const& group) +{ + auto pk_table = group.get_table(c_primaryKeyTableName); + for (size_t i = 0, count = pk_table->size(); i < count; ++i) { + validate_primary_column_uniqueness(group, + pk_table->get_string(c_primaryKeyObjectClassColumnIndex, i), + pk_table->get_string(c_primaryKeyPropertyNameColumnIndex, i)); + } +} +} // anonymous namespace + +uint64_t ObjectStore::get_schema_version(Group const& group) { + ConstTableRef table = group.get_table(c_metadataTableName); + if (!table || table->get_column_count() == 0) { + return ObjectStore::NotVersioned; + } + return table->get_int(c_versionColumnIndex, c_zeroRowIndex); +} + +StringData ObjectStore::get_primary_key_for_object(Group const& group, StringData object_type) { + ConstTableRef table = group.get_table(c_primaryKeyTableName); + if (!table) { + return ""; + } + size_t row = table->find_first_string(c_primaryKeyObjectClassColumnIndex, object_type); + if (row == not_found) { + return ""; + } + return table->get_string(c_primaryKeyPropertyNameColumnIndex, row); +} + +void ObjectStore::set_primary_key_for_object(Group& group, StringData object_type, StringData primary_key) { + TableRef table = group.get_table(c_primaryKeyTableName); + + // get row or create if new object and populate + size_t row = table->find_first_string(c_primaryKeyObjectClassColumnIndex, object_type); + if (row == not_found && primary_key.size()) { + row = table->add_empty_row(); + table->set_string(c_primaryKeyObjectClassColumnIndex, row, object_type); + } + + // set if changing, or remove if setting to nil + if (primary_key.size() == 0) { + if (row != not_found) { + table->remove(row); + } + } + else { + table->set_string(c_primaryKeyPropertyNameColumnIndex, row, primary_key); + } +} + +StringData ObjectStore::object_type_for_table_name(StringData table_name) { + if (table_name.begins_with(c_object_table_prefix)) { + return table_name.substr(sizeof(c_object_table_prefix) - 1); + } + return StringData(); +} + +std::string ObjectStore::table_name_for_object_type(StringData object_type) { + return std::string(c_object_table_prefix) + std::string(object_type); +} + +TableRef ObjectStore::table_for_object_type(Group& group, StringData object_type) { + auto name = table_name_for_object_type(object_type); + return group.get_table(name); +} + +ConstTableRef ObjectStore::table_for_object_type(Group const& group, StringData object_type) { + auto name = table_name_for_object_type(object_type); + return group.get_table(name); +} + +namespace { +struct SchemaDifferenceExplainer { + std::vector errors; + + void operator()(schema_change::AddTable op) + { + errors.emplace_back("Class '%1' has been added.", op.object->name); + } + + void operator()(schema_change::AddProperty op) + { + errors.emplace_back("Property '%1.%2' has been added.", op.object->name, op.property->name); + } + + void operator()(schema_change::RemoveProperty op) + { + errors.emplace_back("Property '%1.%2' has been removed.", op.object->name, op.property->name); + } + + void operator()(schema_change::ChangePropertyType op) + { + errors.emplace_back("Property '%1.%2' has been changed from '%3' to '%4'.", + op.object->name, op.new_property->name, + string_for_property_type(op.old_property->type), + string_for_property_type(op.new_property->type)); + } + + void operator()(schema_change::MakePropertyNullable op) + { + errors.emplace_back("Property '%1.%2' has been made optional.", op.object->name, op.property->name); + } + + void operator()(schema_change::MakePropertyRequired op) + { + errors.emplace_back("Property '%1.%2' has been made required.", op.object->name, op.property->name); + } + + void operator()(schema_change::ChangePrimaryKey op) + { + if (op.property && !op.object->primary_key.empty()) { + errors.emplace_back("Primary Key for class '%1 has changed from '%2' to '%3'.", + op.object->name, op.object->primary_key, op.property->name); + } + else if (op.property) { + errors.emplace_back("Primary Key for class '%1 has been added.", op.object->name); + } + else { + errors.emplace_back("Primary Key for class '%1 has been removed.", op.object->name); + } + } + + void operator()(schema_change::AddIndex op) + { + errors.emplace_back("Property '%1.%2' has been made indexed.", op.object->name, op.property->name); + } + + void operator()(schema_change::RemoveIndex op) + { + errors.emplace_back("Property '%1.%2' has been made unindexed.", op.object->name, op.property->name); + } +}; + +class TableHelper { +public: + TableHelper(Group& g) : m_group(g) { } + + Table& operator()(const ObjectSchema* object_schema) + { + if (object_schema != m_current_object_schema) { + m_current_table = table_for_object_schema(m_group, *object_schema); + m_current_object_schema = object_schema; + } + REALM_ASSERT(m_current_table); + return *m_current_table; + } + +private: + Group& m_group; + const ObjectSchema* m_current_object_schema = nullptr; + TableRef m_current_table; +}; + +template +void verify_no_errors(Verifier&& verifier, std::vector const& changes) +{ + for (auto& change : changes) { + change.visit(verifier); + } + + if (!verifier.errors.empty()) { + throw ErrorType(verifier.errors); + } +} +} // anonymous namespace + +bool ObjectStore::needs_migration(std::vector const& changes) +{ + using namespace schema_change; + struct Visitor { + bool operator()(AddIndex) { return false; } + bool operator()(AddProperty) { return true; } + bool operator()(AddTable) { return false; } + bool operator()(ChangePrimaryKey) { return true; } + bool operator()(ChangePropertyType) { return true; } + bool operator()(MakePropertyNullable) { return true; } + bool operator()(MakePropertyRequired) { return true; } + bool operator()(RemoveIndex) { return false; } + bool operator()(RemoveProperty) { return true; } + }; + + return std::any_of(begin(changes), end(changes), + [](auto&& change) { return change.visit(Visitor()); }); +} + +void ObjectStore::verify_no_changes_required(std::vector const& changes) +{ + verify_no_errors(SchemaDifferenceExplainer(), changes); +} + +void ObjectStore::verify_no_migration_required(std::vector const& changes) +{ + using namespace schema_change; + struct Verifier : SchemaDifferenceExplainer { + using SchemaDifferenceExplainer::operator(); + + // Adding a table or adding/removing indexes can be done automatically. + // All other changes require migrations. + void operator()(AddTable) { } + void operator()(AddIndex) { } + void operator()(RemoveIndex) { } + } verifier; + verify_no_errors(verifier, changes); +} + +void ObjectStore::verify_valid_additive_changes(std::vector const& changes) +{ + using namespace schema_change; + struct Verifier : SchemaDifferenceExplainer { + using SchemaDifferenceExplainer::operator(); + + // Additive mode allows adding things, extra columns, and adding/removing indexes + void operator()(AddTable) { } + void operator()(AddProperty) { } + void operator()(RemoveProperty) { } + void operator()(AddIndex) { } + void operator()(RemoveIndex) { } + } verifier; + verify_no_errors(verifier, changes); +} + +static void apply_non_migration_changes(Group& group, std::vector const& changes) +{ + using namespace schema_change; + struct Applier : SchemaDifferenceExplainer { + Applier(Group& group) : group{group}, table{group} { } + Group& group; + TableHelper table; + + // Produce an exception listing the unsupported schema changes for + // everything but the explicitly supported ones + using SchemaDifferenceExplainer::operator(); + + void operator()(AddTable op) { create_table(group, *op.object); } + void operator()(AddIndex op) { add_index(table(op.object), op.property->table_column); } + void operator()(RemoveIndex op) { table(op.object).remove_search_index(op.property->table_column); } + } applier{group}; + verify_no_errors(applier, changes); +} + +static void create_initial_tables(Group& group, std::vector const& changes) +{ + using namespace schema_change; + struct Applier { + Applier(Group& group) : group{group}, table{group} { } + Group& group; + TableHelper table; + + void operator()(AddTable op) { create_table(group, *op.object); } + + // Note that in normal operation none of these will be hit, as if we're + // creating the initial tables there shouldn't be anything to update. + // Implementing these makes us better able to handle weird + // not-quite-correct files produced by other things and has no obvious + // downside. + void operator()(AddProperty op) { add_column(group, table(op.object), *op.property); } + void operator()(RemoveProperty op) { table(op.object).remove_column(op.property->table_column); } + void operator()(MakePropertyNullable op) { make_property_optional(group, table(op.object), *op.property); } + void operator()(MakePropertyRequired op) { make_property_required(group, table(op.object), *op.property); } + void operator()(ChangePrimaryKey op) { ObjectStore::set_primary_key_for_object(group, op.object->name, op.property->name); } + void operator()(AddIndex op) { add_index(table(op.object), op.property->table_column); } + void operator()(RemoveIndex op) { table(op.object).remove_search_index(op.property->table_column); } + + void operator()(ChangePropertyType op) + { + insert_column(group, table(op.object), *op.new_property, op.old_property->table_column); + table(op.object).remove_column(op.old_property->table_column + 1); + } + } applier{group}; + + for (auto& change : changes) { + change.visit(applier); + } +} + +static void apply_additive_changes(Group& group, std::vector const& changes, bool update_indexes) +{ + using namespace schema_change; + struct Applier { + Applier(Group& group, bool update_indexes) : group{group}, table{group}, update_indexes{update_indexes} { } + Group& group; + TableHelper table; + bool update_indexes; + + void operator()(AddTable op) { create_table(group, *op.object); } + void operator()(AddProperty op) { add_column(group, table(op.object), *op.property); } + void operator()(AddIndex op) { if (update_indexes) add_index(table(op.object), op.property->table_column); } + void operator()(RemoveIndex op) { if (update_indexes) table(op.object).remove_search_index(op.property->table_column); } + void operator()(RemoveProperty) { } + + // No need for errors for these, as we've already verified that they aren't present + void operator()(ChangePrimaryKey) { } + void operator()(ChangePropertyType) { } + void operator()(MakePropertyNullable) { } + void operator()(MakePropertyRequired) { } + } applier{group, update_indexes}; + + for (auto& change : changes) { + change.visit(applier); + } +} + +static void apply_pre_migration_changes(Group& group, std::vector const& changes) +{ + using namespace schema_change; + struct Applier { + Applier(Group& group) : group{group}, table{group} { } + Group& group; + TableHelper table; + + void operator()(AddTable op) { create_table(group, *op.object); } + void operator()(AddProperty op) { add_column(group, table(op.object), *op.property); } + void operator()(RemoveProperty) { /* delayed until after the migration */ } + void operator()(ChangePropertyType op) { replace_column(group, table(op.object), *op.old_property, *op.new_property); } + void operator()(MakePropertyNullable op) { make_property_optional(group, table(op.object), *op.property); } + void operator()(MakePropertyRequired op) { make_property_required(group, table(op.object), *op.property); } + void operator()(ChangePrimaryKey op) { ObjectStore::set_primary_key_for_object(group, op.object->name, op.property ? op.property->name : ""); } + void operator()(AddIndex op) { add_index(table(op.object), op.property->table_column); } + void operator()(RemoveIndex op) { table(op.object).remove_search_index(op.property->table_column); } + } applier{group}; + + for (auto& change : changes) { + change.visit(applier); + } +} + +static void apply_post_migration_changes(Group& group, std::vector const& changes, Schema const& initial_schema) +{ + using namespace schema_change; + struct Applier { + Applier(Group& group, Schema const& initial_schema) : group{group}, initial_schema(initial_schema), table(group) { } + Group& group; + Schema const& initial_schema; + TableHelper table; + + void operator()(RemoveProperty op) + { + if (!initial_schema.empty() && !initial_schema.find(op.object->name)->property_for_name(op.property->name)) + throw std::logic_error(util::format("Renamed property '%1.%2' does not exist.", op.object->name, op.property->name)); + auto table = table_for_object_schema(group, *op.object); + table->remove_column(op.property->table_column); + } + + void operator()(ChangePrimaryKey op) + { + if (op.property) { + validate_primary_column_uniqueness(group, op.object->name, op.property->name); + } + } + + void operator()(AddTable op) { create_table(group, *op.object); } + void operator()(AddIndex op) { add_index(table(op.object), op.property->table_column); } + void operator()(RemoveIndex op) { table(op.object).remove_search_index(op.property->table_column); } + + void operator()(ChangePropertyType) { } + void operator()(MakePropertyNullable) { } + void operator()(MakePropertyRequired) { } + void operator()(AddProperty) { } + } applier{group, initial_schema}; + + for (auto& change : changes) { + change.visit(applier); + } +} + +void ObjectStore::apply_schema_changes(Group& group, Schema& schema, uint64_t& schema_version, + Schema const& target_schema, uint64_t target_schema_version, + SchemaMode mode, std::vector const& changes, + std::function migration_function) +{ + create_metadata_tables(group); + + if (schema_version == ObjectStore::NotVersioned) { + create_initial_tables(group, changes); + set_schema_version(group, target_schema_version); + schema_version = target_schema_version; + schema = target_schema; + set_schema_columns(group, schema); + return; + } + + if (mode == SchemaMode::Additive) { + apply_additive_changes(group, changes, schema_version < target_schema_version); + + if (schema_version < target_schema_version) { + schema_version = target_schema_version; + set_schema_version(group, target_schema_version); + } + + schema = target_schema; + set_schema_columns(group, schema); + return; + } + + if (mode == SchemaMode::Manual) { + // Have to update the schema on the Realm before calling the migration + // function as the migration will need it + auto old_version = schema_version; + auto old_schema = schema; + schema_version = target_schema_version; + schema = target_schema; + set_schema_columns(group, schema); + + try { + migration_function(); + verify_no_changes_required(schema_from_group(group).compare(schema)); + validate_primary_column_uniqueness(group); + } + catch (...) { + schema = move(old_schema); + schema_version = old_version; + throw; + } + + set_schema_columns(group, schema); + set_schema_version(group, target_schema_version); + return; + } + + if (schema_version == target_schema_version) { + apply_non_migration_changes(group, changes); + schema = target_schema; + set_schema_columns(group, schema); + return; + } + + apply_pre_migration_changes(group, changes); + if (migration_function) { + // Have to update the schema on the Realm before calling the migration + // function as the migration will need it + auto old_version = schema_version; + auto old_schema = schema; + schema_version = target_schema_version; + schema = target_schema; + set_schema_columns(group, schema); + + try { + migration_function(); + + // Migration function may have changed the schema, so we need to re-read it + schema = schema_from_group(group); + apply_post_migration_changes(group, schema.compare(target_schema), old_schema); + validate_primary_column_uniqueness(group); + } + catch (...) { + schema = move(old_schema); + schema_version = old_version; + throw; + } + } + else { + apply_post_migration_changes(group, changes, {}); + } + + set_schema_version(group, target_schema_version); + schema_version = target_schema_version; + schema = target_schema; + set_schema_columns(group, schema); +} + +Schema ObjectStore::schema_from_group(Group const& group) { + std::vector schema; + schema.reserve(group.size()); + for (size_t i = 0; i < group.size(); i++) { + auto object_type = object_type_for_table_name(group.get_table_name(i)); + if (object_type.size()) { + schema.emplace_back(group, object_type, i); + } + } + return schema; +} + +void ObjectStore::set_schema_columns(Group const& group, Schema& schema) +{ + for (auto& object_schema : schema) { + auto table = table_for_object_schema(group, object_schema); + if (!table) { + continue; + } + for (auto& property : object_schema.persisted_properties) { + property.table_column = table->get_column_index(property.name); + } + } +} + +void ObjectStore::delete_data_for_object(Group& group, StringData object_type) { + if (TableRef table = table_for_object_type(group, object_type)) { + group.remove_table(table->get_index_in_group()); + ObjectStore::set_primary_key_for_object(group, object_type, ""); + } +} + +bool ObjectStore::is_empty(Group const& group) { + for (size_t i = 0; i < group.size(); i++) { + ConstTableRef table = group.get_table(i); + std::string object_type = object_type_for_table_name(table->get_name()); + if (!object_type.length()) { + continue; + } + if (!table->is_empty()) { + return false; + } + } + return true; +} + +void ObjectStore::rename_property(Group& group, Schema& target_schema, StringData object_type, StringData old_name, StringData new_name) +{ + TableRef table = table_for_object_type(group, object_type); + if (!table) { + throw std::logic_error(util::format("Cannot rename properties for type '%1' because it does not exist.", object_type)); + } + + auto target_object_schema = target_schema.find(object_type); + if (target_object_schema == target_schema.end()) { + throw std::logic_error(util::format("Cannot rename properties for type '%1' because it has been removed from the Realm.", object_type)); + } + + if (target_object_schema->property_for_name(old_name)) { + throw std::logic_error(util::format("Cannot rename property '%1.%2' to '%3' because the source property still exists.", + object_type, old_name, new_name)); + } + + ObjectSchema table_object_schema(group, object_type); + Property *old_property = table_object_schema.property_for_name(old_name); + if (!old_property) { + throw std::logic_error(util::format("Cannot rename property '%1.%2' because it does not exist.", object_type, old_name)); + } + + Property *new_property = table_object_schema.property_for_name(new_name); + if (!new_property) { + // New property doesn't exist in the table, which means we're probably + // renaming to an intermediate property in a multi-version migration. + // This is safe because the migration will fail schema validation unless + // this property is renamed again to a valid name before the end. + table->rename_column(old_property->table_column, new_name); + return; + } + + if (old_property->type != new_property->type || old_property->object_type != new_property->object_type) { + throw std::logic_error(util::format("Cannot rename property '%1.%2' to '%3' because it would change from type '%4' to '%5'.", + object_type, old_name, new_name, old_property->type_string(), new_property->type_string())); + } + + if (old_property->is_nullable && !new_property->is_nullable) { + throw std::logic_error(util::format("Cannot rename property '%1.%2' to '%3' because it would change from optional to required.", + object_type, old_name, new_name)); + } + + size_t column_to_remove = new_property->table_column; + table->rename_column(old_property->table_column, new_name); + table->remove_column(column_to_remove); + + // update table_column for each property since it may have shifted + for (auto& current_prop : target_object_schema->persisted_properties) { + if (current_prop.table_column == column_to_remove) + current_prop.table_column = old_property->table_column; + else if (current_prop.table_column > column_to_remove) + --current_prop.table_column; + } + + // update nullability for column + if (new_property->is_nullable && !old_property->is_nullable) { + auto prop = *new_property; + prop.table_column = old_property->table_column; + make_property_optional(group, *table, prop); + } +} + +InvalidSchemaVersionException::InvalidSchemaVersionException(uint64_t old_version, uint64_t new_version) +: logic_error(util::format("Provided schema version %1 is less than last set version %2.", new_version, old_version)) +, m_old_version(old_version), m_new_version(new_version) +{ +} + +DuplicatePrimaryKeyValueException::DuplicatePrimaryKeyValueException(std::string object_type, std::string property) +: logic_error(util::format("Primary key property '%1.%2' has duplicate values after migration.", object_type, property)) +, m_object_type(object_type), m_property(property) +{ +} + +SchemaValidationException::SchemaValidationException(std::vector const& errors) +: std::logic_error([&] { + std::string message = "Schema validation failed due to the following errors:"; + for (auto const& error : errors) { + message += std::string("\n- ") + error.what(); + } + return message; +}()) +{ +} + +SchemaMismatchException::SchemaMismatchException(std::vector const& errors) +: std::logic_error([&] { + std::string message = "Migration is required due to the following errors:"; + for (auto const& error : errors) { + message += std::string("\n- ") + error.what(); + } + return message; +}()) +{ +} + +InvalidSchemaChangeException::InvalidSchemaChangeException(std::vector const& errors) +: std::logic_error([&] { + std::string message = "The following changes cannot be made in additive-only schema mode:"; + for (auto const& error : errors) { + message += std::string("\n- ") + error.what(); + } + return message; +}()) +{ +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/placeholder.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/placeholder.cpp new file mode 100644 index 0000000..8936534 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/placeholder.cpp @@ -0,0 +1 @@ +// This file is intentionally left blank. diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/results.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/results.cpp new file mode 100644 index 0000000..260880e --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/results.cpp @@ -0,0 +1,601 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "results.hpp" + +#include "impl/realm_coordinator.hpp" +#include "impl/results_notifier.hpp" +#include "object_schema.hpp" +#include "object_store.hpp" +#include "schema.hpp" +#include "util/compiler.hpp" +#include "util/format.hpp" + +#include + +using namespace realm; + +Results::Results() = default; +Results::~Results() = default; + +Results::Results(SharedRealm r, Query q, SortDescriptor s) +: m_realm(std::move(r)) +, m_query(std::move(q)) +, m_table(m_query.get_table().get()) +, m_sort(std::move(s)) +, m_mode(Mode::Query) +{ +} + +Results::Results(SharedRealm r, Table& table) +: m_realm(std::move(r)) +, m_table(&table) +, m_mode(Mode::Table) +{ +} + +Results::Results(SharedRealm r, LinkViewRef lv, util::Optional q, SortDescriptor s) +: m_realm(std::move(r)) +, m_link_view(lv) +, m_table(&lv->get_target_table()) +, m_sort(std::move(s)) +, m_mode(Mode::LinkView) +{ + if (q) { + m_query = std::move(*q); + m_mode = Mode::Query; + } +} + +Results::Results(SharedRealm r, TableView tv, SortDescriptor s) +: m_realm(std::move(r)) +, m_table_view(std::move(tv)) +, m_table(&m_table_view.get_parent()) +, m_sort(std::move(s)) +, m_mode(Mode::TableView) +{ +} + +Results::Results(const Results&) = default; +Results& Results::operator=(const Results&) = default; + +Results::Results(Results&& other) +: m_realm(std::move(other.m_realm)) +, m_object_schema(std::move(other.m_object_schema)) +, m_query(std::move(other.m_query)) +, m_table_view(std::move(other.m_table_view)) +, m_link_view(std::move(other.m_link_view)) +, m_table(other.m_table) +, m_sort(std::move(other.m_sort)) +, m_notifier(std::move(other.m_notifier)) +, m_mode(other.m_mode) +, m_update_policy(other.m_update_policy) +, m_has_used_table_view(other.m_has_used_table_view) +, m_wants_background_updates(other.m_wants_background_updates) +{ + if (m_notifier) { + m_notifier->target_results_moved(other, *this); + } +} + +Results& Results::operator=(Results&& other) +{ + this->~Results(); + new (this) Results(std::move(other)); + return *this; +} + +bool Results::is_valid() const +{ + if (m_realm) + m_realm->verify_thread(); + + if (m_table && !m_table->is_attached()) + return false; + + return true; +} + +void Results::validate_read() const +{ + // is_valid ensures that we're on the correct thread. + if (!is_valid()) + throw InvalidatedException(); +} + +void Results::validate_write() const +{ + validate_read(); + if (!m_realm || !m_realm->is_in_transaction()) + throw InvalidTransactionException("Must be in a write transaction"); +} + +size_t Results::size() +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: return 0; + case Mode::Table: return m_table->size(); + case Mode::LinkView: return m_link_view->size(); + case Mode::Query: + m_query.sync_view_if_needed(); + return m_query.count(); + case Mode::TableView: + update_tableview(); + return m_table_view.size(); + } + REALM_UNREACHABLE(); +} + +const ObjectSchema& Results::get_object_schema() const +{ + validate_read(); + + if (!m_object_schema) { + REALM_ASSERT(m_realm); + auto it = m_realm->schema().find(get_object_type()); + REALM_ASSERT(it != m_realm->schema().end()); + m_object_schema = &*it; + } + + return *m_object_schema; +} + + +StringData Results::get_object_type() const noexcept +{ + if (!m_table) { + return StringData(); + } + + return ObjectStore::object_type_for_table_name(m_table->get_name()); +} + +RowExpr Results::get(size_t row_ndx) +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: break; + case Mode::Table: + if (row_ndx < m_table->size()) + return m_table->get(row_ndx); + break; + case Mode::LinkView: + if (update_linkview()) { + if (row_ndx < m_link_view->size()) + return m_link_view->get(row_ndx); + break; + } + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(); + if (row_ndx >= m_table_view.size()) + break; + if (m_update_policy == UpdatePolicy::Never && !m_table_view.is_row_attached(row_ndx)) + return {}; + return m_table_view.get(row_ndx); + } + + throw OutOfBoundsIndexException{row_ndx, size()}; +} + +util::Optional Results::first() +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: + return none; + case Mode::Table: + return m_table->size() == 0 ? util::none : util::make_optional(m_table->front()); + case Mode::LinkView: + if (update_linkview()) + return m_link_view->size() == 0 ? util::none : util::make_optional(m_link_view->get(0)); + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(); + return m_table_view.size() == 0 ? util::none : util::make_optional(m_table_view.front()); + } + REALM_UNREACHABLE(); +} + +util::Optional Results::last() +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: + return none; + case Mode::Table: + return m_table->size() == 0 ? util::none : util::make_optional(m_table->back()); + case Mode::LinkView: + if (update_linkview()) + return m_link_view->size() == 0 ? util::none : util::make_optional(m_link_view->get(m_link_view->size() - 1)); + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(); + return m_table_view.size() == 0 ? util::none : util::make_optional(m_table_view.back()); + } + REALM_UNREACHABLE(); +} + +bool Results::update_linkview() +{ + REALM_ASSERT(m_update_policy == UpdatePolicy::Auto); + + if (m_sort) { + m_query = get_query(); + m_mode = Mode::Query; + update_tableview(); + return false; + } + return true; +} + +void Results::update_tableview(bool wants_notifications) +{ + if (m_update_policy == UpdatePolicy::Never) { + REALM_ASSERT(m_mode == Mode::TableView); + return; + } + + switch (m_mode) { + case Mode::Empty: + case Mode::Table: + case Mode::LinkView: + return; + case Mode::Query: + m_query.sync_view_if_needed(); + m_table_view = m_query.find_all(); + if (m_sort) { + m_table_view.sort(m_sort); + } + m_mode = Mode::TableView; + break; + case Mode::TableView: + if (wants_notifications && !m_notifier && !m_realm->is_in_transaction() && m_realm->can_deliver_notifications()) { + m_notifier = std::make_shared<_impl::ResultsNotifier>(*this); + _impl::RealmCoordinator::register_notifier(m_notifier); + } + m_has_used_table_view = true; + m_table_view.sync_if_needed(); + break; + } +} + +size_t Results::index_of(Row const& row) +{ + validate_read(); + if (!row) { + throw DetatchedAccessorException{}; + } + if (m_table && row.get_table() != m_table) { + throw IncorrectTableException( + ObjectStore::object_type_for_table_name(m_table->get_name()), + ObjectStore::object_type_for_table_name(row.get_table()->get_name()), + "Attempting to get the index of a Row of the wrong type" + ); + } + return index_of(row.get_index()); +} + +size_t Results::index_of(size_t row_ndx) +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: + return not_found; + case Mode::Table: + return row_ndx; + case Mode::LinkView: + if (update_linkview()) + return m_link_view->find(row_ndx); + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(); + return m_table_view.find_by_source_ndx(row_ndx); + } + REALM_UNREACHABLE(); +} + +template +util::Optional Results::aggregate(size_t column, bool return_none_for_empty, + const char* name, + Int agg_int, Float agg_float, + Double agg_double, Timestamp agg_timestamp) +{ + validate_read(); + if (!m_table) + return none; + if (column > m_table->get_column_count()) + throw OutOfBoundsIndexException{column, m_table->get_column_count()}; + + auto do_agg = [&](auto const& getter) -> util::Optional { + switch (m_mode) { + case Mode::Empty: + return none; + case Mode::Table: + if (return_none_for_empty && m_table->size() == 0) + return none; + return util::Optional(getter(*m_table)); + case Mode::LinkView: + m_query = this->get_query(); + m_mode = Mode::Query; + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + this->update_tableview(); + if (return_none_for_empty && m_table_view.size() == 0) + return none; + return util::Optional(getter(m_table_view)); + } + REALM_UNREACHABLE(); + }; + + switch (m_table->get_column_type(column)) + { + case type_Timestamp: return do_agg(agg_timestamp); + case type_Double: return do_agg(agg_double); + case type_Float: return do_agg(agg_float); + case type_Int: return do_agg(agg_int); + default: + throw UnsupportedColumnTypeException{column, m_table, name}; + } +} + +util::Optional Results::max(size_t column) +{ + return aggregate(column, true, "max", + [=](auto const& table) { return table.maximum_int(column); }, + [=](auto const& table) { return table.maximum_float(column); }, + [=](auto const& table) { return table.maximum_double(column); }, + [=](auto const& table) { return table.maximum_timestamp(column); }); +} + +util::Optional Results::min(size_t column) +{ + return aggregate(column, true, "min", + [=](auto const& table) { return table.minimum_int(column); }, + [=](auto const& table) { return table.minimum_float(column); }, + [=](auto const& table) { return table.minimum_double(column); }, + [=](auto const& table) { return table.minimum_timestamp(column); }); +} + +util::Optional Results::sum(size_t column) +{ + return aggregate(column, false, "sum", + [=](auto const& table) { return table.sum_int(column); }, + [=](auto const& table) { return table.sum_float(column); }, + [=](auto const& table) { return table.sum_double(column); }, + [=](auto const&) -> util::None { throw UnsupportedColumnTypeException{column, m_table, "sum"}; }); +} + +util::Optional Results::average(size_t column) +{ + return aggregate(column, true, "average", + [=](auto const& table) { return table.average_int(column); }, + [=](auto const& table) { return table.average_float(column); }, + [=](auto const& table) { return table.average_double(column); }, + [=](auto const&) -> util::None { throw UnsupportedColumnTypeException{column, m_table, "average"}; }); +} + +void Results::clear() +{ + switch (m_mode) { + case Mode::Empty: + return; + case Mode::Table: + validate_write(); + m_table->clear(); + break; + case Mode::Query: + // Not using Query:remove() because building the tableview and + // clearing it is actually significantly faster + case Mode::TableView: + validate_write(); + update_tableview(); + + switch (m_update_policy) { + case UpdatePolicy::Auto: + m_table_view.clear(RemoveMode::unordered); + break; + case UpdatePolicy::Never: { + // Copy the TableView because a frozen Results shouldn't let its size() change. + TableView copy(m_table_view); + copy.clear(RemoveMode::unordered); + break; + } + } + break; + case Mode::LinkView: + validate_write(); + m_link_view->remove_all_target_rows(); + break; + } +} + +Query Results::get_query() const +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: + case Mode::Query: + return m_query; + case Mode::TableView: { + // A TableView has an associated Query if it was produced by Query::find_all. This is indicated + // by TableView::get_query returning a Query with a non-null table. + Query query = m_table_view.get_query(); + if (query.get_table()) { + return query; + } + + // The TableView has no associated query so create one with no conditions that is restricted + // to the rows in the TableView. + if (m_update_policy == UpdatePolicy::Auto) { + m_table_view.sync_if_needed(); + } + return Query(*m_table, std::unique_ptr(new TableView(m_table_view))); + } + case Mode::LinkView: + return m_table->where(m_link_view); + case Mode::Table: + return m_table->where(); + } + REALM_UNREACHABLE(); +} + +TableView Results::get_tableview() +{ + validate_read(); + switch (m_mode) { + case Mode::Empty: + return {}; + case Mode::LinkView: + if (update_linkview()) + return m_table->where(m_link_view).find_all(); + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(); + return m_table_view; + case Mode::Table: + return m_table->where().find_all(); + } + REALM_UNREACHABLE(); +} + +Results Results::sort(realm::SortDescriptor&& sort) const +{ + return Results(m_realm, get_query(), std::move(sort)); +} + +Results Results::filter(Query&& q) const +{ + return Results(m_realm, get_query().and_query(std::move(q)), m_sort); +} + +Results Results::snapshot() const & +{ + validate_read(); + + return Results(*this).snapshot(); +} + +Results Results::snapshot() && +{ + validate_read(); + + switch (m_mode) { + case Mode::Empty: + return Results(); + + case Mode::Table: + case Mode::LinkView: + m_query = get_query(); + m_mode = Mode::Query; + + REALM_FALLTHROUGH; + case Mode::Query: + case Mode::TableView: + update_tableview(false); + m_notifier.reset(); + m_update_policy = UpdatePolicy::Never; + return std::move(*this); + } + REALM_UNREACHABLE(); +} + +void Results::prepare_async() +{ + if (m_realm->config().read_only()) { + throw InvalidTransactionException("Cannot create asynchronous query for read-only Realms"); + } + if (m_realm->is_in_transaction()) { + throw InvalidTransactionException("Cannot create asynchronous query while in a write transaction"); + } + if (m_update_policy == UpdatePolicy::Never) { + throw std::logic_error("Cannot create asynchronous query for snapshotted Results."); + } + + if (!m_notifier) { + m_wants_background_updates = true; + m_notifier = std::make_shared<_impl::ResultsNotifier>(*this); + _impl::RealmCoordinator::register_notifier(m_notifier); + } +} + +NotificationToken Results::async(std::function target) +{ + prepare_async(); + auto wrap = [=](CollectionChangeSet, std::exception_ptr e) { target(e); }; + return {m_notifier, m_notifier->add_callback(wrap)}; +} + +NotificationToken Results::add_notification_callback(CollectionChangeCallback cb) +{ + prepare_async(); + return {m_notifier, m_notifier->add_callback(std::move(cb))}; +} + +bool Results::is_in_table_order() const +{ + switch (m_mode) { + case Mode::Empty: + case Mode::Table: + return true; + case Mode::LinkView: + return false; + case Mode::Query: + return m_query.produces_results_in_table_order() && !m_sort; + case Mode::TableView: + return m_table_view.is_in_table_order(); + } + REALM_UNREACHABLE(); // keep gcc happy +} + +void Results::Internal::set_table_view(Results& results, realm::TableView &&tv) +{ + REALM_ASSERT(results.m_update_policy != UpdatePolicy::Never); + // If the previous TableView was never actually used, then stop generating + // new ones until the user actually uses the Results object again + if (results.m_mode == Mode::TableView) { + results.m_wants_background_updates = results.m_has_used_table_view; + } + + results.m_table_view = std::move(tv); + results.m_mode = Mode::TableView; + results.m_has_used_table_view = false; + REALM_ASSERT(results.m_table_view.is_in_sync()); + REALM_ASSERT(results.m_table_view.is_attached()); +} + +Results::OutOfBoundsIndexException::OutOfBoundsIndexException(size_t r, size_t c) +: std::out_of_range(util::format("Requested index %1 greater than max %2", r, c)) +, requested(r), valid_count(c) {} + +Results::UnsupportedColumnTypeException::UnsupportedColumnTypeException(size_t column, const Table* table, const char* operation) +: std::logic_error(util::format("Cannot %1 property '%2': operation not supported for '%3' properties", + operation, table->get_column_name(column), + string_for_property_type(static_cast(table->get_column_type(column))))) +, column_index(column) +, column_name(table->get_column_name(column)) +, column_type(table->get_column_type(column)) +{ +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/schema.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/schema.cpp new file mode 100644 index 0000000..f45dd13 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/schema.cpp @@ -0,0 +1,214 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "schema.hpp" + +#include "object_schema.hpp" +#include "object_store.hpp" +#include "object_schema.hpp" +#include "property.hpp" + +#include + +using namespace realm; + +namespace realm { +bool operator==(Schema const& a, Schema const& b) +{ + return static_cast(a) == static_cast(b); +} +} + +Schema::Schema() = default; +Schema::~Schema() = default; +Schema::Schema(Schema const&) = default; +Schema::Schema(Schema &&) = default; +Schema& Schema::operator=(Schema const&) = default; +Schema& Schema::operator=(Schema&&) = default; + +Schema::Schema(std::initializer_list types) : Schema(base(types)) { } + +Schema::Schema(base types) : base(std::move(types)) +{ + std::sort(begin(), end(), [](ObjectSchema const& lft, ObjectSchema const& rgt) { + return lft.name < rgt.name; + }); +} + +Schema::iterator Schema::find(StringData name) +{ + auto it = std::lower_bound(begin(), end(), name, [](ObjectSchema const& lft, StringData rgt) { + return lft.name < rgt; + }); + if (it != end() && it->name != name) { + it = end(); + } + return it; +} + +Schema::const_iterator Schema::find(StringData name) const +{ + return const_cast(this)->find(name); +} + +Schema::iterator Schema::find(ObjectSchema const& object) noexcept +{ + return find(object.name); +} + +Schema::const_iterator Schema::find(ObjectSchema const& object) const noexcept +{ + return const_cast(this)->find(object); +} + +void Schema::validate() const +{ + std::vector exceptions; + for (auto const& object : *this) { + object.validate(*this, exceptions); + } + + if (exceptions.size()) { + throw SchemaValidationException(exceptions); + } +} + +namespace { +struct IsNotRemoveProperty { + bool operator()(SchemaChange sc) const { return sc.visit(*this); } + bool operator()(schema_change::RemoveProperty) const { return false; } + template bool operator()(T) const { return true; } +}; +struct GetRemovedColumn { + size_t operator()(SchemaChange sc) const { return sc.visit(*this); } + size_t operator()(schema_change::RemoveProperty p) const { return p.property->table_column; } + template size_t operator()(T) const { __builtin_unreachable(); } +}; +} + +static void compare(ObjectSchema const& existing_schema, + ObjectSchema const& target_schema, + std::vector& changes) +{ + for (auto& current_prop : existing_schema.persisted_properties) { + auto target_prop = target_schema.property_for_name(current_prop.name); + + if (!target_prop) { + changes.emplace_back(schema_change::RemoveProperty{&existing_schema, ¤t_prop}); + continue; + } + if (current_prop.type != target_prop->type || current_prop.object_type != target_prop->object_type) { + changes.emplace_back(schema_change::ChangePropertyType{&existing_schema, ¤t_prop, target_prop}); + continue; + } + if (current_prop.is_nullable != target_prop->is_nullable) { + if (current_prop.is_nullable) + changes.emplace_back(schema_change::MakePropertyRequired{&existing_schema, ¤t_prop}); + else + changes.emplace_back(schema_change::MakePropertyNullable{&existing_schema, ¤t_prop}); + } + if (target_prop->requires_index()) { + if (!current_prop.is_indexed) + changes.emplace_back(schema_change::AddIndex{&existing_schema, ¤t_prop}); + } + else if (current_prop.requires_index()) { + changes.emplace_back(schema_change::RemoveIndex{&existing_schema, ¤t_prop}); + } + } + + if (existing_schema.primary_key != target_schema.primary_key) { + changes.emplace_back(schema_change::ChangePrimaryKey{&existing_schema, target_schema.primary_key_property()}); + } + + for (auto& target_prop : target_schema.persisted_properties) { + if (!existing_schema.property_for_name(target_prop.name)) { + changes.emplace_back(schema_change::AddProperty{&existing_schema, &target_prop}); + } + } + + // Move all RemovePropertys to the end and sort in descending order of + // column index, as removing a column will shift all columns after that one + auto it = std::partition(begin(changes), end(changes), IsNotRemoveProperty{}); + std::sort(it, end(changes), + [](auto a, auto b) { return GetRemovedColumn()(a) > GetRemovedColumn()(b); }); +} + +std::vector Schema::compare(Schema const& target_schema) const +{ + std::vector changes; + for (auto &object_schema : target_schema) { + auto matching_schema = find(object_schema); + if (matching_schema == end()) { + changes.emplace_back(schema_change::AddTable{&object_schema}); + continue; + } + + ::compare(*matching_schema, object_schema, changes); + } + return changes; +} + +void Schema::copy_table_columns_from(realm::Schema const& other) +{ + for (auto& source_schema : other) { + auto matching_schema = find(source_schema); + if (matching_schema == end()) { + continue; + } + + for (auto& current_prop : source_schema.persisted_properties) { + auto target_prop = matching_schema->property_for_name(current_prop.name); + if (target_prop) { + target_prop->table_column = current_prop.table_column; + } + } + } +} + +namespace realm { +bool operator==(SchemaChange const& lft, SchemaChange const& rgt) +{ + if (lft.m_kind != rgt.m_kind) + return false; + + using namespace schema_change; + struct Visitor { + SchemaChange const& value; + + #define REALM_SC_COMPARE(type, ...) \ + bool operator()(type rgt) const \ + { \ + auto cmp = [](auto&& v) { return std::tie(__VA_ARGS__); }; \ + return cmp(value.type) == cmp(rgt); \ + } + + REALM_SC_COMPARE(AddIndex, v.object, v.property) + REALM_SC_COMPARE(AddProperty, v.object, v.property) + REALM_SC_COMPARE(AddTable, v.object) + REALM_SC_COMPARE(ChangePrimaryKey, v.object, v.property) + REALM_SC_COMPARE(ChangePropertyType, v.object, v.old_property, v.new_property) + REALM_SC_COMPARE(MakePropertyNullable, v.object, v.property) + REALM_SC_COMPARE(MakePropertyRequired, v.object, v.property) + REALM_SC_COMPARE(RemoveIndex, v.object, v.property) + REALM_SC_COMPARE(RemoveProperty, v.object, v.property) + + #undef REALM_SC_COMPARE + } visitor{lft}; + return rgt.visit(visitor); +} +} // namespace realm diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/shared_realm.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/shared_realm.cpp new file mode 100644 index 0000000..141fc8d --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/shared_realm.cpp @@ -0,0 +1,671 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "shared_realm.hpp" + +#include "impl/handover.hpp" +#include "impl/realm_coordinator.hpp" +#include "impl/transact_log_handler.hpp" + +#include "binding_context.hpp" +#include "object_schema.hpp" +#include "object_store.hpp" +#include "schema.hpp" +#include "thread_confined.hpp" + +#include "util/format.hpp" + +#include +#include + +using namespace realm; +using namespace realm::_impl; + +Realm::Realm(Config config) +: m_config(std::move(config)) +{ + open_with_config(m_config, m_history, m_shared_group, m_read_only_group, this); + + if (m_read_only_group) { + m_group = m_read_only_group.get(); + } +} + +void Realm::init(std::shared_ptr<_impl::RealmCoordinator> coordinator) +{ + // if there is an existing realm at the current path steal its schema/column mapping + if (auto existing = coordinator ? coordinator->get_schema() : nullptr) { + m_schema = *existing; + m_schema_version = coordinator->get_schema_version(); + } + else { + // otherwise get the schema from the group + m_schema_version = ObjectStore::get_schema_version(read_group()); + m_schema = ObjectStore::schema_from_group(read_group()); + + if (m_shared_group) { + m_schema_transaction_version = m_shared_group->get_version_of_current_transaction().version; + m_shared_group->end_read(); + m_group = nullptr; + } + } + + m_coordinator = std::move(coordinator); + + if (m_config.schema) { + try { + auto schema = std::move(*m_config.schema); + m_config.schema = util::none; + update_schema(std::move(schema), m_config.schema_version, + std::move(m_config.migration_function)); + } + catch (...) { + m_coordinator = nullptr; // don't try to unregister in the destructor as it'll deadlock + throw; + } + } + +} + +REALM_NOINLINE static void translate_file_exception(StringData path, bool read_only=false) +{ + try { + throw; + } + catch (util::File::PermissionDenied const& ex) { + throw RealmFileException(RealmFileException::Kind::PermissionDenied, ex.get_path(), + util::format("Unable to open a realm at path '%1'. Please use a path where your app has %2 permissions.", + ex.get_path(), read_only ? "read" : "read-write"), + ex.what()); + } + catch (util::File::Exists const& ex) { + throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(), + util::format("File at path '%1' already exists.", ex.get_path()), + ex.what()); + } + catch (util::File::NotFound const& ex) { + throw RealmFileException(RealmFileException::Kind::NotFound, ex.get_path(), + util::format("Directory at path '%1' does not exist.", ex.get_path()), ex.what()); + } + catch (util::File::AccessError const& ex) { + // Errors for `open()` include the path, but other errors don't. We + // don't want two copies of the path in the error, so strip it out if it + // appears, and then include it in our prefix. + std::string underlying = ex.what(); + auto pos = underlying.find(ex.get_path()); + if (pos != std::string::npos && pos > 0) { + // One extra char at each end for the quotes + underlying.replace(pos - 1, ex.get_path().size() + 2, ""); + } + throw RealmFileException(RealmFileException::Kind::AccessError, ex.get_path(), + util::format("Unable to open a realm at path '%1': %2.", ex.get_path(), underlying), ex.what()); + } + catch (IncompatibleLockFile const& ex) { + throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, path, + "Realm file is currently open in another process " + "which cannot share access with this process. " + "All processes sharing a single file must be the same architecture.", + ex.what()); + } + catch (FileFormatUpgradeRequired const& ex) { + throw RealmFileException(RealmFileException::Kind::FormatUpgradeRequired, path, + "The Realm file format must be allowed to be upgraded " + "in order to proceed.", + ex.what()); + } +} + +void Realm::open_with_config(const Config& config, + std::unique_ptr& history, + std::unique_ptr& shared_group, + std::unique_ptr& read_only_group, + Realm* realm) +{ + if (config.encryption_key.data() && config.encryption_key.size() != 64) { + throw InvalidEncryptionKeyException(); + } + try { + if (config.read_only()) { + read_only_group = std::make_unique(config.path, config.encryption_key.data(), Group::mode_ReadOnly); + } + else { + history = realm::make_client_history(config.path, config.encryption_key.data()); + SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly : + SharedGroup::durability_Full; + shared_group = std::make_unique(*history, durability, config.encryption_key.data(), !config.disable_format_upgrade, + [&](int from_version, int to_version) { + if (realm) { + realm->upgrade_initial_version = from_version; + realm->upgrade_final_version = to_version; + } + }); + } + } + catch (...) { + translate_file_exception(config.path, config.read_only()); + } +} + +Realm::~Realm() +{ + if (m_coordinator) { + m_coordinator->unregister_realm(this); + } +} + +Group& Realm::read_group() +{ + if (!m_group) { + m_group = &const_cast(m_shared_group->begin_read()); + add_schema_change_handler(); + } + return *m_group; +} + +SharedRealm Realm::get_shared_realm(Config config) +{ + auto coordinator = RealmCoordinator::get_coordinator(config.path); + return coordinator->get_realm(std::move(config)); +} + +void Realm::set_schema(Schema schema, uint64_t version) +{ + schema.copy_table_columns_from(m_schema); + m_schema = schema; + m_coordinator->update_schema(schema, version); +} + +bool Realm::read_schema_from_group_if_needed() +{ + // schema of read-only Realms can't change + if (m_read_only_group) + return false; + + Group& group = read_group(); + auto current_version = m_shared_group->get_version_of_current_transaction().version; + if (m_schema_transaction_version == current_version) + return false; + + m_schema = ObjectStore::schema_from_group(group); + m_schema_version = ObjectStore::get_schema_version(group); + m_schema_transaction_version = current_version; + return true; +} + +void Realm::reset_file_if_needed(Schema const& schema, uint64_t version, std::vector& required_changes) +{ + if (m_schema_version == ObjectStore::NotVersioned) + return; + if (m_schema_version == version && !ObjectStore::needs_migration(required_changes)) + return; + + // FIXME: this does not work if multiple processes try to open the file at + // the same time, or even multiple threads if there is not any external + // synchronization. The latter is probably fixable, but making it + // multi-process-safe requires some sort of multi-process exclusive lock + m_group = nullptr; + m_shared_group = nullptr; + m_history = nullptr; + util::File::remove(m_config.path); + + open_with_config(m_config, m_history, m_shared_group, m_read_only_group, this); + m_schema = ObjectStore::schema_from_group(read_group()); + m_schema_version = ObjectStore::get_schema_version(read_group()); + required_changes = m_schema.compare(schema); +} + +void Realm::update_schema(Schema schema, uint64_t version, MigrationFunction migration_function) +{ + schema.validate(); + read_schema_from_group_if_needed(); + std::vector required_changes = m_schema.compare(schema); + + auto no_changes_required = [&] { + switch (m_config.schema_mode) { + case SchemaMode::Automatic: + if (version < m_schema_version && m_schema_version != ObjectStore::NotVersioned) { + throw InvalidSchemaVersionException(m_schema_version, version); + } + if (version == m_schema_version) { + if (required_changes.empty()) { + set_schema(std::move(schema), version); + return true; + } + ObjectStore::verify_no_migration_required(required_changes); + } + return false; + + case SchemaMode::ReadOnly: + if (version != m_schema_version) + throw InvalidSchemaVersionException(m_schema_version, version); + ObjectStore::verify_no_migration_required(m_schema.compare(schema)); + set_schema(std::move(schema), version); + return true; + + case SchemaMode::ResetFile: + reset_file_if_needed(schema, version, required_changes); + return required_changes.empty(); + + case SchemaMode::Additive: + if (required_changes.empty()) { + set_schema(std::move(schema), version); + return version == m_schema_version; + } + ObjectStore::verify_valid_additive_changes(required_changes); + return false; + + case SchemaMode::Manual: + if (version < m_schema_version && m_schema_version != ObjectStore::NotVersioned) { + throw InvalidSchemaVersionException(m_schema_version, version); + } + if (version == m_schema_version) { + ObjectStore::verify_no_changes_required(required_changes); + return true; + } + return false; + } + __builtin_unreachable(); + }; + + if (no_changes_required()) + return; + // Either the schema version has changed or we need to do non-migration changes + + m_group->set_schema_change_notification_handler(nullptr); + transaction::begin_without_validation(*m_shared_group); + add_schema_change_handler(); + + // Cancel the write transaction if we exit this function before committing it + struct WriteTransactionGuard { + Realm& realm; + ~WriteTransactionGuard() { if (realm.is_in_transaction()) realm.cancel_transaction(); } + } write_transaction_guard{*this}; + + // If beginning the write transaction advanced the version, then someone else + // may have updated the schema and we need to re-read it + // We can't just begin the write transaction before checking anything because + // that means that write transactions would block opening Realms in other processes + if (read_schema_from_group_if_needed()) { + required_changes = m_schema.compare(schema); + if (no_changes_required()) + return; + } + + bool additive = m_config.schema_mode == SchemaMode::Additive; + if (migration_function && !additive) { + auto wrapper = [&] { + SharedRealm old_realm(new Realm(m_config)); + old_realm->init(nullptr); + // Need to open in read-write mode so that it uses a SharedGroup, but + // users shouldn't actually be able to write via the old realm + old_realm->m_config.schema_mode = SchemaMode::ReadOnly; + + migration_function(old_realm, shared_from_this(), m_schema); + }; + ObjectStore::apply_schema_changes(read_group(), m_schema, m_schema_version, + schema, version, m_config.schema_mode, required_changes, wrapper); + } + else { + ObjectStore::apply_schema_changes(read_group(), m_schema, m_schema_version, + schema, version, m_config.schema_mode, required_changes); + REALM_ASSERT_DEBUG(additive || (required_changes = ObjectStore::schema_from_group(read_group()).compare(schema)).empty()); + } + + commit_transaction(); + m_coordinator->update_schema(m_schema, version); +} + +void Realm::add_schema_change_handler() +{ + if (m_config.schema_mode == SchemaMode::Additive) { + m_group->set_schema_change_notification_handler([&] { + auto new_schema = ObjectStore::schema_from_group(read_group()); + auto required_changes = m_schema.compare(new_schema); + ObjectStore::verify_valid_additive_changes(required_changes); + m_schema.copy_table_columns_from(new_schema); + }); + } +} + +static void check_read_write(Realm *realm) +{ + if (realm->config().read_only()) { + throw InvalidTransactionException("Can't perform transactions on read-only Realms."); + } +} + +void Realm::verify_thread() const +{ + if (m_thread_id != std::this_thread::get_id()) { + throw IncorrectThreadException(); + } +} + +void Realm::verify_in_write() const +{ + if (!is_in_transaction()) { + throw InvalidTransactionException("Cannot modify managed objects outside of a write transaction."); + } +} + +bool Realm::is_in_transaction() const noexcept +{ + if (!m_shared_group) { + return false; + } + return m_shared_group->get_transact_stage() == SharedGroup::transact_Writing; +} + +void Realm::begin_transaction() +{ + check_read_write(this); + verify_thread(); + + if (is_in_transaction()) { + throw InvalidTransactionException("The Realm is already in a write transaction"); + } + + // make sure we have a read transaction + read_group(); + + transaction::begin(*m_shared_group, m_binding_context.get(), m_config.schema_mode); +} + +void Realm::commit_transaction() +{ + check_read_write(this); + verify_thread(); + + if (!is_in_transaction()) { + throw InvalidTransactionException("Can't commit a non-existing write transaction"); + } + + transaction::commit(*m_shared_group, m_binding_context.get()); + m_coordinator->send_commit_notifications(); +} + +void Realm::cancel_transaction() +{ + check_read_write(this); + verify_thread(); + + if (!is_in_transaction()) { + throw InvalidTransactionException("Can't cancel a non-existing write transaction"); + } + + transaction::cancel(*m_shared_group, m_binding_context.get()); +} + +void Realm::invalidate() +{ + verify_thread(); + check_read_write(this); + + if (is_in_transaction()) { + cancel_transaction(); + } + if (!m_group) { + return; + } + + m_shared_group->end_read(); + m_group = nullptr; +} + +bool Realm::compact() +{ + verify_thread(); + + if (m_config.read_only()) { + throw InvalidTransactionException("Can't compact a read-only Realm"); + } + if (is_in_transaction()) { + throw InvalidTransactionException("Can't compact a Realm within a write transaction"); + } + + Group& group = read_group(); + for (auto &object_schema : m_schema) { + ObjectStore::table_for_object_type(group, object_schema.name)->optimize(); + } + m_shared_group->end_read(); + m_group = nullptr; + + return m_shared_group->compact(); +} + +void Realm::write_copy(StringData path, BinaryData key) +{ + if (key.data() && key.size() != 64) { + throw InvalidEncryptionKeyException(); + } + verify_thread(); + try { + read_group().write(path, key.data()); + } + catch (...) { + translate_file_exception(path); + } +} + +void Realm::notify() +{ + if (is_closed()) { + return; + } + + verify_thread(); + + if (m_shared_group->has_changed()) { // Throws + if (m_binding_context) { + m_binding_context->changes_available(); + } + if (m_auto_refresh) { + if (m_group) { + m_coordinator->advance_to_ready(*this); + } + else if (m_binding_context) { + m_binding_context->did_change({}, {}); + } + } + } + else { + m_coordinator->process_available_async(*this); + } +} + +bool Realm::refresh() +{ + verify_thread(); + check_read_write(this); + + // can't be any new changes if we're in a write transaction + if (is_in_transaction()) { + return false; + } + + // advance transaction if database has changed + if (!m_shared_group->has_changed()) { // Throws + return false; + } + + if (m_group) { + transaction::advance(*m_shared_group, m_binding_context.get(), m_config.schema_mode); + m_coordinator->process_available_async(*this); + } + else { + // Create the read transaction + read_group(); + } + + return true; +} + +bool Realm::can_deliver_notifications() const noexcept +{ + if (m_config.read_only()) { + return false; + } + + if (m_binding_context && !m_binding_context->can_deliver_notifications()) { + return false; + } + + return true; +} + +uint64_t Realm::get_schema_version(const realm::Realm::Config &config) +{ + auto coordinator = RealmCoordinator::get_existing_coordinator(config.path); + if (coordinator) { + return coordinator->get_schema_version(); + } + + return ObjectStore::get_schema_version(Realm(config).read_group()); +} + +void Realm::close() +{ + if (m_coordinator) { + m_coordinator->unregister_realm(this); + } + + m_group = nullptr; + m_shared_group = nullptr; + m_history = nullptr; + m_read_only_group = nullptr; + m_binding_context = nullptr; + m_coordinator = nullptr; +} + +util::Optional Realm::file_format_upgraded_from_version() const +{ + if (upgrade_initial_version != upgrade_final_version) { + return upgrade_initial_version; + } + return util::none; +} + +Realm::HandoverPackage::HandoverPackage(HandoverPackage&&) = default; +Realm::HandoverPackage& Realm::HandoverPackage::operator=(HandoverPackage&&) = default; +Realm::HandoverPackage::VersionID::VersionID() : VersionID(SharedGroup::VersionID()) { }; + +// Precondition: `m_version` is not greater than `new_version` +// Postcondition: `m_version` is equal to `new_version` +void Realm::HandoverPackage::advance_to_version(VersionID new_version) +{ + if (SharedGroup::VersionID(new_version) == SharedGroup::VersionID(m_version_id)) { + return; + } + REALM_ASSERT_DEBUG((SharedGroup::VersionID(new_version) > SharedGroup::VersionID(m_version_id))); + + // Open `Realm` at handover version + _impl::RealmCoordinator& coordinator = get_coordinator(); + Realm::Config config = coordinator.get_config(); + config.cache = false; + SharedRealm realm = coordinator.get_realm(config); + REALM_ASSERT(!realm->is_in_read_transaction()); + realm->m_group = &const_cast(realm->m_shared_group->begin_read(m_version_id)); + + // Import handover, advance version, and then repackage for handover + auto objects = realm->accept_handover(std::move(*this)); + transaction::advance(*realm->m_shared_group, realm->m_binding_context.get(), + realm->m_config.schema_mode, new_version); + *this = realm->package_for_handover(std::move(objects)); +} + +Realm::HandoverPackage::~HandoverPackage() +{ + if (is_awaiting_import()) { + get_coordinator().get_realm()->m_shared_group->unpin_version(m_version_id); + mark_not_awaiting_import(); + } +} + +Realm::HandoverPackage Realm::package_for_handover(std::vector objects_to_hand_over) +{ + verify_thread(); + if (is_in_transaction()) { + throw InvalidTransactionException("Cannot package handover during a write transaction."); + } + + HandoverPackage handover; + auto version_id = m_shared_group->pin_version(); + handover.m_version_id = version_id; + handover.m_source_realm = shared_from_this(); + // Since `m_source_realm` is used to determine if we need to unpin when destroyed, + // `m_source_realm` should only be set after `pin_version` succeeds in case it throws. + + handover.m_objects.reserve(objects_to_hand_over.size()); + for (auto &object : objects_to_hand_over) { + REALM_ASSERT(object.get_realm().get() == this); + handover.m_objects.push_back(object.export_for_handover()); + } + + return handover; +} + +std::vector Realm::accept_handover(Realm::HandoverPackage handover) +{ + verify_thread(); + + if (!handover.is_awaiting_import()) { + throw std::logic_error("Handover package must not be imported more than once."); + } + + auto unpin_version = util::make_scope_exit([&]() noexcept { + m_shared_group->unpin_version(handover.m_version_id); + handover.mark_not_awaiting_import(); + }); + + if (is_in_transaction()) { + throw InvalidTransactionException("Cannot accept handover during a write transaction."); + } + + // Ensure we're on the same version as the handover + if (!m_group) { + // A read transaction doesn't yet exist, so create at the handover version + m_group = &const_cast(m_shared_group->begin_read(handover.m_version_id)); + } + else { + auto current_version = m_shared_group->get_version_of_current_transaction(); + + if (SharedGroup::VersionID(handover.m_version_id) <= current_version) { + // The handover is behind, so advance it to our version + handover.advance_to_version(current_version); + } else { + // We're behind, so advance to the handover's version + transaction::advance(*m_shared_group, m_binding_context.get(), + m_config.schema_mode, handover.m_version_id); + m_coordinator->process_available_async(*this); + } + } + + std::vector objects; + objects.reserve(handover.m_objects.size()); + for (auto &object : handover.m_objects) { + objects.push_back(std::move(object).import_from_handover(shared_from_this())); + } + + // Avoid weird partial-refresh semantics when importing old packages + refresh(); + + return objects; +} + +MismatchedConfigException::MismatchedConfigException(StringData message, StringData path) +: std::logic_error(util::format(message.data(), path)) { } diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/thread_confined.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/thread_confined.cpp new file mode 100644 index 0000000..0db0d57 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/thread_confined.cpp @@ -0,0 +1,126 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "thread_confined.hpp" + +#include "impl/handover.hpp" + +using namespace realm; + +AnyThreadConfined::AnyThreadConfined(const AnyThreadConfined& thread_confined) +{ + switch (thread_confined.m_type) { + case Type::Object: + new (&m_object) Object(thread_confined.m_object); + break; + + case Type::List: + new (&m_list) List(thread_confined.m_list); + break; + + case Type::Results: + new (&m_results) Results(thread_confined.m_results); + break; + } + new (&m_type) Type(thread_confined.m_type); +} + +AnyThreadConfined& AnyThreadConfined::operator=(const AnyThreadConfined& thread_confined) +{ + this->~AnyThreadConfined(); + new (this) AnyThreadConfined(thread_confined); + return *this; +} + +AnyThreadConfined::AnyThreadConfined(AnyThreadConfined&& thread_confined) +{ + switch (thread_confined.m_type) { + case Type::Object: + new (&m_object) Object(std::move(thread_confined.m_object)); + break; + + case Type::List: + new (&m_list) List(std::move(thread_confined.m_list)); + break; + + case Type::Results: + new (&m_results) Results(std::move(thread_confined.m_results)); + break; + } + new (&m_type) Type(std::move(thread_confined.m_type)); +} + +AnyThreadConfined& AnyThreadConfined::operator=(AnyThreadConfined&& thread_confined) +{ + this->~AnyThreadConfined(); + new (this) AnyThreadConfined(std::move(thread_confined)); + return *this; +} + +AnyThreadConfined::~AnyThreadConfined() +{ + switch (m_type) { + case Type::Object: + m_object.~Object(); + break; + + case Type::List: + m_list.~List(); + break; + + case Type::Results: + m_results.~Results(); + break; + } +} + +SharedRealm AnyThreadConfined::get_realm() const +{ + switch (m_type) { + case Type::Object: + return m_object.realm(); + + case Type::List: + return m_list.get_realm(); + + case Type::Results: + return m_results.get_realm(); + } + REALM_UNREACHABLE(); +} + +_impl::AnyHandover AnyThreadConfined::export_for_handover() const +{ + SharedGroup& shared_group = Realm::Internal::get_shared_group(*get_realm()); + switch (m_type) { + case AnyThreadConfined::Type::Object: + return _impl::AnyHandover(shared_group.export_for_handover(m_object.row()), + m_object.get_object_schema().name); + + case AnyThreadConfined::Type::List: + return _impl::AnyHandover(shared_group.export_linkview_for_handover(m_list.m_link_view)); + + case AnyThreadConfined::Type::Results: { + SortDescriptor::HandoverPatch sort_order; + SortDescriptor::generate_patch(m_results.get_sort(), sort_order); + return _impl::AnyHandover(shared_group.export_for_handover(m_results.get_query(), ConstSourcePayload::Copy), + std::move(sort_order)); + } + } + REALM_UNREACHABLE(); +} diff --git a/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/util/format.cpp b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/util/format.cpp new file mode 100644 index 0000000..4103c8d --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/ObjectStore/src/util/format.cpp @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include "util/format.hpp" + +#include + +#include +#include + +namespace realm { namespace _impl { +Printable::Printable(StringData value) : m_type(Type::String), m_string(value.data()) { } + +void Printable::print(std::ostream& out) const +{ + switch (m_type) { + case Printable::Type::Bool: + out << (m_uint ? "true" : "false"); + break; + case Printable::Type::Uint: + out << m_uint; + break; + case Printable::Type::Int: + out << m_int; + break; + case Printable::Type::String: + out << m_string; + break; + } +} + +std::string format(const char* fmt, std::initializer_list values) +{ + std::stringstream ss; + while (*fmt) { + auto next = strchr(fmt, '%'); + + // emit the rest of the format string if there are no more percents + if (!next) { + ss << fmt; + break; + } + + // emit everything up to the next percent + ss.write(fmt, next - fmt); + ++next; + REALM_ASSERT(*next); + + // %% produces a single escaped % + if (*next == '%') { + ss << '%'; + fmt = next + 1; + continue; + } + REALM_ASSERT(isdigit(*next)); + + // The const_cast is safe because stroul does not actually modify + // the pointed-to string, but it lacks a const overload + auto index = strtoul(next, const_cast(&fmt), 10) - 1; + REALM_ASSERT(index < values.size()); + (values.begin() + index)->print(ss); + } + return ss.str(); +} + +} // namespace _impl +} // namespace realm diff --git a/SiriKitExample/Pods/Realm/Realm/RLMAccessor.mm b/SiriKitExample/Pods/Realm/Realm/RLMAccessor.mm new file mode 100644 index 0000000..b833e12 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMAccessor.mm @@ -0,0 +1,800 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMAccessor.h" + +#import "RLMArray_Private.hpp" +#import "RLMListBase.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObject_Private.hpp" +#import "RLMObservation.hpp" +#import "RLMProperty_Private.h" +#import "RLMRealm_Private.hpp" +#import "RLMResults_Private.h" +#import "RLMSchema_Private.h" +#import "RLMUtil.hpp" +#import "results.hpp" +#import "property.hpp" + +#import +#import + +typedef NS_ENUM(char, RLMAccessorCode) { + RLMAccessorCodeByte, + RLMAccessorCodeShort, + RLMAccessorCodeInt, + RLMAccessorCodeLong, + RLMAccessorCodeLongLong, + RLMAccessorCodeFloat, + RLMAccessorCodeDouble, + RLMAccessorCodeBool, + RLMAccessorCodeString, + RLMAccessorCodeDate, + RLMAccessorCodeData, + RLMAccessorCodeLink, + RLMAccessorCodeArray, + RLMAccessorCodeLinkingObjects, + RLMAccessorCodeAny, + + RLMAccessorCodeIntObject, + RLMAccessorCodeFloatObject, + RLMAccessorCodeDoubleObject, + RLMAccessorCodeBoolObject, +}; + +template +static T get(__unsafe_unretained RLMObjectBase *const obj, NSUInteger index) { + RLMVerifyAttached(obj); + return obj->_row.get_table()->get(obj->_info->objectSchema->persisted_properties[index].table_column, obj->_row.get_index()); +} + +template +static NSNumber *getBoxed(__unsafe_unretained RLMObjectBase *const obj, NSUInteger index) { + RLMVerifyAttached(obj); + auto col = obj->_info->objectSchema->persisted_properties[index].table_column; + if (obj->_row.is_null(col)) { + return nil; + } + return @(obj->_row.get_table()->get(col, obj->_row.get_index())); +} + + +// long getter/setter +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, long long val) { + RLMVerifyInWriteTransaction(obj); + obj->_row.set_int(colIndex, val); +} + +// float getter/setter +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, float val) { + RLMVerifyInWriteTransaction(obj); + obj->_row.set_float(colIndex, val); +} + +// double getter/setter +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, double val) { + RLMVerifyInWriteTransaction(obj); + obj->_row.set_double(colIndex, val); +} + +// bool getter/setter +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, BOOL val) { + RLMVerifyInWriteTransaction(obj); + obj->_row.set_bool(colIndex, val); +} + +// string getter/setter +static inline NSString *RLMGetString(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex) { + return RLMStringDataToNSString(get(obj, colIndex)); +} +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, __unsafe_unretained NSString *const val) { + RLMVerifyInWriteTransaction(obj); + try { + obj->_row.set_string(colIndex, RLMStringDataWithNSString(val)); + } + catch (std::exception const& e) { + @throw RLMException(e); + } +} + +// date getter/setter +static inline NSDate *RLMGetDate(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex) { + return RLMTimestampToNSDate(get(obj, colIndex)); +} +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, __unsafe_unretained NSDate *const date) { + RLMVerifyInWriteTransaction(obj); + if (date) { + obj->_row.set_timestamp(colIndex, RLMTimestampForNSDate(date)); + } + else { + obj->_row.set_null(colIndex); + } +} + +// data getter/setter +static inline NSData *RLMGetData(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex) { + return RLMBinaryDataToNSData(get(obj, colIndex)); +} +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, __unsafe_unretained NSData *const data) { + RLMVerifyInWriteTransaction(obj); + + try { + obj->_row.set_binary(colIndex, RLMBinaryDataForNSData(data)); + } + catch (std::exception const& e) { + @throw RLMException(e); + } +} + +static inline RLMObjectBase *RLMGetLinkedObjectForValue(__unsafe_unretained RLMRealm *const realm, + __unsafe_unretained NSString *const className, + __unsafe_unretained id const value, + RLMCreationOptions creationOptions) NS_RETURNS_RETAINED; +static inline RLMObjectBase *RLMGetLinkedObjectForValue(__unsafe_unretained RLMRealm *const realm, + __unsafe_unretained NSString *const className, + __unsafe_unretained id const value, + RLMCreationOptions creationOptions) { + RLMObjectBase *link = RLMDynamicCast(value); + if (!link || ![link->_objectSchema.className isEqualToString:className]) { + // create from non-rlmobject + return RLMCreateObjectInRealmWithValue(realm, className, value, creationOptions & RLMCreationOptionsCreateOrUpdate); + } + + if (link.isInvalidated) { + @throw RLMException(@"Adding a deleted or invalidated object to a Realm is not permitted"); + } + + if (link->_realm == realm) { + return link; + } + + if (creationOptions & RLMCreationOptionsPromoteUnmanaged) { + if (!link->_realm) { + RLMAddObjectToRealm(link, realm, creationOptions & RLMCreationOptionsCreateOrUpdate); + return link; + } + @throw RLMException(@"Can not add objects from a different Realm"); + } + + // copy from another realm or copy from unmanaged + return RLMCreateObjectInRealmWithValue(realm, className, link, creationOptions & RLMCreationOptionsCreateOrUpdate); +} + +// link getter/setter +static inline RLMObjectBase *RLMGetLink(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex) { + RLMVerifyAttached(obj); + auto col = obj->_info->objectSchema->persisted_properties[colIndex].table_column; + + if (obj->_row.is_null_link(col)) { + return nil; + } + NSUInteger index = obj->_row.get_link(col); + return RLMCreateObjectAccessor(obj->_realm, obj->_info->linkTargetType(colIndex), index); +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained RLMObjectBase *const val) { + RLMVerifyInWriteTransaction(obj); + if (!val) { + obj->_row.nullify_link(colIndex); + return; + } + + RLMObjectBase *link = RLMGetLinkedObjectForValue(obj->_realm, val->_objectSchema.className, + val, RLMCreationOptionsPromoteUnmanaged); + + // make sure it is the correct type + if (link->_row.get_table() != obj->_row.get_table()->get_link_target(colIndex)) { + @throw RLMException(@"Can't set object of type '%@' to property of type '%@'", + val->_objectSchema.className, + obj->_info->propertyForTableColumn(colIndex).objectClassName); + } + obj->_row.set_link(colIndex, link->_row.get_index()); +} + +// array getter/setter +static inline RLMArray *RLMGetArray(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex) { + RLMVerifyAttached(obj); + auto prop = obj->_info->rlmObjectSchema.properties[colIndex]; + return [[RLMArrayLinkView alloc] initWithParent:obj property:prop]; +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained id const array) { + RLMVerifyInWriteTransaction(obj); + + realm::LinkViewRef linkView = obj->_row.get_linklist(colIndex); + // remove all old + // FIXME: make sure delete rules don't purge objects + linkView->clear(); + for (RLMObjectBase *link in array) { + RLMObjectBase * addedLink = RLMGetLinkedObjectForValue(obj->_realm, link->_objectSchema.className, link, RLMCreationOptionsPromoteUnmanaged); + linkView->add(addedLink->_row.get_index()); + } +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained NSNumber *const intObject) { + RLMVerifyInWriteTransaction(obj); + + if (intObject) { + obj->_row.set_int(colIndex, intObject.longLongValue); + } + else { + obj->_row.set_null(colIndex); + } +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained NSNumber *const floatObject) { + RLMVerifyInWriteTransaction(obj); + + if (floatObject) { + obj->_row.set_float(colIndex, floatObject.floatValue); + } + else { + obj->_row.set_null(colIndex); + } +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained NSNumber *const doubleObject) { + RLMVerifyInWriteTransaction(obj); + + if (doubleObject) { + obj->_row.set_double(colIndex, doubleObject.doubleValue); + } + else { + obj->_row.set_null(colIndex); + } +} + +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, + __unsafe_unretained NSNumber *const boolObject) { + RLMVerifyInWriteTransaction(obj); + + if (boolObject) { + obj->_row.set_bool(colIndex, boolObject.boolValue); + } + else { + obj->_row.set_null(colIndex); + } +} + +static inline RLMLinkingObjects *RLMGetLinkingObjects(__unsafe_unretained RLMObjectBase *const obj, + __unsafe_unretained RLMProperty *const property) { + auto& objectInfo = obj->_realm->_info[property.objectClassName]; + auto linkingProperty = objectInfo.objectSchema->property_for_name(property.linkOriginPropertyName.UTF8String); + auto backlinkView = obj->_row.get_table()->get_backlink_view(obj->_row.get_index(), objectInfo.table(), linkingProperty->table_column); + realm::Results results(obj->_realm->_realm, std::move(backlinkView)); + return [RLMLinkingObjects resultsWithObjectInfo:objectInfo results:std::move(results)]; +} + +// any getter/setter +static inline id RLMGetAnyProperty(__unsafe_unretained RLMObjectBase *const obj, NSUInteger col_ndx) { + RLMVerifyAttached(obj); + return RLMMixedToObjc(obj->_row.get_mixed(col_ndx)); +} +static inline void RLMSetValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger, __unsafe_unretained id) { + RLMVerifyInWriteTransaction(obj); + @throw RLMException(@"Modifying Mixed properties is not supported"); +} + +// dynamic getter with column closure +static IMP RLMAccessorGetter(RLMProperty *prop, RLMAccessorCode accessorCode) { + NSUInteger index = prop.index; + switch (accessorCode) { + case RLMAccessorCodeByte: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return (char)get(obj, index); + }); + case RLMAccessorCodeShort: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return (short)get(obj, index); + }); + case RLMAccessorCodeInt: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return (int)get(obj, index); + }); + case RLMAccessorCodeLongLong: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return get(obj, index); + }); + case RLMAccessorCodeLong: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return (long)get(obj, index); + }); + case RLMAccessorCodeFloat: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return get(obj, index); + }); + case RLMAccessorCodeDouble: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return get(obj, index); + }); + case RLMAccessorCodeBool: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return get(obj, index); + }); + case RLMAccessorCodeString: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetString(obj, index); + }); + case RLMAccessorCodeDate: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetDate(obj, index); + }); + case RLMAccessorCodeData: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetData(obj, index); + }); + case RLMAccessorCodeLink: + return imp_implementationWithBlock(^id(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetLink(obj, index); + }); + case RLMAccessorCodeArray: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetArray(obj, index); + }); + case RLMAccessorCodeAny: + @throw RLMException(@"Cannot create accessor class for schema with Mixed properties"); + case RLMAccessorCodeIntObject: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return getBoxed(obj, index); + }); + case RLMAccessorCodeFloatObject: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return getBoxed(obj, index); + }); + case RLMAccessorCodeDoubleObject: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return getBoxed(obj, index); + }); + case RLMAccessorCodeBoolObject: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return getBoxed(obj, index); + }); + case RLMAccessorCodeLinkingObjects: + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj) { + return RLMGetLinkingObjects(obj, prop); + }); + } +} + +template +static void RLMWrapSetter(__unsafe_unretained RLMObjectBase *const obj, __unsafe_unretained NSString *const name, Function&& f) { + if (RLMObservationInfo *info = RLMGetObservationInfo(obj->_observationInfo, obj->_row.get_index(), *obj->_info)) { + info->willChange(name); + f(); + info->didChange(name); + } + else { + f(); + } +} + +template +static IMP RLMMakeSetter(RLMProperty *prop) { + NSUInteger index = prop.index; + NSString *name = prop.name; + if (prop.isPrimary) { + return imp_implementationWithBlock(^(__unused RLMObjectBase *obj, __unused ArgType val) { + @throw RLMException(@"Primary key can't be changed after an object is inserted."); + }); + } + return imp_implementationWithBlock(^(__unsafe_unretained RLMObjectBase *const obj, ArgType val) { + RLMWrapSetter(obj, name, [&] { + RLMSetValue(obj, obj->_info->objectSchema->persisted_properties[index].table_column, static_cast(val)); + }); + }); +} + +// dynamic setter with column closure +static IMP RLMAccessorSetter(RLMProperty *prop, RLMAccessorCode accessorCode) { + switch (accessorCode) { + case RLMAccessorCodeByte: return RLMMakeSetter(prop); + case RLMAccessorCodeShort: return RLMMakeSetter(prop); + case RLMAccessorCodeInt: return RLMMakeSetter(prop); + case RLMAccessorCodeLong: return RLMMakeSetter(prop); + case RLMAccessorCodeLongLong: return RLMMakeSetter(prop); + case RLMAccessorCodeFloat: return RLMMakeSetter(prop); + case RLMAccessorCodeDouble: return RLMMakeSetter(prop); + case RLMAccessorCodeBool: return RLMMakeSetter(prop); + case RLMAccessorCodeString: return RLMMakeSetter(prop); + case RLMAccessorCodeDate: return RLMMakeSetter(prop); + case RLMAccessorCodeData: return RLMMakeSetter(prop); + case RLMAccessorCodeLink: return RLMMakeSetter(prop); + case RLMAccessorCodeArray: return RLMMakeSetter(prop); + case RLMAccessorCodeAny: return RLMMakeSetter(prop); + case RLMAccessorCodeIntObject: return RLMMakeSetter *>(prop); + case RLMAccessorCodeFloatObject: return RLMMakeSetter *>(prop); + case RLMAccessorCodeDoubleObject: return RLMMakeSetter *>(prop); + case RLMAccessorCodeBoolObject: return RLMMakeSetter *>(prop); + case RLMAccessorCodeLinkingObjects: return nil; + } +} + +// call getter for superclass for property at colIndex +static id RLMSuperGet(RLMObjectBase *obj, NSString *propName) { + typedef id (*getter_type)(RLMObjectBase *, SEL); + RLMProperty *prop = obj->_objectSchema[propName]; + Class superClass = class_getSuperclass(obj.class); + getter_type superGetter = (getter_type)[superClass instanceMethodForSelector:prop.getterSel]; + return superGetter(obj, prop.getterSel); +} + +// call setter for superclass for property at colIndex +static void RLMSuperSet(RLMObjectBase *obj, NSString *propName, id val) { + typedef void (*setter_type)(RLMObjectBase *, SEL, RLMArray *ar); + RLMProperty *prop = obj->_objectSchema[propName]; + Class superClass = class_getSuperclass(obj.class); + setter_type superSetter = (setter_type)[superClass instanceMethodForSelector:prop.setterSel]; + superSetter(obj, prop.setterSel, val); +} + +// getter/setter for unmanaged object +static IMP RLMAccessorUnmanagedGetter(RLMProperty *prop, RLMAccessorCode accessorCode) { + // only override getters for RLMArray and linking objects properties + if (accessorCode == RLMAccessorCodeArray) { + NSString *objectClassName = prop.objectClassName; + NSString *propName = prop.name; + + return imp_implementationWithBlock(^(RLMObjectBase *obj) { + id val = RLMSuperGet(obj, propName); + if (!val) { + val = [[RLMArray alloc] initWithObjectClassName:objectClassName]; + RLMSuperSet(obj, propName, val); + } + return val; + }); + } + else if (accessorCode == RLMAccessorCodeLinkingObjects) { + return imp_implementationWithBlock(^(RLMObjectBase *){ + return [RLMResults emptyDetachedResults]; + }); + } + return nil; +} +static IMP RLMAccessorUnmanagedSetter(RLMProperty *prop, RLMAccessorCode accessorCode) { + // only override getters for RLMArray and linking objects properties + if (accessorCode == RLMAccessorCodeArray) { + NSString *propName = prop.name; + NSString *objectClassName = prop.objectClassName; + return imp_implementationWithBlock(^(RLMObjectBase *obj, id ar) { + // make copy when setting (as is the case for all other variants) + RLMArray *unmanagedAr = [[RLMArray alloc] initWithObjectClassName:objectClassName]; + [unmanagedAr addObjects:ar]; + RLMSuperSet(obj, propName, unmanagedAr); + }); + } + return nil; +} + +// macros/helpers to generate objc type strings for registering methods +#define GETTER_TYPES(C) C "@:" +#define SETTER_TYPES(C) "v@:" C + +// getter type strings +// NOTE: this typecode is really the the first charachter of the objc/runtime.h type +// the @ type maps to multiple core types (string, date, array, mixed, any which are id in objc) +static const char *getterTypeStringForObjcCode(char code) { + switch (code) { + case 's': return GETTER_TYPES("s"); + case 'i': return GETTER_TYPES("i"); + case 'l': return GETTER_TYPES("l"); + case 'q': return GETTER_TYPES("q"); + case 'f': return GETTER_TYPES("f"); + case 'd': return GETTER_TYPES("d"); + case 'B': return GETTER_TYPES("B"); + case 'c': return GETTER_TYPES("c"); + case '@': return GETTER_TYPES("@"); + default: @throw RLMException(@"Invalid accessor code"); + } +} + +// setter type strings +// NOTE: this typecode is really the the first charachter of the objc/runtime.h type +// the @ type maps to multiple core types (string, date, array, mixed, any which are id in objc) +static const char *setterTypeStringForObjcCode(char code) { + switch (code) { + case 's': return SETTER_TYPES("s"); + case 'i': return SETTER_TYPES("i"); + case 'l': return SETTER_TYPES("l"); + case 'q': return SETTER_TYPES("q"); + case 'f': return SETTER_TYPES("f"); + case 'd': return SETTER_TYPES("d"); + case 'B': return SETTER_TYPES("B"); + case 'c': return SETTER_TYPES("c"); + case '@': return SETTER_TYPES("@"); + default: @throw RLMException(@"Invalid accessor code"); + } +} + +// get accessor lookup code based on objc type and rlm type +static RLMAccessorCode accessorCodeForType(char objcTypeCode, RLMPropertyType rlmType) { + switch (objcTypeCode) { + case 't': return RLMAccessorCodeArray; + case '@': // custom accessors for strings and subtables + switch (rlmType) { // custom accessor codes for types that map to objc objects + case RLMPropertyTypeObject: return RLMAccessorCodeLink; + case RLMPropertyTypeString: return RLMAccessorCodeString; + case RLMPropertyTypeArray: return RLMAccessorCodeArray; + case RLMPropertyTypeDate: return RLMAccessorCodeDate; + case RLMPropertyTypeData: return RLMAccessorCodeData; + case RLMPropertyTypeAny: return RLMAccessorCodeAny; + + case RLMPropertyTypeBool: return RLMAccessorCodeBoolObject; + case RLMPropertyTypeDouble: return RLMAccessorCodeDoubleObject; + case RLMPropertyTypeFloat: return RLMAccessorCodeFloatObject; + case RLMPropertyTypeInt: return RLMAccessorCodeIntObject; + + case RLMPropertyTypeLinkingObjects: return RLMAccessorCodeLinkingObjects; + } + case 'c': + switch (rlmType) { + case RLMPropertyTypeInt: return RLMAccessorCodeByte; + case RLMPropertyTypeBool: return RLMAccessorCodeBool; + default: + @throw RLMException(@"Unexpected property type for Objective-C type code"); + } + case 'B': return RLMAccessorCodeBool; + case 's': return RLMAccessorCodeShort; + case 'i': return RLMAccessorCodeInt; + case 'l': return RLMAccessorCodeLong; + case 'q': return RLMAccessorCodeLongLong; + case 'f': return RLMAccessorCodeFloat; + case 'd': return RLMAccessorCodeDouble; + default: + @throw RLMException(@"Invalid type for objc typecode"); + } +} + +// implement the class method className on accessors to return the className of the +// base object +void RLMReplaceClassNameMethod(Class accessorClass, NSString *className) { + Class metaClass = object_getClass(accessorClass); + IMP imp = imp_implementationWithBlock(^(Class){ return className; }); + class_addMethod(metaClass, @selector(className), imp, "@@:"); +} + +// implement the shared schema method +void RLMReplaceSharedSchemaMethod(Class accessorClass, RLMObjectSchema *schema) { + Class metaClass = object_getClass(accessorClass); + IMP imp = imp_implementationWithBlock(^(Class cls) { + if (cls == accessorClass) { + return schema; + } + + // If we aren't being called directly on the class this was overriden + // for, the class is either a subclass which we haven't initialized yet, + // or it's a runtime-generated class which should use the parent's + // schema. We check for the latter by checking if the immediate + // descendent of the desired class is a class generated by us (there + // may be further subclasses not generated by us for things like KVO). + Class parent = class_getSuperclass(cls); + while (parent != accessorClass) { + cls = parent; + parent = class_getSuperclass(cls); + } + if (RLMIsGeneratedClass(cls)) { + return schema; + } + + return [RLMSchema sharedSchemaForClass:cls]; + }); + class_addMethod(metaClass, @selector(sharedSchema), imp, "@@:"); +} + +static NSMutableSet *s_generatedClasses = [NSMutableSet new]; +static void RLMMarkClassAsGenerated(Class cls) { + @synchronized (s_generatedClasses) { + [s_generatedClasses addObject:cls]; + } +} + +bool RLMIsGeneratedClass(Class cls) { + @synchronized (s_generatedClasses) { + return [s_generatedClasses containsObject:cls]; + } +} + +static Class RLMCreateAccessorClass(Class objectClass, + RLMObjectSchema *schema, + NSString *accessorClassPrefix, + IMP (*getterGetter)(RLMProperty *, RLMAccessorCode), + IMP (*setterGetter)(RLMProperty *, RLMAccessorCode)) { + // throw if no schema, prefix, or object class + if (!objectClass || !schema || !accessorClassPrefix) { + @throw RLMException(@"Missing arguments"); + } + if (!RLMIsObjectOrSubclass(objectClass)) { + @throw RLMException(@"objectClass must derive from RLMObject or Object"); + } + + // create and register proxy class which derives from object class + NSString *accessorClassName = [accessorClassPrefix stringByAppendingString:schema.className]; + Class accClass = objc_getClass(accessorClassName.UTF8String); + if (!accClass) { + accClass = objc_allocateClassPair(objectClass, accessorClassName.UTF8String, 0); + objc_registerClassPair(accClass); + } + + // override getters/setters for each propery + NSArray *allProperties = [schema.properties arrayByAddingObjectsFromArray:schema.computedProperties]; + for (RLMProperty *prop in allProperties) { + RLMAccessorCode accessorCode = accessorCodeForType(prop.objcType, prop.type); + if (prop.getterSel && getterGetter) { + IMP getterImp = getterGetter(prop, accessorCode); + if (getterImp) { + class_replaceMethod(accClass, prop.getterSel, getterImp, getterTypeStringForObjcCode(prop.objcType)); + } + } + if (prop.setterSel && setterGetter) { + IMP setterImp = setterGetter(prop, accessorCode); + if (setterImp) { + class_replaceMethod(accClass, prop.setterSel, setterImp, setterTypeStringForObjcCode(prop.objcType)); + } + } + } + + RLMMarkClassAsGenerated(accClass); + + return accClass; +} + +Class RLMAccessorClassForObjectClass(Class objectClass, RLMObjectSchema *schema, NSString *prefix) { + return RLMCreateAccessorClass(objectClass, schema, prefix, RLMAccessorGetter, RLMAccessorSetter); +} + +Class RLMUnmanagedAccessorClassForObjectClass(Class objectClass, RLMObjectSchema *schema) { + return RLMCreateAccessorClass(objectClass, schema, @"RLMUnmanaged_", + RLMAccessorUnmanagedGetter, RLMAccessorUnmanagedSetter); +} + +void RLMDynamicValidatedSet(RLMObjectBase *obj, NSString *propName, id val) { + RLMObjectSchema *schema = obj->_objectSchema; + RLMProperty *prop = schema[propName]; + if (!prop) { + @throw RLMException(@"Invalid property name '%@' for class '%@'.", propName, obj->_objectSchema.className); + } + if (prop.isPrimary) { + @throw RLMException(@"Primary key can't be changed to '%@' after an object is inserted.", val); + } + if (!RLMIsObjectValidForProperty(val, prop)) { + @throw RLMException(@"Invalid property value '%@' for property '%@' of class '%@'", val, propName, obj->_objectSchema.className); + } + + RLMDynamicSet(obj, prop, RLMCoerceToNil(val), RLMCreationOptionsPromoteUnmanaged); +} + +// Precondition: the property is not a primary key +void RLMDynamicSet(__unsafe_unretained RLMObjectBase *const obj, __unsafe_unretained RLMProperty *const prop, + __unsafe_unretained id const val, RLMCreationOptions creationOptions) { + REALM_ASSERT_DEBUG(!prop.isPrimary); + + auto col = obj->_info->tableColumn(prop); + RLMWrapSetter(obj, prop.name, [&] { + switch (accessorCodeForType(prop.objcType, prop.type)) { + case RLMAccessorCodeByte: + case RLMAccessorCodeShort: + case RLMAccessorCodeInt: + case RLMAccessorCodeLong: + case RLMAccessorCodeLongLong: + RLMSetValue(obj, col, [val longLongValue]); + break; + case RLMAccessorCodeFloat: + RLMSetValue(obj, col, [val floatValue]); + break; + case RLMAccessorCodeDouble: + RLMSetValue(obj, col, [val doubleValue]); + break; + case RLMAccessorCodeBool: + RLMSetValue(obj, col, [val boolValue]); + break; + case RLMAccessorCodeIntObject: + RLMSetValue(obj, col, (NSNumber *)val); + break; + case RLMAccessorCodeFloatObject: + RLMSetValue(obj, col, (NSNumber *)val); + break; + case RLMAccessorCodeDoubleObject: + RLMSetValue(obj, col, (NSNumber *)val); + break; + case RLMAccessorCodeBoolObject: + RLMSetValue(obj, col, (NSNumber *)val); + break; + case RLMAccessorCodeString: + RLMSetValue(obj, col, (NSString *)val); + break; + case RLMAccessorCodeDate: + RLMSetValue(obj, col, (NSDate *)val); + break; + case RLMAccessorCodeData: + RLMSetValue(obj, col, (NSData *)val); + break; + case RLMAccessorCodeLink: { + if (!val || val == NSNull.null) { + RLMSetValue(obj, col, (RLMObjectBase *)nil); + } + else { + RLMSetValue(obj, col, RLMGetLinkedObjectForValue(obj->_realm, prop.objectClassName, val, creationOptions)); + } + break; + } + case RLMAccessorCodeArray: + if (!val || val == NSNull.null) { + RLMSetValue(obj, col, (id)nil); + } + else { + id rawLinks = val; + NSMutableArray *links = [NSMutableArray array]; + for (id rawLink in rawLinks) { + [links addObject:RLMGetLinkedObjectForValue(obj->_realm, prop.objectClassName, rawLink, creationOptions)]; + } + RLMSetValue(obj, col, links); + } + break; + case RLMAccessorCodeAny: + RLMSetValue(obj, col, val); + break; + case RLMAccessorCodeLinkingObjects: + @throw RLMException(@"Linking objects properties are read-only"); + } + }); +} + +id RLMDynamicGet(__unsafe_unretained RLMObjectBase *const obj, __unsafe_unretained RLMProperty *const prop) { + auto index = prop.index; + switch (accessorCodeForType(prop.objcType, prop.type)) { + case RLMAccessorCodeIntObject: + case RLMAccessorCodeByte: + case RLMAccessorCodeShort: + case RLMAccessorCodeInt: + case RLMAccessorCodeLong: + case RLMAccessorCodeLongLong: return getBoxed(obj, index); + case RLMAccessorCodeFloatObject: + case RLMAccessorCodeFloat: return getBoxed(obj, index); + case RLMAccessorCodeDoubleObject: + case RLMAccessorCodeDouble: return getBoxed(obj, index); + case RLMAccessorCodeBoolObject: + case RLMAccessorCodeBool: return getBoxed(obj, index); + case RLMAccessorCodeString: return RLMGetString(obj, index); + case RLMAccessorCodeDate: return RLMGetDate(obj, index); + case RLMAccessorCodeData: return RLMGetData(obj, index); + case RLMAccessorCodeLink: return RLMGetLink(obj, index); + case RLMAccessorCodeArray: return RLMGetArray(obj, index); + case RLMAccessorCodeAny: return RLMGetAnyProperty(obj, index); + case RLMAccessorCodeLinkingObjects: return RLMGetLinkingObjects(obj, prop); + } +} + +id RLMDynamicGetByName(__unsafe_unretained RLMObjectBase *const obj, __unsafe_unretained NSString *const propName, bool asList) { + RLMProperty *prop = obj->_objectSchema[propName]; + if (!prop) { + @throw RLMException(@"Invalid property name '%@' for class '%@'.", propName, obj->_objectSchema.className); + } + if (asList && prop.type == RLMPropertyTypeArray && prop.swiftIvar) { + RLMListBase *list = object_getIvar(obj, prop.swiftIvar); + if (!list._rlmArray) { + list._rlmArray = RLMDynamicGet(obj, prop); + } + return list; + } + return RLMDynamicGet(obj, prop); +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMAnalytics.mm b/SiriKitExample/Pods/Realm/Realm/RLMAnalytics.mm new file mode 100644 index 0000000..13aa0c3 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMAnalytics.mm @@ -0,0 +1,240 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +// Asynchronously submits build information to Realm if running in an iOS +// simulator or on OS X if a debugger is attached. Does nothing if running on an +// iOS / watchOS device or if a debugger is *not* attached. +// +// To be clear: this does *not* run when your app is in production or on +// your end-user’s devices; it will only run in the simulator or when a debugger +// is attached. +// +// Why are we doing this? In short, because it helps us build a better product +// for you. None of the data personally identifies you, your employer or your +// app, but it *will* help us understand what language you use, what iOS +// versions you target, etc. Having this info will help prioritizing our time, +// adding new features and deprecating old features. Collecting an anonymized +// bundle & anonymized MAC is the only way for us to count actual usage of the +// other metrics accurately. If we don’t have a way to deduplicate the info +// reported, it will be useless, as a single developer building their Swift app +// 10 times would report 10 times more than a single Objective-C developer that +// only builds once, making the data all but useless. +// No one likes sharing data unless it’s necessary, we get it, and we’ve +// debated adding this for a long long time. Since Realm is a free product +// without an email signup, we feel this is a necessary step so we can collect +// relevant data to build a better product for you. If you truly, absolutely +// feel compelled to not send this data back to Realm, then you can set an env +// variable named REALM_DISABLE_ANALYTICS. Since Realm is free we believe +// letting these analytics run is a small price to pay for the product & support +// we give you. +// +// Currently the following information is reported: +// - What version of Realm is being used, and from which language (obj-c or Swift). +// - What version of OS X it's running on (in case Xcode aggressively drops +// support for older versions again, we need to know what we need to support). +// - The minimum iOS/OS X version that the application is targeting (again, to +// help us decide what versions we need to support). +// - An anonymous MAC address and bundle ID to aggregate the other information on. +// - What version of Swift is being used (if applicable). + +#import "RLMAnalytics.hpp" + +#import + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_MAC || (TARGET_OS_WATCH && TARGET_OS_SIMULATOR) || (TARGET_OS_TV && TARGET_OS_SIMULATOR) +#import "RLMRealm.h" +#import "RLMUtil.hpp" + +#import +#import +#import +#import +#import + +#import + +#ifndef REALM_COCOA_VERSION +#import "RLMVersion.h" +#endif + +// Declared for RealmSwiftObjectUtil +@interface NSObject (SwiftVersion) ++ (NSString *)swiftVersion; +@end + +// Wrapper for sysctl() that handles the memory management stuff +static auto RLMSysCtl(int *mib, u_int mibSize, size_t *bufferSize) { + std::unique_ptr buffer(nullptr, &free); + + int ret = sysctl(mib, mibSize, nullptr, bufferSize, nullptr, 0); + if (ret != 0) { + return buffer; + } + + buffer.reset(malloc(*bufferSize)); + if (!buffer) { + return buffer; + } + + ret = sysctl(mib, mibSize, buffer.get(), bufferSize, nullptr, 0); + if (ret != 0) { + buffer.reset(); + } + + return buffer; +} + +// Get the version of OS X we're running on (even in the simulator this gives +// the OS X version and not the simulated iOS version) +static NSString *RLMOSVersion() { + std::array mib = {CTL_KERN, KERN_OSRELEASE}; + size_t bufferSize; + auto buffer = RLMSysCtl(&mib[0], mib.size(), &bufferSize); + if (!buffer) { + return nil; + } + + return [[NSString alloc] initWithBytesNoCopy:buffer.release() + length:bufferSize - 1 + encoding:NSUTF8StringEncoding + freeWhenDone:YES]; +} + +// Hash the data in the given buffer and convert it to a hex-format string +static NSString *RLMHashData(const void *bytes, size_t length) { + unsigned char buffer[CC_SHA256_DIGEST_LENGTH]; + CC_SHA256(bytes, static_cast(length), buffer); + + char formatted[CC_SHA256_DIGEST_LENGTH * 2 + 1]; + for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; ++i) { + sprintf(formatted + i * 2, "%02x", buffer[i]); + } + + return [[NSString alloc] initWithBytes:formatted + length:CC_SHA256_DIGEST_LENGTH * 2 + encoding:NSUTF8StringEncoding]; +} + +// Returns the hash of the MAC address of the first network adaptor since the +// vendorIdentifier isn't constant between iOS simulators. +static NSString *RLMMACAddress() { + int en0 = static_cast(if_nametoindex("en0")); + if (!en0) { + return nil; + } + + std::array mib = {CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, en0}; + size_t bufferSize; + auto buffer = RLMSysCtl(&mib[0], mib.size(), &bufferSize); + if (!buffer) { + return nil; + } + + // sockaddr_dl struct is immediately after the if_msghdr struct in the buffer + auto sockaddr = reinterpret_cast(static_cast(buffer.get()) + 1); + auto mac = reinterpret_cast(sockaddr->sdl_data + sockaddr->sdl_nlen); + + return RLMHashData(mac, 6); +} + +static NSDictionary *RLMAnalyticsPayload() { + NSBundle *appBundle = NSBundle.mainBundle; + NSString *hashedBundleID = appBundle.bundleIdentifier; + + // Main bundle isn't always the one of interest (e.g. when running tests + // it's xctest rather than the app's bundle), so look for one with a bundle ID + if (!hashedBundleID) { + for (NSBundle *bundle in NSBundle.allBundles) { + if ((hashedBundleID = bundle.bundleIdentifier)) { + appBundle = bundle; + break; + } + } + } + + // If we found a bundle ID anywhere, hash it as it could contain sensitive + // information (e.g. the name of an unnanounced product) + if (hashedBundleID) { + NSData *data = [hashedBundleID dataUsingEncoding:NSUTF8StringEncoding]; + hashedBundleID = RLMHashData(data.bytes, data.length); + } + + NSString *osVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString]; + Class swiftObjectUtilClass = NSClassFromString(@"RealmSwiftObjectUtil"); + BOOL isSwift = swiftObjectUtilClass != nil; + NSString *swiftVersion = isSwift ? [swiftObjectUtilClass swiftVersion] : @"N/A"; + + static NSString *kUnknownString = @"unknown"; + NSString *hashedMACAddress = RLMMACAddress() ?: kUnknownString; + + return @{ + @"event": @"Run", + @"properties": @{ + // MixPanel properties + @"token": @"ce0fac19508f6c8f20066d345d360fd0", + + // Anonymous identifiers to deduplicate events + @"distinct_id": hashedMACAddress, + @"Anonymized MAC Address": hashedMACAddress, + @"Anonymized Bundle ID": hashedBundleID ?: kUnknownString, + + // Which version of Realm is being used + @"Binding": @"cocoa", + @"Language": isSwift ? @"swift" : @"objc", + @"Realm Version": REALM_COCOA_VERSION, +#if TARGET_OS_WATCH + @"Target OS Type": @"watchos", +#elif TARGET_OS_TV + @"Target OS Type": @"tvos", +#elif TARGET_OS_IPHONE + @"Target OS Type": @"ios", +#else + @"Target OS Type": @"osx", +#endif + @"Swift Version": swiftVersion, + // Current OS version the app is targetting + @"Target OS Version": osVersionString, + // Minimum OS version the app is targetting + @"Target OS Minimum Version": appBundle.infoDictionary[@"MinimumOSVersion"] ?: kUnknownString, + + // Host OS version being built on + @"Host OS Type": @"osx", + @"Host OS Version": RLMOSVersion() ?: kUnknownString, + } + }; +} + +void RLMSendAnalytics() { + if (getenv("REALM_DISABLE_ANALYTICS") || !RLMIsDebuggerAttached() || RLMIsRunningInPlayground()) { + return; + } + + + NSData *payload = [NSJSONSerialization dataWithJSONObject:RLMAnalyticsPayload() options:0 error:nil]; + NSString *url = [NSString stringWithFormat:@"https://api.mixpanel.com/track/?data=%@&ip=1", [payload base64EncodedStringWithOptions:0]]; + + // No error handling or anything because logging errors annoyed people for no + // real benefit, and it's not clear what else we could do + [[NSURLSession.sharedSession dataTaskWithURL:[NSURL URLWithString:url]] resume]; +} + +#else + +void RLMSendAnalytics() {} + +#endif diff --git a/SiriKitExample/Pods/Realm/Realm/RLMArray.mm b/SiriKitExample/Pods/Realm/Realm/RLMArray.mm new file mode 100644 index 0000000..2cfccf9 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMArray.mm @@ -0,0 +1,439 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMArray_Private.hpp" + +#import "RLMObject_Private.h" +#import "RLMObjectStore.h" +#import "RLMObjectSchema.h" +#import "RLMQueryUtil.hpp" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +#import + +// See -countByEnumeratingWithState:objects:count +@interface RLMArrayHolder : NSObject { +@public + std::unique_ptr items; +} +@end +@implementation RLMArrayHolder +@end + +@implementation RLMArray { +@public + // Backing array when this instance is unmanaged + NSMutableArray *_backingArray; +} + +template +static void changeArray(__unsafe_unretained RLMArray *const ar, + NSKeyValueChange kind, dispatch_block_t f, IndexSetFactory&& is) { + if (!ar->_backingArray) { + ar->_backingArray = [NSMutableArray new]; + } + + if (RLMObjectBase *parent = ar->_parentObject) { + NSIndexSet *indexes = is(); + [parent willChange:kind valuesAtIndexes:indexes forKey:ar->_key]; + f(); + [parent didChange:kind valuesAtIndexes:indexes forKey:ar->_key]; + } + else { + f(); + } +} + +static void changeArray(__unsafe_unretained RLMArray *const ar, NSKeyValueChange kind, NSUInteger index, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return [NSIndexSet indexSetWithIndex:index]; }); +} + +static void changeArray(__unsafe_unretained RLMArray *const ar, NSKeyValueChange kind, NSRange range, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return [NSIndexSet indexSetWithIndexesInRange:range]; }); +} + +static void changeArray(__unsafe_unretained RLMArray *const ar, NSKeyValueChange kind, NSIndexSet *is, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return is; }); +} + +- (instancetype)initWithObjectClassName:(__unsafe_unretained NSString *const)objectClassName { + self = [super init]; + if (self) { + _objectClassName = objectClassName; + } + return self; +} + +- (RLMRealm *)realm { + return nil; +} + +// +// Generic implementations for all RLMArray variants +// + +- (id)firstObject { + if (self.count) { + return [self objectAtIndex:0]; + } + return nil; +} + +- (id)lastObject { + NSUInteger count = self.count; + if (count) { + return [self objectAtIndex:count-1]; + } + return nil; +} + +- (void)addObjects:(id)objects { + for (id obj in objects) { + [self addObject:obj]; + } +} + +- (void)addObject:(RLMObject *)object { + [self insertObject:object atIndex:self.count]; +} + +- (void)removeLastObject { + NSUInteger count = self.count; + if (count) { + [self removeObjectAtIndex:count-1]; + } +} + +- (id)objectAtIndexedSubscript:(NSUInteger)index { + return [self objectAtIndex:index]; +} + +- (void)setObject:(id)newValue atIndexedSubscript:(NSUInteger)index { + [self replaceObjectAtIndex:index withObject:newValue]; +} + +// +// Unmanaged RLMArray implementation +// + +static void RLMValidateMatchingObjectType(RLMArray *array, RLMObject *object) { + if (!object) { + @throw RLMException(@"Object must not be nil"); + } + if (!object->_objectSchema) { + @throw RLMException(@"Object cannot be inserted unless the schema is initialized. " + "This can happen if you try to insert objects into a RLMArray / List from a default value or from an overriden unmanaged initializer (`init()`)."); + } + if (![array->_objectClassName isEqualToString:object->_objectSchema.className]) { + @throw RLMException(@"Object type '%@' does not match RLMArray type '%@'.", + object->_objectSchema.className, array->_objectClassName); + } +} + +static void RLMValidateArrayBounds(__unsafe_unretained RLMArray *const ar, + NSUInteger index, bool allowOnePastEnd=false) { + NSUInteger max = ar->_backingArray.count + allowOnePastEnd; + if (index >= max) { + @throw RLMException(@"Index %llu is out of bounds (must be less than %llu).", + (unsigned long long)index, (unsigned long long)max); + } +} + +- (id)objectAtIndex:(NSUInteger)index { + RLMValidateArrayBounds(self, index); + if (!_backingArray) { + _backingArray = [NSMutableArray new]; + } + return [_backingArray objectAtIndex:index]; +} + +- (NSUInteger)count { + return _backingArray.count; +} + +- (BOOL)isInvalidated { + return NO; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unused __unsafe_unretained id [])buffer count:(__unused NSUInteger)len { + if (state->state != 0) { + return 0; + } + + // We need to enumerate a copy of the backing array so that it doesn't + // reflect changes made during enumeration. This copy has to be autoreleased + // (since there's nowhere for us to store a strong reference), and uses + // RLMArrayHolder rather than an NSArray because NSArray doesn't guarantee + // that it'll use a single contiguous block of memory, and if it doesn't + // we'd need to forward multiple calls to this method to the same NSArray, + // which would require holding a reference to it somewhere. + __autoreleasing RLMArrayHolder *copy = [[RLMArrayHolder alloc] init]; + copy->items = std::make_unique(self.count); + + NSUInteger i = 0; + for (id object in _backingArray) { + copy->items[i++] = object; + } + + state->itemsPtr = (__unsafe_unretained id *)(void *)copy->items.get(); + // needs to point to something valid, but the whole point of this is so + // that it can't be changed + state->mutationsPtr = state->extra; + state->state = i; + + return i; +} + +- (void)addObjectsFromArray:(NSArray *)array { + for (id obj in array) { + RLMValidateMatchingObjectType(self, obj); + } + changeArray(self, NSKeyValueChangeInsertion, NSMakeRange(_backingArray.count, array.count), ^{ + [_backingArray addObjectsFromArray:array]; + }); +} + +- (void)insertObject:(RLMObject *)anObject atIndex:(NSUInteger)index { + RLMValidateMatchingObjectType(self, anObject); + RLMValidateArrayBounds(self, index, true); + changeArray(self, NSKeyValueChangeInsertion, index, ^{ + [_backingArray insertObject:anObject atIndex:index]; + }); +} + +- (void)insertObjects:(id)objects atIndexes:(NSIndexSet *)indexes { + changeArray(self, NSKeyValueChangeInsertion, indexes, ^{ + NSUInteger currentIndex = [indexes firstIndex]; + for (RLMObject *obj in objects) { + RLMValidateMatchingObjectType(self, obj); + [_backingArray insertObject:obj atIndex:currentIndex]; + currentIndex = [indexes indexGreaterThanIndex:currentIndex]; + } + }); +} + +- (void)removeObjectAtIndex:(NSUInteger)index { + RLMValidateArrayBounds(self, index); + changeArray(self, NSKeyValueChangeRemoval, index, ^{ + [_backingArray removeObjectAtIndex:index]; + }); +} + +- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes { + changeArray(self, NSKeyValueChangeRemoval, indexes, ^{ + [_backingArray removeObjectsAtIndexes:indexes]; + }); +} + +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject { + RLMValidateMatchingObjectType(self, anObject); + RLMValidateArrayBounds(self, index); + changeArray(self, NSKeyValueChangeReplacement, index, ^{ + [_backingArray replaceObjectAtIndex:index withObject:anObject]; + }); +} + +- (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex { + RLMValidateArrayBounds(self, sourceIndex); + RLMValidateArrayBounds(self, destinationIndex); + RLMObjectBase *original = _backingArray[sourceIndex]; + + auto start = std::min(sourceIndex, destinationIndex); + auto len = std::max(sourceIndex, destinationIndex) - start + 1; + changeArray(self, NSKeyValueChangeReplacement, {start, len}, ^{ + [_backingArray removeObjectAtIndex:sourceIndex]; + [_backingArray insertObject:original atIndex:destinationIndex]; + }); +} + +- (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2 { + RLMValidateArrayBounds(self, index1); + RLMValidateArrayBounds(self, index2); + + changeArray(self, NSKeyValueChangeReplacement, ^{ + [_backingArray exchangeObjectAtIndex:index1 withObjectAtIndex:index2]; + }, [=] { + NSMutableIndexSet *set = [[NSMutableIndexSet alloc] initWithIndex:index1]; + [set addIndex:index2]; + return set; + }); +} + +- (NSUInteger)indexOfObject:(RLMObject *)object { + RLMValidateMatchingObjectType(self, object); + NSUInteger index = 0; + for (RLMObject *cmp in _backingArray) { + if (RLMObjectBaseAreEqual(object, cmp)) { + return index; + } + index++; + } + return NSNotFound; +} + +- (void)removeAllObjects { + changeArray(self, NSKeyValueChangeRemoval, NSMakeRange(0, _backingArray.count), ^{ + [_backingArray removeAllObjects]; + }); +} + +- (RLMResults *)objectsWhere:(NSString *)predicateFormat, ... +{ + va_list args; + va_start(args, predicateFormat); + RLMResults *results = [self objectsWhere:predicateFormat args:args]; + va_end(args); + return results; +} + +- (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args +{ + return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]]; +} + +- (id)valueForKeyPath:(NSString *)keyPath { + if (!_backingArray) { + return [super valueForKeyPath:keyPath]; + } + // Although delegating to valueForKeyPath: here would allow to support + // nested key paths as well, limiting functionality gives consistency + // between unmanaged and managed arrays. + if ([keyPath characterAtIndex:0] == '@') { + NSRange operatorRange = [keyPath rangeOfString:@"." options:NSLiteralSearch]; + if (operatorRange.location != NSNotFound) { + NSString *operatorKeyPath = [keyPath substringFromIndex:operatorRange.location + 1]; + if ([operatorKeyPath rangeOfString:@"."].location != NSNotFound) { + @throw RLMException(@"Nested key paths are not supported yet for KVC collection operators."); + } + } + } + return [_backingArray valueForKeyPath:keyPath]; +} + +- (id)valueForKey:(NSString *)key { + if ([key isEqualToString:RLMInvalidatedKey]) { + return @NO; // Unmanaged arrays are never invalidated + } + if (!_backingArray) { + return @[]; + } + return [_backingArray valueForKey:key]; +} + +- (void)setValue:(id)value forKey:(NSString *)key { + [_backingArray setValue:value forKey:key]; +} + +- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate { + if (!_backingArray) { + return NSNotFound; + } + return [_backingArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger, BOOL *) { + return [predicate evaluateWithObject:obj]; + }]; +} + +- (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes { + if (!_backingArray) { + _backingArray = [NSMutableArray new]; + } + return [_backingArray objectsAtIndexes:indexes]; +} + +- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context { + RLMValidateArrayObservationKey(keyPath, self); + [super addObserver:observer forKeyPath:keyPath options:options context:context]; +} + +// +// Methods unsupported on unmanaged RLMArray instances +// + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" + +- (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate +{ + @throw RLMException(@"This method may only be called on RLMArray instances retrieved from an RLMRealm"); +} + +- (RLMResults *)sortedResultsUsingProperty:(NSString *)property ascending:(BOOL)ascending +{ + return [self sortedResultsUsingDescriptors:@[[RLMSortDescriptor sortDescriptorWithProperty:property ascending:ascending]]]; +} + +- (RLMResults *)sortedResultsUsingDescriptors:(NSArray *)properties +{ + @throw RLMException(@"This method may only be called on RLMArray instances retrieved from an RLMRealm"); +} + +// The compiler complains about the method's argument type not matching due to +// it not having the generic type attached, but it doesn't seem to be possible +// to actually include the generic type +// http://www.openradar.me/radar?id=6135653276319744 +#pragma clang diagnostic ignored "-Wmismatched-parameter-types" +- (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMArray *, RLMCollectionChange *, NSError *))block { + @throw RLMException(@"This method may only be called on RLMArray instances retrieved from an RLMRealm"); +} +#pragma clang diagnostic pop + +- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat, ... +{ + va_list args; + va_start(args, predicateFormat); + NSUInteger index = [self indexOfObjectWhere:predicateFormat args:args]; + va_end(args); + return index; +} + +- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat args:(va_list)args +{ + return [self indexOfObjectWithPredicate:[NSPredicate predicateWithFormat:predicateFormat + arguments:args]]; +} + +#pragma mark - Superclass Overrides + +- (NSString *)description { + return [self descriptionWithMaxDepth:RLMDescriptionMaxDepth]; +} + +- (NSString *)descriptionWithMaxDepth:(NSUInteger)depth { + return RLMDescriptionWithMaxDepth(@"RLMArray", self, depth); +} +@end + +@interface RLMSortDescriptor () +@property (nonatomic, strong) NSString *property; +@property (nonatomic, assign) BOOL ascending; +@end + +@implementation RLMSortDescriptor ++ (instancetype)sortDescriptorWithProperty:(NSString *)propertyName ascending:(BOOL)ascending { + RLMSortDescriptor *desc = [[RLMSortDescriptor alloc] init]; + desc->_property = propertyName; + desc->_ascending = ascending; + return desc; +} + +- (instancetype)reversedSortDescriptor { + return [self.class sortDescriptorWithProperty:_property ascending:!_ascending]; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMArrayLinkView.mm b/SiriKitExample/Pods/Realm/Realm/RLMArrayLinkView.mm new file mode 100644 index 0000000..f161be5 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMArrayLinkView.mm @@ -0,0 +1,424 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMArray_Private.hpp" + +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObject_Private.hpp" +#import "RLMObservation.hpp" +#import "RLMProperty_Private.h" +#import "RLMQueryUtil.hpp" +#import "RLMRealm_Private.hpp" +#import "RLMSchema.h" +#import "RLMUtil.hpp" + +#import "list.hpp" +#import "results.hpp" + +#import +#import + +// +// RLMArray implementation +// +@implementation RLMArrayLinkView { +@public + realm::List _backingList; + RLMRealm *_realm; + RLMClassInfo *_objectInfo; + RLMClassInfo *_ownerInfo; + std::unique_ptr _observationInfo; +} + +- (RLMArrayLinkView *)initWithParent:(__unsafe_unretained RLMObjectBase *const)parentObject + property:(__unsafe_unretained RLMProperty *const)property { + self = [self initWithObjectClassName:property.objectClassName]; + if (self) { + _realm = parentObject->_realm; + _backingList = realm::List(_realm->_realm, parentObject->_row.get_linklist(parentObject->_info->tableColumn(property))); + _objectInfo = &parentObject->_info->linkTargetType(property.index); + _ownerInfo = parentObject->_info; + _key = property.name; + } + return self; +} + +void RLMValidateArrayObservationKey(__unsafe_unretained NSString *const keyPath, + __unsafe_unretained RLMArray *const array) { + if (![keyPath isEqualToString:RLMInvalidatedKey]) { + @throw RLMException(@"[<%@ %p> addObserver:forKeyPath:options:context:] is not supported. Key path: %@", + [array class], array, keyPath); + } +} + +void RLMEnsureArrayObservationInfo(std::unique_ptr& info, + __unsafe_unretained NSString *const keyPath, + __unsafe_unretained RLMArray *const array, + __unsafe_unretained id const observed) { + RLMValidateArrayObservationKey(keyPath, array); + if (!info && array.class == [RLMArrayLinkView class]) { + RLMArrayLinkView *lv = static_cast(array); + info = std::make_unique(*lv->_ownerInfo, + lv->_backingList.get_origin_row_index(), + observed); + } +} + +// +// validation helpers +// +[[gnu::noinline]] +[[noreturn]] +static void throwError() { + try { + throw; + } + catch (realm::InvalidTransactionException const&) { + @throw RLMException(@"Cannot modify managed RLMArray outside of a write transaction"); + } + catch (realm::IncorrectThreadException const&) { + @throw RLMException(@"Realm accessed from incorrect thread"); + } + catch (realm::List::InvalidatedException const&) { + @throw RLMException(@"RLMArray has been invalidated or the containing object has been deleted"); + } + catch (realm::List::OutOfBoundsIndexException const& e) { + @throw RLMException(@"Index %zu is out of bounds (must be less than %zu)", + e.requested, e.valid_count); + } +} + +template +static auto translateErrors(Function&& f) { + try { + return f(); + } + catch (...) { + throwError(); + } +} + +static void validateObjectToAdd(__unsafe_unretained RLMArrayLinkView *const ar, + __unsafe_unretained RLMObject *const obj) { + if (!obj) { + @throw RLMException(@"Cannot add `nil` to RLMArray<%@>", ar->_objectClassName); + } + + NSString *objectClassName = obj->_objectSchema.className; + if (![objectClassName isEqualToString:ar->_objectClassName]) { + @throw RLMException(@"Cannot add object of type '%@' to RLMArray<%@>", + objectClassName, ar->_objectClassName); + } + + if (obj->_realm != ar.realm) { + [ar.realm addObject:obj]; + } + else if (obj->_realm && !obj->_row.is_attached()) { + @throw RLMException(@"Object has been deleted or invalidated."); + } +} + +template +static void changeArray(__unsafe_unretained RLMArrayLinkView *const ar, + NSKeyValueChange kind, dispatch_block_t f, IndexSetFactory&& is) { + translateErrors([&] { ar->_backingList.verify_in_transaction(); }); + RLMObservationInfo *info = RLMGetObservationInfo(ar->_observationInfo.get(), + ar->_backingList.get_origin_row_index(), + *ar->_ownerInfo); + if (info) { + NSIndexSet *indexes = is(); + info->willChange(ar->_key, kind, indexes); + try { + f(); + } + catch (...) { + info->didChange(ar->_key, kind, indexes); + throwError(); + } + info->didChange(ar->_key, kind, indexes); + } + else { + translateErrors([&] { f(); }); + } +} + +static void changeArray(__unsafe_unretained RLMArrayLinkView *const ar, NSKeyValueChange kind, NSUInteger index, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return [NSIndexSet indexSetWithIndex:index]; }); +} + +static void changeArray(__unsafe_unretained RLMArrayLinkView *const ar, NSKeyValueChange kind, NSRange range, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return [NSIndexSet indexSetWithIndexesInRange:range]; }); +} + +static void changeArray(__unsafe_unretained RLMArrayLinkView *const ar, NSKeyValueChange kind, NSIndexSet *is, dispatch_block_t f) { + changeArray(ar, kind, f, [=] { return is; }); +} + +// +// public method implementations +// +- (RLMRealm *)realm { + return _realm; +} + +- (NSUInteger)count { + return translateErrors([&] { return _backingList.size(); }); +} + +- (BOOL)isInvalidated { + return translateErrors([&] { return !_backingList.is_valid(); }); +} + +- (RLMClassInfo *)objectInfo { + return _objectInfo; +} + +- (BOOL)isEqual:(id)object { + if (RLMArrayLinkView *linkView = RLMDynamicCast(object)) { + return linkView->_backingList == _backingList; + } + return NO; +} + +- (NSUInteger)hash { + return std::hash()(_backingList); +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state + objects:(__unused __unsafe_unretained id [])buffer + count:(NSUInteger)len { + __autoreleasing RLMFastEnumerator *enumerator; + if (state->state == 0) { + translateErrors([&] { _backingList.verify_attached(); }); + + enumerator = [[RLMFastEnumerator alloc] initWithCollection:self objectSchema:*_objectInfo]; + state->extra[0] = (long)enumerator; + state->extra[1] = self.count; + } + else { + enumerator = (__bridge id)(void *)state->extra[0]; + } + + return [enumerator countByEnumeratingWithState:state count:len]; +} + +- (id)objectAtIndex:(NSUInteger)index { + return RLMCreateObjectAccessor(_realm, *_objectInfo, + translateErrors([&] { return _backingList.get(index).get_index(); })); +} + +static void RLMInsertObject(RLMArrayLinkView *ar, RLMObject *object, NSUInteger index) { + if (index == NSUIntegerMax) { + index = translateErrors([&] { return ar->_backingList.size(); }); + } + + validateObjectToAdd(ar, object); + changeArray(ar, NSKeyValueChangeInsertion, index, ^{ + ar->_backingList.insert(index, object->_row.get_index()); + }); +} + +- (void)addObject:(RLMObject *)object { + RLMInsertObject(self, object, NSUIntegerMax); +} + +- (void)insertObject:(RLMObject *)object atIndex:(NSUInteger)index { + RLMInsertObject(self, object, index); +} + +- (void)insertObjects:(id)objects atIndexes:(NSIndexSet *)indexes { + changeArray(self, NSKeyValueChangeInsertion, indexes, ^{ + NSUInteger index = [indexes firstIndex]; + for (RLMObject *obj in objects) { + validateObjectToAdd(self, obj); + _backingList.insert(index, obj->_row.get_index()); + index = [indexes indexGreaterThanIndex:index]; + } + }); +} + + +- (void)removeObjectAtIndex:(NSUInteger)index { + changeArray(self, NSKeyValueChangeRemoval, index, ^{ + _backingList.remove(index); + }); +} + +- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes { + changeArray(self, NSKeyValueChangeRemoval, indexes, ^{ + [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger idx, BOOL *) { + _backingList.remove(idx); + }]; + }); +} + +- (void)addObjectsFromArray:(NSArray *)array { + changeArray(self, NSKeyValueChangeInsertion, NSMakeRange(self.count, array.count), ^{ + for (RLMObject *obj in array) { + validateObjectToAdd(self, obj); + _backingList.add(obj->_row.get_index()); + } + }); +} + +- (void)removeAllObjects { + changeArray(self, NSKeyValueChangeRemoval, NSMakeRange(0, self.count), ^{ + _backingList.remove_all(); + }); +} + +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(RLMObject *)object { + validateObjectToAdd(self, object); + changeArray(self, NSKeyValueChangeReplacement, index, ^{ + _backingList.set(index, object->_row.get_index()); + }); +} + +- (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex { + auto start = std::min(sourceIndex, destinationIndex); + auto len = std::max(sourceIndex, destinationIndex) - start + 1; + changeArray(self, NSKeyValueChangeReplacement, {start, len}, ^{ + _backingList.move(sourceIndex, destinationIndex); + }); +} + +- (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2 { + changeArray(self, NSKeyValueChangeReplacement, ^{ + _backingList.swap(index1, index2); + }, [=] { + NSMutableIndexSet *set = [[NSMutableIndexSet alloc] initWithIndex:index1]; + [set addIndex:index2]; + return set; + }); +} + +- (NSUInteger)indexOfObject:(RLMObject *)object { + if (object.invalidated) { + @throw RLMException(@"Object has been deleted or invalidated"); + } + + // check that object types align + if (![_objectClassName isEqualToString:object->_objectSchema.className]) { + @throw RLMException(@"Object of type (%@) does not match RLMArray type (%@)", + object->_objectSchema.className, _objectClassName); + } + + return translateErrors([&] { return RLMConvertNotFound(_backingList.find(object->_row)); }); +} + +- (id)valueForKeyPath:(NSString *)keyPath { + if ([keyPath hasPrefix:@"@"]) { + // Delegate KVC collection operators to RLMResults + auto query = translateErrors([&] { return _backingList.get_query(); }); + RLMResults *results = [RLMResults resultsWithObjectInfo:*_objectInfo + results:realm::Results(_realm->_realm, std::move(query))]; + return [results valueForKeyPath:keyPath]; + } + return [super valueForKeyPath:keyPath]; +} + +- (id)valueForKey:(NSString *)key { + // Ideally we'd use "@invalidated" for this so that "invalidated" would use + // normal array KVC semantics, but observing @things works very oddly (when + // it's part of a key path, it's triggered automatically when array index + // changes occur, and can't be sent explicitly, but works normally when it's + // the entire key path), and an RLMArrayLinkView *can't* have objects where + // invalidated is true, so we're not losing much. + if ([key isEqualToString:RLMInvalidatedKey]) { + return @(!_backingList.is_valid()); + } + + translateErrors([&] { _backingList.verify_attached(); }); + return RLMCollectionValueForKey(self, key); +} + +- (void)setValue:(id)value forKey:(NSString *)key { + translateErrors([&] { _backingList.verify_in_transaction(); }); + RLMCollectionSetValueForKey(self, key, value); +} + +- (void)deleteObjectsFromRealm { + // delete all target rows from the realm + RLMTrackDeletions(_realm, ^{ + translateErrors([&] { _backingList.delete_all(); }); + }); +} + +- (RLMResults *)sortedResultsUsingDescriptors:(NSArray *)properties { + auto order = RLMSortDescriptorFromDescriptors(*_objectInfo->table(), properties); + auto results = translateErrors([&] { return _backingList.sort(std::move(order)); }); + return [RLMResults resultsWithObjectInfo:*_objectInfo results:std::move(results)]; +} + +- (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate { + auto query = RLMPredicateToQuery(predicate, _objectInfo->rlmObjectSchema, _realm.schema, _realm.group); + auto results = translateErrors([&] { return _backingList.filter(std::move(query)); }); + return [RLMResults resultsWithObjectInfo:*_objectInfo results:std::move(results)]; +} + +- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate { + auto query = translateErrors([&] { return _backingList.get_query(); }); + query.and_query(RLMPredicateToQuery(predicate, _objectInfo->rlmObjectSchema, _realm.schema, _realm.group)); +#if REALM_VER_MAJOR >= 2 + auto indexInTable = query.find(); + if (indexInTable == realm::not_found) { + return NSNotFound; + } + auto row = query.get_table()->get(indexInTable); + return _backingList.find(row); +#else + return RLMConvertNotFound(query.find()); +#endif +} + +- (NSArray *)objectsAtIndexes:(__unused NSIndexSet *)indexes { + // FIXME: this is called by KVO when array changes are made. It's not clear + // why, and returning nil seems to work fine. + return nil; +} + +- (void)addObserver:(id)observer + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context { + RLMEnsureArrayObservationInfo(_observationInfo, keyPath, self, self); + [super addObserver:observer forKeyPath:keyPath options:options context:context]; +} + +- (NSUInteger)indexInSource:(NSUInteger)index { + return _backingList.get_unchecked(index); +} + +- (realm::TableView)tableView { + return translateErrors([&] { return _backingList.get_query(); }).find_all(); +} + +// The compiler complains about the method's argument type not matching due to +// it not having the generic type attached, but it doesn't seem to be possible +// to actually include the generic type +// http://www.openradar.me/radar?id=6135653276319744 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmismatched-parameter-types" +- (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMArray *, RLMCollectionChange *, NSError *))block { + [_realm verifyNotificationsAreSupported]; + return RLMAddNotificationBlock(self, _backingList, block); +} +#pragma clang diagnostic pop + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMClassInfo.mm b/SiriKitExample/Pods/Realm/Realm/RLMClassInfo.mm new file mode 100644 index 0000000..09ad9d5 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMClassInfo.mm @@ -0,0 +1,107 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMClassInfo.hpp" + +#import "RLMRealm_Private.hpp" +#import "RLMObjectSchema.h" +#import "RLMSchema.h" +#import "RLMProperty_Private.h" +#import "RLMQueryUtil.hpp" +#import "RLMUtil.hpp" + +#import "object_schema.hpp" +#import "object_store.hpp" +#import "schema.hpp" + +#import + +using namespace realm; + +RLMClassInfo::RLMClassInfo(RLMRealm *realm, RLMObjectSchema *rlmObjectSchema, + const realm::ObjectSchema *objectSchema) +: realm(realm), rlmObjectSchema(rlmObjectSchema), objectSchema(objectSchema) { } + +realm::Table *RLMClassInfo::table() const { + if (!m_table) { + m_table = ObjectStore::table_for_object_type(realm.group, objectSchema->name).get(); + } + return m_table; +} + +RLMProperty *RLMClassInfo::propertyForTableColumn(NSUInteger col) const noexcept { + auto const& props = objectSchema->persisted_properties; + for (size_t i = 0; i < props.size(); ++i) { + if (props[i].table_column == col) { + return rlmObjectSchema.properties[i]; + } + } + return nil; +} + +RLMProperty *RLMClassInfo::propertyForPrimaryKey() const noexcept { + return rlmObjectSchema.primaryKeyProperty; +} + +NSUInteger RLMClassInfo::tableColumn(NSString *propertyName) const { + return tableColumn(RLMValidatedProperty(rlmObjectSchema, propertyName)); +} + +NSUInteger RLMClassInfo::tableColumn(RLMProperty *property) const { + return objectSchema->persisted_properties[property.index].table_column; +} + +RLMClassInfo &RLMClassInfo::linkTargetType(size_t index) { + if (index < m_linkTargets.size() && m_linkTargets[index]) { + return *m_linkTargets[index]; + } + if (m_linkTargets.size() <= index) { + m_linkTargets.resize(index + 1); + } + m_linkTargets[index] = &realm->_info[rlmObjectSchema.properties[index].objectClassName]; + return *m_linkTargets[index]; +} + +RLMSchemaInfo::impl::iterator RLMSchemaInfo::begin() noexcept { return m_objects.begin(); } +RLMSchemaInfo::impl::iterator RLMSchemaInfo::end() noexcept { return m_objects.end(); } +RLMSchemaInfo::impl::const_iterator RLMSchemaInfo::begin() const noexcept { return m_objects.begin(); } +RLMSchemaInfo::impl::const_iterator RLMSchemaInfo::end() const noexcept { return m_objects.end(); } + +RLMClassInfo& RLMSchemaInfo::operator[](NSString *name) { + auto it = m_objects.find(name); + if (it == m_objects.end()) { + @throw RLMException(@"Object type '%@' is not managed by the Realm. " + @"If using a custom `objectClasses` / `objectTypes` array in your configuration, " + @"add `%@` to the list of `objectClasses` / `objectTypes`.", + name, name); + } + return *&it->second; +} + +RLMSchemaInfo::RLMSchemaInfo(RLMRealm *realm, RLMSchema *rlmSchema, realm::Schema const& schema) { + REALM_ASSERT(rlmSchema.objectSchema.count == schema.size()); + REALM_ASSERT(m_objects.empty()); + + m_objects.reserve(schema.size()); + for (RLMObjectSchema *rlmObjectSchema in rlmSchema.objectSchema) { + m_objects.emplace(std::piecewise_construct, + std::forward_as_tuple(rlmObjectSchema.className), + std::forward_as_tuple(realm, rlmObjectSchema, + &*schema.find(rlmObjectSchema.className.UTF8String))); + } +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMCollection.mm b/SiriKitExample/Pods/Realm/Realm/RLMCollection.mm new file mode 100644 index 0000000..8b1bfe1 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMCollection.mm @@ -0,0 +1,344 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMCollection_Private.hpp" + +#import "RLMArray_Private.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObject_Private.hpp" + +#import "collection_notifications.hpp" +#import "list.hpp" +#import "results.hpp" + +#import + +static const int RLMEnumerationBufferSize = 16; + +@implementation RLMFastEnumerator { + // The buffer supplied by fast enumeration does not retain the objects given + // to it, but because we create objects on-demand and don't want them + // autoreleased (a table can have more rows than the device has memory for + // accessor objects) we need a thing to retain them. + id _strongBuffer[RLMEnumerationBufferSize]; + + RLMRealm *_realm; + RLMClassInfo *_info; + + // Collection being enumerated. Only one of these two will be valid: when + // possible we enumerate the collection directly, but when in a write + // transaction we instead create a frozen TableView and enumerate that + // instead so that mutating the collection during enumeration works. + id _collection; + realm::TableView _tableView; +} + +- (instancetype)initWithCollection:(id)collection objectSchema:(RLMClassInfo&)info { + self = [super init]; + if (self) { + _realm = collection.realm; + _info = &info; + + if (_realm.inWriteTransaction) { + _tableView = [collection tableView]; + } + else { + _collection = collection; + [_realm registerEnumerator:self]; + } + } + return self; +} + +- (void)dealloc { + if (_collection) { + [_realm unregisterEnumerator:self]; + } +} + +- (void)detach { + _tableView = [_collection tableView]; + _collection = nil; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state + count:(NSUInteger)len { + [_realm verifyThread]; + if (!_tableView.is_attached() && !_collection) { + @throw RLMException(@"Collection is no longer valid"); + } + // The fast enumeration buffer size is currently a hardcoded number in the + // compiler so this can't actually happen, but just in case it changes in + // the future... + if (len > RLMEnumerationBufferSize) { + len = RLMEnumerationBufferSize; + } + + NSUInteger batchCount = 0, count = state->extra[1]; + + Class accessorClass = _info->rlmObjectSchema.accessorClass; + for (NSUInteger index = state->state; index < count && batchCount < len; ++index) { + RLMObject *accessor = RLMCreateManagedAccessor(accessorClass, _realm, _info); + if (_collection) { + accessor->_row = (*_info->table())[[_collection indexInSource:index]]; + } + else if (_tableView.is_row_attached(index)) { + accessor->_row = (*_info->table())[_tableView.get_source_ndx(index)]; + } + RLMInitializeSwiftAccessorGenerics(accessor); + _strongBuffer[batchCount] = accessor; + batchCount++; + } + + for (NSUInteger i = batchCount; i < len; ++i) { + _strongBuffer[i] = nil; + } + + if (batchCount == 0) { + // Release our data if we're done, as we're autoreleased and so may + // stick around for a while + _collection = nil; + if (_tableView.is_attached()) { + _tableView = {}; + } + else { + [_realm unregisterEnumerator:self]; + } + } + + state->itemsPtr = (__unsafe_unretained id *)(void *)_strongBuffer; + state->state += batchCount; + state->mutationsPtr = state->extra+1; + + return batchCount; +} +@end + + +NSArray *RLMCollectionValueForKey(id collection, NSString *key) { + size_t count = collection.count; + if (count == 0) { + return @[]; + } + + RLMRealm *realm = collection.realm; + RLMClassInfo *info = collection.objectInfo; + + NSMutableArray *results = [NSMutableArray arrayWithCapacity:count]; + if ([key isEqualToString:@"self"]) { + for (size_t i = 0; i < count; i++) { + size_t rowIndex = [collection indexInSource:i]; + [results addObject:RLMCreateObjectAccessor(realm, *info, rowIndex) ?: NSNull.null]; + } + return results; + } + + RLMObject *accessor = RLMCreateManagedAccessor(info->rlmObjectSchema.accessorClass, realm, info); + realm::Table *table = info->table(); + for (size_t i = 0; i < count; i++) { + size_t rowIndex = [collection indexInSource:i]; + accessor->_row = (*table)[rowIndex]; + RLMInitializeSwiftAccessorGenerics(accessor); + [results addObject:[accessor valueForKey:key] ?: NSNull.null]; + } + + return results; +} + +void RLMCollectionSetValueForKey(id collection, NSString *key, id value) { + realm::TableView tv = [collection tableView]; + if (tv.size() == 0) { + return; + } + + RLMRealm *realm = collection.realm; + RLMClassInfo *info = collection.objectInfo; + RLMObject *accessor = RLMCreateManagedAccessor(info->rlmObjectSchema.accessorClass, realm, info); + for (size_t i = 0; i < tv.size(); i++) { + accessor->_row = tv[i]; + RLMInitializeSwiftAccessorGenerics(accessor); + [accessor setValue:value forKey:key]; + } +} + +NSString *RLMDescriptionWithMaxDepth(NSString *name, + id collection, + NSUInteger depth) { + if (depth == 0) { + return @""; + } + + const NSUInteger maxObjects = 100; + auto str = [NSMutableString stringWithFormat:@"%@ <%p> (\n", name, (void *)collection]; + size_t index = 0, skipped = 0; + for (id obj in collection) { + NSString *sub; + if ([obj respondsToSelector:@selector(descriptionWithMaxDepth:)]) { + sub = [obj descriptionWithMaxDepth:depth - 1]; + } + else { + sub = [obj description]; + } + + // Indent child objects + NSString *objDescription = [sub stringByReplacingOccurrencesOfString:@"\n" + withString:@"\n\t"]; + [str appendFormat:@"\t[%zu] %@,\n", index++, objDescription]; + if (index >= maxObjects) { + skipped = collection.count - maxObjects; + break; + } + } + + // Remove last comma and newline characters + if (collection.count > 0) { + [str deleteCharactersInRange:NSMakeRange(str.length-2, 2)]; + } + if (skipped) { + [str appendFormat:@"\n\t... %zu objects skipped.", skipped]; + } + [str appendFormat:@"\n)"]; + return str; +} + +@implementation RLMCancellationToken { + realm::NotificationToken _token; +} +- (instancetype)initWithToken:(realm::NotificationToken)token { + self = [super init]; + if (self) { + _token = std::move(token); + } + return self; +} + +- (void)stop { + _token = {}; +} + +@end + +@implementation RLMCollectionChange { + realm::CollectionChangeSet _indices; +} + +- (instancetype)initWithChanges:(realm::CollectionChangeSet)indices { + self = [super init]; + if (self) { + _indices = std::move(indices); + } + return self; +} + +static NSArray *toArray(realm::IndexSet const& set) { + NSMutableArray *ret = [NSMutableArray new]; + for (auto index : set.as_indexes()) { + [ret addObject:@(index)]; + } + return ret; +} + +- (NSArray *)insertions { + return toArray(_indices.insertions); +} + +- (NSArray *)deletions { + return toArray(_indices.deletions); +} + +- (NSArray *)modifications { + return toArray(_indices.modifications); +} + +static NSArray *toIndexPathArray(realm::IndexSet const& set, NSUInteger section) { + NSMutableArray *ret = [NSMutableArray new]; + NSUInteger path[2] = {section, 0}; + for (auto index : set.as_indexes()) { + path[1] = index; + [ret addObject:[NSIndexPath indexPathWithIndexes:path length:2]]; + } + return ret; +} + +- (NSArray *)deletionsInSection:(NSUInteger)section { + return toIndexPathArray(_indices.deletions, section); +} + +- (NSArray *)insertionsInSection:(NSUInteger)section { + return toIndexPathArray(_indices.insertions, section); + +} + +- (NSArray *)modificationsInSection:(NSUInteger)section { + return toIndexPathArray(_indices.modifications, section); + +} +@end + +template +RLMNotificationToken *RLMAddNotificationBlock(id objcCollection, + Collection& collection, + void (^block)(id, RLMCollectionChange *, NSError *), + bool suppressInitialChange) { + struct IsValid { + static bool call(realm::List const& list) { + return list.is_valid(); + } + static bool call(realm::Results const&) { + return true; + } + }; + + auto skip = suppressInitialChange ? std::make_shared(true) : nullptr; + auto cb = [=, &collection](realm::CollectionChangeSet const& changes, + std::exception_ptr err) { + if (err) { + try { + rethrow_exception(err); + } + catch (...) { + NSError *error = nil; + RLMRealmTranslateException(&error); + block(nil, nil, error); + return; + } + } + + if (!IsValid::call(collection)) { + return; + } + + if (skip && *skip) { + *skip = false; + block(objcCollection, nil, nil); + } + else if (changes.empty()) { + block(objcCollection, nil, nil); + } + else { + block(objcCollection, [[RLMCollectionChange alloc] initWithChanges:changes], nil); + } + }; + + return [[RLMCancellationToken alloc] initWithToken:collection.add_notification_callback(cb)]; +} + +// Explicitly instantiate the templated function for the two types we'll use it on +template RLMNotificationToken *RLMAddNotificationBlock(id, realm::List&, void (^)(id, RLMCollectionChange *, NSError *), bool); +template RLMNotificationToken *RLMAddNotificationBlock(id, realm::Results&, void (^)(id, RLMCollectionChange *, NSError *), bool); diff --git a/SiriKitExample/Pods/Realm/Realm/RLMConstants.m b/SiriKitExample/Pods/Realm/Realm/RLMConstants.m new file mode 100644 index 0000000..7136127 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMConstants.m @@ -0,0 +1,34 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import + +RLMNotification const RLMRealmRefreshRequiredNotification = @"RLMRealmRefreshRequiredNotification"; +RLMNotification const RLMRealmDidChangeNotification = @"RLMRealmDidChangeNotification"; + +NSString * const RLMErrorDomain = @"io.realm"; + +NSString * const RLMUnknownSystemErrorDomain = @"io.realm.unknown"; + +NSString * const RLMExceptionName = @"RLMException"; + +NSString * const RLMRealmVersionKey = @"RLMRealmVersion"; + +NSString * const RLMRealmCoreVersionKey = @"RLMRealmCoreVersion"; + +NSString * const RLMInvalidatedKey = @"invalidated"; diff --git a/SiriKitExample/Pods/Realm/Realm/RLMListBase.mm b/SiriKitExample/Pods/Realm/Realm/RLMListBase.mm new file mode 100644 index 0000000..78cf91a --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMListBase.mm @@ -0,0 +1,60 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMListBase.h" + +#import "RLMArray_Private.hpp" +#import "RLMObservation.hpp" + +@interface RLMArray (KVO) +- (NSArray *)objectsAtIndexes:(__unused NSIndexSet *)indexes; +@end + +@implementation RLMListBase { + std::unique_ptr _observationInfo; +} + +- (instancetype)initWithArray:(RLMArray *)array { + self = [super init]; + if (self) { + __rlmArray = array; + } + return self; +} + +- (id)valueForKey:(NSString *)key { + return [__rlmArray valueForKey:key]; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len { + return [__rlmArray countByEnumeratingWithState:state objects:buffer count:len]; +} + +- (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes { + return [__rlmArray objectsAtIndexes:indexes]; +} + +- (void)addObserver:(id)observer + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context { + RLMEnsureArrayObservationInfo(_observationInfo, keyPath, __rlmArray, self); + [super addObserver:observer forKeyPath:keyPath options:options context:context]; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMMigration.mm b/SiriKitExample/Pods/Realm/Realm/RLMMigration.mm new file mode 100644 index 0000000..6d8da01 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMMigration.mm @@ -0,0 +1,162 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMMigration_Private.h" + +#import "RLMAccessor.h" +#import "RLMObject_Private.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMProperty_Private.h" +#import "RLMRealm_Dynamic.h" +#import "RLMRealm_Private.hpp" +#import "RLMResults_Private.h" +#import "RLMSchema_Private.hpp" +#import "RLMUtil.hpp" + +#import "object_store.hpp" +#import "shared_realm.hpp" +#import "schema.hpp" + +#import + +using namespace realm; + +// The source realm for a migration has to use a SharedGroup to be able to share +// the file with the destination realm, but we don't want to let the user call +// beginWriteTransaction on it as that would make no sense. +@interface RLMMigrationRealm : RLMRealm +@end + +@implementation RLMMigrationRealm +- (BOOL)readonly { + return YES; +} + +- (void)beginWriteTransaction { + @throw RLMException(@"Cannot modify the source Realm in a migration"); +} +@end + +@implementation RLMMigration { + realm::Schema *_schema; +} + +- (instancetype)initWithRealm:(RLMRealm *)realm oldRealm:(RLMRealm *)oldRealm schema:(realm::Schema &)schema { + self = [super init]; + if (self) { + _realm = realm; + _oldRealm = oldRealm; + _schema = &schema; + object_setClass(_oldRealm, RLMMigrationRealm.class); + } + return self; +} + +- (RLMSchema *)oldSchema { + return self.oldRealm.schema; +} + +- (RLMSchema *)newSchema { + return self.realm.schema; +} + +- (void)enumerateObjects:(NSString *)className block:(RLMObjectMigrationBlock)block { + // get all objects + RLMResults *objects = [_realm.schema schemaForClassName:className] ? [_realm allObjects:className] : nil; + RLMResults *oldObjects = [_oldRealm.schema schemaForClassName:className] ? [_oldRealm allObjects:className] : nil; + + if (objects && oldObjects) { + for (long i = oldObjects.count - 1; i >= 0; i--) { + @autoreleasepool { + block(oldObjects[i], objects[i]); + } + } + } + else if (objects) { + for (long i = objects.count - 1; i >= 0; i--) { + @autoreleasepool { + block(nil, objects[i]); + } + } + } + else if (oldObjects) { + for (long i = oldObjects.count - 1; i >= 0; i--) { + @autoreleasepool { + block(oldObjects[i], nil); + } + } + } +} + +- (void)execute:(RLMMigrationBlock)block { + @autoreleasepool { + // disable all primary keys for migration and use DynamicObject for all types + for (RLMObjectSchema *objectSchema in _realm.schema.objectSchema) { + objectSchema.accessorClass = RLMDynamicObject.class; + objectSchema.primaryKeyProperty.isPrimary = NO; + } + for (RLMObjectSchema *objectSchema in _oldRealm.schema.objectSchema) { + objectSchema.accessorClass = RLMDynamicObject.class; + } + + block(self, _oldRealm->_realm->schema_version()); + + _oldRealm = nil; + _realm = nil; + } +} + +- (RLMObject *)createObject:(NSString *)className withValue:(id)value { + return [_realm createObject:className withValue:value]; +} + +- (RLMObject *)createObject:(NSString *)className withObject:(id)object { + return [self createObject:className withValue:object]; +} + +- (void)deleteObject:(RLMObject *)object { + [_realm deleteObject:object]; +} + +- (BOOL)deleteDataForClassName:(NSString *)name { + if (!name) { + return false; + } + + TableRef table = ObjectStore::table_for_object_type(_realm.group, name.UTF8String); + if (!table) { + return false; + } + + if ([_realm.schema schemaForClassName:name]) { + table->clear(); + } + else { + realm::ObjectStore::delete_data_for_object(_realm.group, name.UTF8String); + } + + return true; +} + +- (void)renamePropertyForClass:(NSString *)className oldName:(NSString *)oldName newName:(NSString *)newName { + const char *objectType = className.UTF8String; + realm::ObjectStore::rename_property(_realm.group, *_schema, objectType, oldName.UTF8String, newName.UTF8String); +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMObject.mm b/SiriKitExample/Pods/Realm/Realm/RLMObject.mm new file mode 100644 index 0000000..fb98d6c --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMObject.mm @@ -0,0 +1,223 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMObject_Private.hpp" + +#import "RLMAccessor.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMQueryUtil.hpp" +#import "RLMRealm_Private.hpp" +#import "RLMSchema_Private.h" + +// We declare things in RLMObject which are actually implemented in RLMObjectBase +// for documentation's sake, which leads to -Wunimplemented-method warnings. +// Other alternatives to this would be to disable -Wunimplemented-method for this +// file (but then we could miss legitimately missing things), or declaring the +// inherited things in a category (but they currently aren't nicely grouped for +// that). +@implementation RLMObject + +// synthesized in RLMObjectBase +@dynamic invalidated, realm, objectSchema; + +#pragma mark - Designated Initializers + +- (instancetype)init { + return [super init]; +} + +- (instancetype)initWithValue:(id)value schema:(RLMSchema *)schema { + return [super initWithValue:value schema:schema]; +} + +- (instancetype)initWithRealm:(__unsafe_unretained RLMRealm *const)realm schema:(RLMObjectSchema *)schema { + return [super initWithRealm:realm schema:schema]; +} + +#pragma mark - Convenience Initializers + +- (instancetype)initWithValue:(id)value { + [self.class sharedSchema]; // ensure this class' objectSchema is loaded in the partialSharedSchema + RLMSchema *schema = RLMSchema.partialSharedSchema; + return [super initWithValue:value schema:schema]; +} + +#pragma mark - Class-based Object Creation + ++ (instancetype)createInDefaultRealmWithValue:(id)value { + return (RLMObject *)RLMCreateObjectInRealmWithValue([RLMRealm defaultRealm], [self className], value, false); +} + ++ (instancetype)createInRealm:(RLMRealm *)realm withValue:(id)value { + return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, false); +} + ++ (instancetype)createOrUpdateInDefaultRealmWithValue:(id)value { + return [self createOrUpdateInRealm:[RLMRealm defaultRealm] withValue:value]; +} + ++ (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value { + // verify primary key + RLMObjectSchema *schema = [self sharedSchema]; + if (!schema.primaryKeyProperty) { + NSString *reason = [NSString stringWithFormat:@"'%@' does not have a primary key and can not be updated", schema.className]; + @throw [NSException exceptionWithName:@"RLMExecption" reason:reason userInfo:nil]; + } + return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, true); +} + +#pragma mark - Subscripting + +- (id)objectForKeyedSubscript:(NSString *)key { + return RLMObjectBaseObjectForKeyedSubscript(self, key); +} + +- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key { + RLMObjectBaseSetObjectForKeyedSubscript(self, key, obj); +} + +#pragma mark - Getting & Querying + ++ (RLMResults *)allObjects { + return RLMGetObjects(RLMRealm.defaultRealm, self.className, nil); +} + ++ (RLMResults *)allObjectsInRealm:(RLMRealm *)realm { + return RLMGetObjects(realm, self.className, nil); +} + ++ (RLMResults *)objectsWhere:(NSString *)predicateFormat, ... { + va_list args; + va_start(args, predicateFormat); + RLMResults *results = [self objectsWhere:predicateFormat args:args]; + va_end(args); + return results; +} + ++ (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args { + return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]]; +} + ++ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat, ... { + va_list args; + va_start(args, predicateFormat); + RLMResults *results = [self objectsInRealm:realm where:predicateFormat args:args]; + va_end(args); + return results; +} + ++ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat args:(va_list)args { + return [self objectsInRealm:realm withPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]]; +} + ++ (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate { + return RLMGetObjects(RLMRealm.defaultRealm, self.className, predicate); +} + ++ (RLMResults *)objectsInRealm:(RLMRealm *)realm withPredicate:(NSPredicate *)predicate { + return RLMGetObjects(realm, self.className, predicate); +} + ++ (instancetype)objectForPrimaryKey:(id)primaryKey { + return RLMGetObject(RLMRealm.defaultRealm, self.className, primaryKey); +} + ++ (instancetype)objectInRealm:(RLMRealm *)realm forPrimaryKey:(id)primaryKey { + return RLMGetObject(realm, self.className, primaryKey); +} + +#pragma mark - Other Instance Methods + +- (BOOL)isEqualToObject:(RLMObject *)object { + return [object isKindOfClass:RLMObject.class] && RLMObjectBaseAreEqual(self, object); +} + ++ (NSString *)className { + return [super className]; +} + +#pragma mark - Default values for schema definition + ++ (NSArray *)indexedProperties { + return @[]; +} + ++ (NSDictionary *)linkingObjectsProperties { + return @{}; +} + ++ (NSDictionary *)defaultPropertyValues { + return nil; +} + ++ (NSString *)primaryKey { + return nil; +} + ++ (NSArray *)ignoredProperties { + return nil; +} + ++ (NSArray *)requiredProperties { + return @[]; +} + +@end + +@implementation RLMDynamicObject + ++ (BOOL)shouldIncludeInDefaultSchema { + return NO; +} + +- (id)valueForUndefinedKey:(NSString *)key { + return RLMDynamicGetByName(self, key, false); +} + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key { + RLMDynamicValidatedSet(self, key, value); +} + +@end + +@implementation RLMWeakObjectHandle { + realm::Row _row; + RLMClassInfo *_info; + Class _objectClass; +} + +- (instancetype)initWithObject:(RLMObjectBase *)object { + if (!(self = [super init])) { + return nil; + } + + _row = object->_row; + _info = object->_info; + _objectClass = object.class; + + return self; +} + +- (RLMObjectBase *)object { + RLMObjectBase *object = RLMCreateManagedAccessor(_objectClass, _info->realm, _info); + object->_row = std::move(_row); + return object; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMObjectBase.mm b/SiriKitExample/Pods/Realm/Realm/RLMObjectBase.mm new file mode 100644 index 0000000..80e5205 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMObjectBase.mm @@ -0,0 +1,450 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMObject_Private.hpp" + +#import "RLMAccessor.h" +#import "RLMArray_Private.hpp" +#import "RLMListBase.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObservation.hpp" +#import "RLMOptionalBase.h" +#import "RLMProperty_Private.h" +#import "RLMRealm_Private.hpp" +#import "RLMSchema_Private.h" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +using namespace realm; + +const NSUInteger RLMDescriptionMaxDepth = 5; + +static bool maybeInitObjectSchemaForUnmanaged(RLMObjectBase *obj) { + obj->_objectSchema = [obj.class sharedSchema]; + if (!obj->_objectSchema) { + return false; + } + + // set default values + if (!obj->_objectSchema.isSwiftClass) { + NSDictionary *dict = RLMDefaultValuesForObjectSchema(obj->_objectSchema); + for (NSString *key in dict) { + [obj setValue:dict[key] forKey:key]; + } + } + + // set unmanaged accessor class + object_setClass(obj, obj->_objectSchema.unmanagedClass); + return true; +} + +@implementation RLMObjectBase +// unmanaged init +- (instancetype)init { + if ((self = [super init])) { + maybeInitObjectSchemaForUnmanaged(self); + } + return self; +} + +- (void)dealloc { + // This can't be a unique_ptr because associated objects are removed + // *after* c++ members are destroyed and dealloc is called, and we need it + // to be in a validish state when that happens + delete _observationInfo; + _observationInfo = nullptr; +} + +static id validatedObjectForProperty(id obj, RLMProperty *prop, RLMSchema *schema) { + if (RLMIsObjectValidForProperty(obj, prop)) { + return obj; + } + + // check for object or array of properties + if (prop.type == RLMPropertyTypeObject) { + // for object create and try to initialize with obj + RLMObjectSchema *objSchema = schema[prop.objectClassName]; + return [[objSchema.objectClass alloc] initWithValue:obj schema:schema]; + } + else if (prop.type == RLMPropertyTypeArray && [obj conformsToProtocol:@protocol(NSFastEnumeration)]) { + // for arrays, create objects for each element and return new array + RLMObjectSchema *objSchema = schema[prop.objectClassName]; + RLMArray *objects = [[RLMArray alloc] initWithObjectClassName:objSchema.className]; + for (id el in obj) { + [objects addObject:[[objSchema.objectClass alloc] initWithValue:el schema:schema]]; + } + return objects; + } + + // if not convertible to prop throw + @throw RLMException(@"Invalid value '%@' for property '%@'", obj, prop.name); +} + +- (instancetype)initWithValue:(id)value schema:(RLMSchema *)schema { + if (!(self = [super init])) { + return self; + } + + if (!maybeInitObjectSchemaForUnmanaged(self)) { + // Don't populate fields from the passed-in object if we're called + // during schema init + return self; + } + + NSArray *properties = _objectSchema.properties; + if (NSArray *array = RLMDynamicCast(value)) { + if (array.count != properties.count) { + @throw RLMException(@"Invalid array input. Number of array elements does not match number of properties."); + } + for (NSUInteger i = 0; i < array.count; i++) { + id propertyValue = validatedObjectForProperty(array[i], properties[i], schema); + [self setValue:RLMCoerceToNil(propertyValue) forKeyPath:[properties[i] name]]; + } + } + else if (value) { + // assume our object is an NSDictionary or an object with kvc properties + NSDictionary *defaultValues = nil; + for (RLMProperty *prop in properties) { + id obj = RLMValidatedValueForProperty(value, prop.name, _objectSchema.className); + + // get default for nil object + if (!obj) { + if (!defaultValues) { + defaultValues = RLMDefaultValuesForObjectSchema(_objectSchema); + } + obj = defaultValues[prop.name]; + } + + // don't set unspecified properties + if (!obj) { + continue; + } + + obj = validatedObjectForProperty(obj, prop, schema); + [self setValue:RLMCoerceToNil(obj) forKeyPath:prop.name]; + } + } else { + @throw RLMException(@"Must provide a non-nil value."); + } + + return self; +} + +id RLMCreateManagedAccessor(Class cls, __unsafe_unretained RLMRealm *realm, RLMClassInfo *info) { + RLMObjectBase *obj = [[cls alloc] initWithRealm:realm schema:info->rlmObjectSchema]; + obj->_info = info; + return obj; +} + +- (instancetype)initWithRealm:(__unsafe_unretained RLMRealm *const)realm + schema:(RLMObjectSchema *)schema { + self = [super init]; + if (self) { + _realm = realm; + _objectSchema = schema; + } + return self; +} + +- (id)valueForKey:(NSString *)key { + if (_observationInfo) { + return _observationInfo->valueForKey(key); + } + return [super valueForKey:key]; +} + +// Generic Swift properties can't be dynamic, so KVO doesn't work for them by default +- (id)valueForUndefinedKey:(NSString *)key { + if (Ivar ivar = _objectSchema[key].swiftIvar) { + return RLMCoerceToNil(object_getIvar(self, ivar)); + } + return [super valueForUndefinedKey:key]; +} + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key { + RLMProperty *property = _objectSchema[key]; + if (Ivar ivar = property.swiftIvar) { + if (property.type == RLMPropertyTypeArray && [value conformsToProtocol:@protocol(NSFastEnumeration)]) { + RLMArray *array = [object_getIvar(self, ivar) _rlmArray]; + [array removeAllObjects]; + [array addObjects:value]; + } + else if (property.optional) { + RLMOptionalBase *optional = object_getIvar(self, ivar); + optional.underlyingValue = value; + } + return; + } + [super setValue:value forUndefinedKey:key]; +} + +// overridden at runtime per-class for performance ++ (NSString *)className { + NSString *className = NSStringFromClass(self); + if ([RLMSwiftSupport isSwiftClassName:className]) { + className = [RLMSwiftSupport demangleClassName:className]; + } + return className; +} + +// overridden at runtime per-class for performance ++ (RLMObjectSchema *)sharedSchema { + return [RLMSchema sharedSchemaForClass:self.class]; +} + ++ (Class)objectUtilClass:(BOOL)isSwift { + return RLMObjectUtilClass(isSwift); +} + +- (NSString *)description +{ + if (self.isInvalidated) { + return @"[invalid object]"; + } + + return [self descriptionWithMaxDepth:RLMDescriptionMaxDepth]; +} + +- (NSString *)descriptionWithMaxDepth:(NSUInteger)depth { + if (depth == 0) { + return @""; + } + + NSString *baseClassName = _objectSchema.className; + NSMutableString *mString = [NSMutableString stringWithFormat:@"%@ {\n", baseClassName]; + + for (RLMProperty *property in _objectSchema.properties) { + id object = RLMObjectBaseObjectForKeyedSubscript(self, property.name); + NSString *sub; + if ([object respondsToSelector:@selector(descriptionWithMaxDepth:)]) { + sub = [object descriptionWithMaxDepth:depth - 1]; + } + else if (property.type == RLMPropertyTypeData) { + static NSUInteger maxPrintedDataLength = 24; + NSData *data = object; + NSUInteger length = data.length; + if (length > maxPrintedDataLength) { + data = [NSData dataWithBytes:data.bytes length:maxPrintedDataLength]; + } + NSString *dataDescription = [data description]; + sub = [NSString stringWithFormat:@"<%@ — %lu total bytes>", [dataDescription substringWithRange:NSMakeRange(1, dataDescription.length - 2)], (unsigned long)length]; + } + else { + sub = [object description]; + } + [mString appendFormat:@"\t%@ = %@;\n", property.name, [sub stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]]; + } + [mString appendString:@"}"]; + + return [NSString stringWithString:mString]; +} + +- (RLMRealm *)realm { + return _realm; +} + +- (RLMObjectSchema *)objectSchema { + return _objectSchema; +} + +- (BOOL)isInvalidated { + // if not unmanaged and our accessor has been detached, we have been deleted + return self.class == _objectSchema.accessorClass && !_row.is_attached(); +} + +- (BOOL)isEqual:(id)object { + if (RLMObjectBase *other = RLMDynamicCast(object)) { + if (_objectSchema.primaryKeyProperty) { + return RLMObjectBaseAreEqual(self, other); + } + } + return [super isEqual:object]; +} + +- (NSUInteger)hash { + if (_objectSchema.primaryKeyProperty) { + id primaryProperty = [self valueForKey:_objectSchema.primaryKeyProperty.name]; + + // modify the hash of our primary key value to avoid potential (although unlikely) collisions + return [primaryProperty hash] ^ 1; + } + else { + return [super hash]; + } +} + ++ (BOOL)shouldIncludeInDefaultSchema { + return RLMIsObjectSubclass(self); +} + +- (id)mutableArrayValueForKey:(NSString *)key { + id obj = [self valueForKey:key]; + if ([obj isKindOfClass:[RLMArray class]]) { + return obj; + } + return [super mutableArrayValueForKey:key]; +} + +- (void)addObserver:(id)observer + forKeyPath:(NSString *)keyPath + options:(NSKeyValueObservingOptions)options + context:(void *)context { + if (!_observationInfo) { + _observationInfo = new RLMObservationInfo(self); + } + _observationInfo->recordObserver(_row, _info, _objectSchema, keyPath); + + [super addObserver:observer forKeyPath:keyPath options:options context:context]; +} + +- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath { + [super removeObserver:observer forKeyPath:keyPath]; + if (_observationInfo) + _observationInfo->removeObserver(); +} + ++ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { + const char *className = class_getName(self); + const char accessorClassPrefix[] = "RLMAccessor_"; + if (!strncmp(className, accessorClassPrefix, sizeof(accessorClassPrefix) - 1)) { + if (self.sharedSchema[key]) { + return NO; + } + } + + return [super automaticallyNotifiesObserversForKey:key]; +} + +@end + +RLMRealm *RLMObjectBaseRealm(__unsafe_unretained RLMObjectBase *object) { + return object ? object->_realm : nil; +} + +RLMObjectSchema *RLMObjectBaseObjectSchema(__unsafe_unretained RLMObjectBase *object) { + return object ? object->_objectSchema : nil; +} + +id RLMObjectBaseObjectForKeyedSubscript(RLMObjectBase *object, NSString *key) { + if (!object) { + return nil; + } + + if (object->_realm) { + return RLMDynamicGetByName(object, key, false); + } + else { + return [object valueForKey:key]; + } +} + +void RLMObjectBaseSetObjectForKeyedSubscript(RLMObjectBase *object, NSString *key, id obj) { + if (!object) { + return; + } + + if (object->_realm) { + RLMDynamicValidatedSet(object, key, obj); + } + else { + [object setValue:obj forKey:key]; + } +} + + +BOOL RLMObjectBaseAreEqual(RLMObjectBase *o1, RLMObjectBase *o2) { + // if not the correct types throw + if ((o1 && ![o1 isKindOfClass:RLMObjectBase.class]) || (o2 && ![o2 isKindOfClass:RLMObjectBase.class])) { + @throw RLMException(@"Can only compare objects of class RLMObjectBase"); + } + // if identical object (or both are nil) + if (o1 == o2) { + return YES; + } + // if one is nil + if (o1 == nil || o2 == nil) { + return NO; + } + // if not in realm or differing realms + if (o1->_realm == nil || o1->_realm != o2->_realm) { + return NO; + } + // if either are detached + if (!o1->_row.is_attached() || !o2->_row.is_attached()) { + return NO; + } + // if table and index are the same + return o1->_row.get_table() == o2->_row.get_table() + && o1->_row.get_index() == o2->_row.get_index(); +} + +id RLMValidatedValueForProperty(id object, NSString *key, NSString *className) { + @try { + return [object valueForKey:key]; + } + @catch (NSException *e) { + if ([e.name isEqualToString:NSUndefinedKeyException]) { + @throw RLMException(@"Invalid value '%@' to initialize object of type '%@': missing key '%@'", + object, className, key); + } + @throw; + } +} + +Class RLMObjectUtilClass(BOOL isSwift) { + static Class objectUtilObjc = [RLMObjectUtil class]; + static Class objectUtilSwift = NSClassFromString(@"RealmSwiftObjectUtil"); + return isSwift && objectUtilSwift ? objectUtilSwift : objectUtilObjc; +} + +@implementation RLMObjectUtil + ++ (NSArray *)ignoredPropertiesForClass:(Class)cls { + return [cls ignoredProperties]; +} + ++ (NSArray *)indexedPropertiesForClass:(Class)cls { + return [cls indexedProperties]; +} + ++ (NSDictionary *)linkingObjectsPropertiesForClass:(Class)cls { + return [cls linkingObjectsProperties]; +} + ++ (NSDictionary *)linkingObjectProperties:(__unused id)object { + return nil; +} + ++ (NSArray *)getGenericListPropertyNames:(__unused id)obj { + return nil; +} + ++ (NSDictionary *)getLinkingObjectsProperties:(__unused id)obj { + return nil; +} + ++ (NSDictionary *)getOptionalProperties:(__unused id)obj { + return nil; +} + ++ (NSArray *)requiredPropertiesForClass:(Class)cls { + return [cls requiredProperties]; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMObjectSchema.mm b/SiriKitExample/Pods/Realm/Realm/RLMObjectSchema.mm new file mode 100644 index 0000000..8762dae --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMObjectSchema.mm @@ -0,0 +1,440 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMObjectSchema_Private.hpp" + +#import "RLMArray.h" +#import "RLMListBase.h" +#import "RLMObject_Private.h" +#import "RLMProperty_Private.hpp" +#import "RLMRealm_Dynamic.h" +#import "RLMRealm_Private.hpp" +#import "RLMSchema_Private.h" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +#import "object_store.hpp" + +using namespace realm; + +// private properties +@interface RLMObjectSchema () +@property (nonatomic, readwrite) NSDictionary *allPropertiesByName; +@property (nonatomic, readwrite) NSString *className; +@end + +@implementation RLMObjectSchema { + NSArray *_swiftGenericProperties; +} + +- (instancetype)initWithClassName:(NSString *)objectClassName objectClass:(Class)objectClass properties:(NSArray *)properties { + self = [super init]; + self.className = objectClassName; + self.properties = properties; + self.objectClass = objectClass; + self.accessorClass = objectClass; + self.unmanagedClass = objectClass; + return self; +} + +// return properties by name +-(RLMProperty *)objectForKeyedSubscript:(__unsafe_unretained NSString *const)key { + return _allPropertiesByName[key]; +} + +// create property map when setting property array +-(void)setProperties:(NSArray *)properties { + _properties = properties; + [self _propertiesDidChange]; +} + +- (void)setComputedProperties:(NSArray *)computedProperties { + _computedProperties = computedProperties; + [self _propertiesDidChange]; +} + +- (void)_propertiesDidChange { + NSMutableDictionary *map = [NSMutableDictionary dictionaryWithCapacity:_properties.count + _computedProperties.count]; + NSUInteger index = 0; + for (RLMProperty *prop in _properties) { + prop.index = index++; + map[prop.name] = prop; + if (prop.isPrimary) { + self.primaryKeyProperty = prop; + } + } + for (RLMProperty *prop in _computedProperties) { + map[prop.name] = prop; + } + _allPropertiesByName = map; +} + + +- (void)setPrimaryKeyProperty:(RLMProperty *)primaryKeyProperty { + _primaryKeyProperty.isPrimary = NO; + primaryKeyProperty.isPrimary = YES; + _primaryKeyProperty = primaryKeyProperty; +} + ++ (instancetype)schemaForObjectClass:(Class)objectClass { + RLMObjectSchema *schema = [RLMObjectSchema new]; + + // determine classname from objectclass as className method has not yet been updated + NSString *className = NSStringFromClass(objectClass); + bool isSwift = [RLMSwiftSupport isSwiftClassName:className]; + if (isSwift) { + className = [RLMSwiftSupport demangleClassName:className]; + } + schema.className = className; + schema.objectClass = objectClass; + schema.accessorClass = objectClass; + schema.isSwiftClass = isSwift; + + // create array of RLMProperties, inserting properties of superclasses first + Class cls = objectClass; + Class superClass = class_getSuperclass(cls); + NSArray *allProperties = @[]; + while (superClass && superClass != RLMObjectBase.class) { + allProperties = [[RLMObjectSchema propertiesForClass:cls isSwift:isSwift] arrayByAddingObjectsFromArray:allProperties]; + cls = superClass; + superClass = class_getSuperclass(superClass); + } + NSArray *persistedProperties = [allProperties filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(RLMProperty *property, NSDictionary *) { + return !RLMPropertyTypeIsComputed(property.type); + }]]; + schema.properties = persistedProperties; + + NSArray *computedProperties = [allProperties filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(RLMProperty *property, NSDictionary *) { + return RLMPropertyTypeIsComputed(property.type); + }]]; + schema.computedProperties = computedProperties; + + // verify that we didn't add any properties twice due to inheritance + if (allProperties.count != [NSSet setWithArray:[allProperties valueForKey:@"name"]].count) { + NSCountedSet *countedPropertyNames = [NSCountedSet setWithArray:[allProperties valueForKey:@"name"]]; + NSSet *duplicatePropertyNames = [countedPropertyNames filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *) { + return [countedPropertyNames countForObject:object] > 1; + }]]; + + if (duplicatePropertyNames.count == 1) { + @throw RLMException(@"Property '%@' is declared multiple times in the class hierarchy of '%@'", duplicatePropertyNames.allObjects.firstObject, className); + } else { + @throw RLMException(@"Object '%@' has properties that are declared multiple times in its class hierarchy: '%@'", className, [duplicatePropertyNames.allObjects componentsJoinedByString:@"', '"]); + } + } + + if (NSString *primaryKey = [objectClass primaryKey]) { + for (RLMProperty *prop in schema.properties) { + if ([primaryKey isEqualToString:prop.name]) { + prop.indexed = YES; + schema.primaryKeyProperty = prop; + break; + } + } + + if (!schema.primaryKeyProperty) { + @throw RLMException(@"Primary key property '%@' does not exist on object '%@'", primaryKey, className); + } + if (schema.primaryKeyProperty.type != RLMPropertyTypeInt && schema.primaryKeyProperty.type != RLMPropertyTypeString) { + @throw RLMException(@"Only 'string' and 'int' properties can be designated the primary key"); + } + } + + for (RLMProperty *prop in schema.properties) { + if (prop.optional && !RLMPropertyTypeIsNullable(prop.type)) { + @throw RLMException(@"Only 'string', 'binary', and 'object' properties can be made optional, and property '%@' is of type '%@'.", + prop.name, RLMTypeToString(prop.type)); + } + } + + return schema; +} + ++ (nullable NSString *)baseNameForLazySwiftProperty:(NSString *)propertyName { + // A Swift lazy var shows up as two separate children on the reflection tree: one named 'x', and another that is + // optional and is named 'x.storage'. Note that '.' is illegal in either a Swift or Objective-C property name. + NSString *const storageSuffix = @".storage"; + if ([propertyName hasSuffix:storageSuffix]) { + return [propertyName substringToIndex:propertyName.length - storageSuffix.length]; + } + return nil; +} + ++ (NSArray *)propertiesForClass:(Class)objectClass isSwift:(bool)isSwiftClass { + Class objectUtil = [objectClass objectUtilClass:isSwiftClass]; + NSArray *ignoredProperties = [objectUtil ignoredPropertiesForClass:objectClass]; + NSDictionary *linkingObjectsProperties = [objectUtil linkingObjectsPropertiesForClass:objectClass]; + + // For Swift classes we need an instance of the object when parsing properties + id swiftObjectInstance = isSwiftClass ? [[objectClass alloc] init] : nil; + + unsigned int count; + objc_property_t *props = class_copyPropertyList(objectClass, &count); + NSMutableArray *propArray = [NSMutableArray arrayWithCapacity:count]; + NSSet *indexed = [[NSSet alloc] initWithArray:[objectUtil indexedPropertiesForClass:objectClass]]; + for (unsigned int i = 0; i < count; i++) { + NSString *propertyName = @(property_getName(props[i])); + if ([ignoredProperties containsObject:propertyName]) { + continue; + } + + RLMProperty *prop = nil; + if (isSwiftClass) { + prop = [[RLMProperty alloc] initSwiftPropertyWithName:propertyName + indexed:[indexed containsObject:propertyName] + linkPropertyDescriptor:linkingObjectsProperties[propertyName] + property:props[i] + instance:swiftObjectInstance]; + } + else { + prop = [[RLMProperty alloc] initWithName:propertyName + indexed:[indexed containsObject:propertyName] + linkPropertyDescriptor:linkingObjectsProperties[propertyName] + property:props[i]]; + } + + if (prop) { + [propArray addObject:prop]; + } + } + free(props); + + if (isSwiftClass) { + // List<> properties don't show up as objective-C properties due to + // being generic, so use Swift reflection to get a list of them, and + // then access their ivars directly + for (NSString *propName in [objectUtil getGenericListPropertyNames:swiftObjectInstance]) { + Ivar ivar = class_getInstanceVariable(objectClass, propName.UTF8String); + id value = object_getIvar(swiftObjectInstance, ivar); + NSString *className = [value _rlmArray].objectClassName; + NSUInteger existing = [propArray indexOfObjectPassingTest:^BOOL(RLMProperty *obj, __unused NSUInteger idx, __unused BOOL *stop) { + return [obj.name isEqualToString:propName]; + }]; + if (existing != NSNotFound) { + [propArray removeObjectAtIndex:existing]; + } + [propArray addObject:[[RLMProperty alloc] initSwiftListPropertyWithName:propName + ivar:ivar + objectClassName:className]]; + } + + // Ditto for LinkingObjects<> properties. + NSDictionary *linkingObjectsProperties = [objectUtil getLinkingObjectsProperties:swiftObjectInstance]; + for (NSString *propName in linkingObjectsProperties) { + NSDictionary *info = linkingObjectsProperties[propName]; + Ivar ivar = class_getInstanceVariable(objectClass, propName.UTF8String); + + NSUInteger existing = [propArray indexOfObjectPassingTest:^BOOL(RLMProperty *obj, __unused NSUInteger idx, __unused BOOL *stop) { + return [obj.name isEqualToString:propName]; + }]; + if (existing != NSNotFound) { + [propArray removeObjectAtIndex:existing]; + } + + [propArray addObject:[[RLMProperty alloc] initSwiftLinkingObjectsPropertyWithName:propName + ivar:ivar + objectClassName:info[@"class"] + linkOriginPropertyName:info[@"property"]]]; + } + } + + if (auto optionalProperties = [objectUtil getOptionalProperties:swiftObjectInstance]) { + for (RLMProperty *property in propArray) { + property.optional = false; + } + [optionalProperties enumerateKeysAndObjectsUsingBlock:^(NSString *propertyName, NSNumber *propertyType, __unused BOOL *stop) { + if ([ignoredProperties containsObject:propertyName]) { + return; + } + NSUInteger existing = [propArray indexOfObjectPassingTest:^BOOL(RLMProperty *obj, __unused NSUInteger idx, __unused BOOL *stop) { + return [obj.name isEqualToString:propertyName]; + }]; + RLMProperty *property; + if (existing != NSNotFound) { + property = propArray[existing]; + property.optional = true; + } + if (auto type = RLMCoerceToNil(propertyType)) { + if (existing == NSNotFound) { + // Check to see if this optional property is an underlying storage property for a Swift lazy var. + // Managed lazy vars are't allowed. + // NOTE: Revisit this once property behaviors are implemented in Swift. + if (NSString *lazyPropertyBaseName = [self baseNameForLazySwiftProperty:propertyName]) { + if ([ignoredProperties containsObject:lazyPropertyBaseName]) { + // This property is the storage property for a ignored lazy Swift property. Just continue. + return; + } else { + @throw RLMException(@"Lazy managed property '%@' is not allowed on a Realm Swift object class. Either add the property to the ignored properties list or make it non-lazy.", lazyPropertyBaseName); + } + } + // The current property isn't a storage property for a lazy Swift property. + property = [[RLMProperty alloc] initSwiftOptionalPropertyWithName:propertyName + indexed:[indexed containsObject:propertyName] + ivar:class_getInstanceVariable(objectClass, propertyName.UTF8String) + propertyType:RLMPropertyType(type.intValue)]; + [propArray addObject:property]; + } + else { + property.type = RLMPropertyType(type.intValue); + } + } + }]; + } + if (auto requiredProperties = [objectUtil requiredPropertiesForClass:objectClass]) { + for (RLMProperty *property in propArray) { + bool required = [requiredProperties containsObject:property.name]; + if (required && property.type == RLMPropertyTypeObject) { + @throw RLMException(@"Object properties cannot be made required, " + "but '+[%@ requiredProperties]' included '%@'", objectClass, property.name); + } + property.optional &= !required; + } + } + + for (RLMProperty *property in propArray) { + if (!property.optional && property.type == RLMPropertyTypeObject) { // remove if/when core supports required link columns + @throw RLMException(@"The `%@.%@` property must be marked as being optional.", [objectClass className], property.name); + } + } + + return propArray; +} + +- (id)copyWithZone:(NSZone *)zone { + RLMObjectSchema *schema = [[RLMObjectSchema allocWithZone:zone] init]; + schema->_objectClass = _objectClass; + schema->_className = _className; + schema->_objectClass = _objectClass; + schema->_accessorClass = _objectClass; + schema->_unmanagedClass = _unmanagedClass; + schema->_isSwiftClass = _isSwiftClass; + + // call property setter to reset map and primary key + schema.properties = [[NSArray allocWithZone:zone] initWithArray:_properties copyItems:YES]; + schema.computedProperties = [[NSArray allocWithZone:zone] initWithArray:_computedProperties copyItems:YES]; + + return schema; +} + +- (BOOL)isEqualToObjectSchema:(RLMObjectSchema *)objectSchema { + if (objectSchema.properties.count != _properties.count) { + return NO; + } + + if (![_properties isEqualToArray:objectSchema.properties]) { + return NO; + } + if (![_computedProperties isEqualToArray:objectSchema.computedProperties]) { + return NO; + } + + return YES; +} + +- (NSString *)description { + NSMutableString *propertiesString = [NSMutableString string]; + for (RLMProperty *property in self.properties) { + [propertiesString appendFormat:@"\t%@\n", [property.description stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]]; + } + for (RLMProperty *property in self.computedProperties) { + [propertiesString appendFormat:@"\t%@\n", [property.description stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]]; + } + return [NSString stringWithFormat:@"%@ {\n%@}", self.className, propertiesString]; +} + +- (realm::ObjectSchema)objectStoreCopy { + ObjectSchema objectSchema; + objectSchema.name = _className.UTF8String; + objectSchema.primary_key = _primaryKeyProperty ? _primaryKeyProperty.name.UTF8String : ""; + for (RLMProperty *prop in _properties) { + Property p = [prop objectStoreCopy]; + p.is_primary = (prop == _primaryKeyProperty); + objectSchema.persisted_properties.push_back(std::move(p)); + } + for (RLMProperty *prop in _computedProperties) { + objectSchema.computed_properties.push_back([prop objectStoreCopy]); + } + return objectSchema; +} + ++ (instancetype)objectSchemaForObjectStoreSchema:(realm::ObjectSchema const&)objectSchema { + RLMObjectSchema *schema = [RLMObjectSchema new]; + schema.className = @(objectSchema.name.c_str()); + + // create array of RLMProperties + NSMutableArray *properties = [NSMutableArray arrayWithCapacity:objectSchema.persisted_properties.size()]; + for (const Property &prop : objectSchema.persisted_properties) { + RLMProperty *property = [RLMProperty propertyForObjectStoreProperty:prop]; + property.isPrimary = (prop.name == objectSchema.primary_key); + [properties addObject:property]; + } + schema.properties = properties; + + NSMutableArray *computedProperties = [NSMutableArray arrayWithCapacity:objectSchema.computed_properties.size()]; + for (const Property &prop : objectSchema.computed_properties) { + [computedProperties addObject:[RLMProperty propertyForObjectStoreProperty:prop]]; + } + schema.computedProperties = computedProperties; + + // get primary key from realm metadata + if (objectSchema.primary_key.length()) { + NSString *primaryKeyString = [NSString stringWithUTF8String:objectSchema.primary_key.c_str()]; + schema.primaryKeyProperty = schema[primaryKeyString]; + if (!schema.primaryKeyProperty) { + @throw RLMException(@"No property matching primary key '%@'", primaryKeyString); + } + } + + // for dynamic schema use vanilla RLMDynamicObject accessor classes + schema.objectClass = RLMObject.class; + schema.accessorClass = RLMDynamicObject.class; + schema.unmanagedClass = RLMObject.class; + + return schema; +} + +- (NSArray *)swiftGenericProperties { + if (_swiftGenericProperties) { + return _swiftGenericProperties; + } + + // This check isn't semantically required, but avoiding accessing the local + // static helps perf in the obj-c case + if (!_isSwiftClass) { + return _swiftGenericProperties = @[]; + } + + // Check if it's a swift class using the obj-c API + static Class s_swiftObjectClass = NSClassFromString(@"RealmSwiftObject"); + if (![_accessorClass isSubclassOfClass:s_swiftObjectClass]) { + return _swiftGenericProperties = @[]; + } + + NSMutableArray *genericProperties = [NSMutableArray new]; + for (RLMProperty *prop in _properties) { + if (prop->_swiftIvar) { + [genericProperties addObject:prop]; + } + } + // Currently all computed properties are Swift generics + [genericProperties addObjectsFromArray:_computedProperties]; + + return _swiftGenericProperties = genericProperties; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMObjectStore.mm b/SiriKitExample/Pods/Realm/Realm/RLMObjectStore.mm new file mode 100644 index 0000000..4ead8a2 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMObjectStore.mm @@ -0,0 +1,543 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMObjectStore.h" + +#import "RLMAccessor.h" +#import "RLMArray_Private.hpp" +#import "RLMListBase.h" +#import "RLMObservation.hpp" +#import "RLMObject_Private.hpp" +#import "RLMObjectSchema_Private.hpp" +#import "RLMOptionalBase.h" +#import "RLMProperty_Private.h" +#import "RLMQueryUtil.hpp" +#import "RLMRealm_Private.hpp" +#import "RLMSchema_Private.h" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +#import "object_store.hpp" +#import "results.hpp" +#import "shared_realm.hpp" + +#import + +using namespace realm; + +void RLMRealmCreateAccessors(RLMSchema *schema) { + for (RLMObjectSchema *objectSchema in schema.objectSchema) { + if (objectSchema.accessorClass != objectSchema.objectClass) { + continue; + } + + static unsigned long long count = 0; + NSString *prefix = [NSString stringWithFormat:@"RLMAccessor_%llu_", count++]; + objectSchema.accessorClass = RLMAccessorClassForObjectClass(objectSchema.objectClass, objectSchema, prefix); + } +} + +static inline void RLMVerifyRealmRead(__unsafe_unretained RLMRealm *const realm) { + if (!realm) { + @throw RLMException(@"Realm must not be nil"); + } + [realm verifyThread]; +} + +static inline void RLMVerifyInWriteTransaction(__unsafe_unretained RLMRealm *const realm) { + RLMVerifyRealmRead(realm); + // if realm is not writable throw + if (!realm.inWriteTransaction) { + @throw RLMException(@"Can only add, remove, or create objects in a Realm in a write transaction - call beginWriteTransaction on an RLMRealm instance first."); + } +} + +void RLMInitializeSwiftAccessorGenerics(__unsafe_unretained RLMObjectBase *const object) { + if (!object || !object->_row || !object->_objectSchema->_isSwiftClass) { + return; + } + if (![object isKindOfClass:object->_objectSchema.objectClass]) { + // It can be a different class if it's a dynamic object, and those don't + // require any init here (and would crash since they don't have the ivars) + return; + } + + for (RLMProperty *prop in object->_objectSchema.swiftGenericProperties) { + if (prop->_type == RLMPropertyTypeArray) { + RLMArray *array = [[RLMArrayLinkView alloc] initWithParent:object property:prop]; + [object_getIvar(object, prop.swiftIvar) set_rlmArray:array]; + } + else if (prop.type == RLMPropertyTypeLinkingObjects) { + id linkingObjects = object_getIvar(object, prop.swiftIvar); + [linkingObjects setObject:(id)[[RLMWeakObjectHandle alloc] initWithObject:object]]; + [linkingObjects setProperty:prop]; + } + else { + RLMOptionalBase *optional = object_getIvar(object, prop.swiftIvar); + optional.property = prop; + optional.object = object; + } + } +} + +static void validateValueForProperty(__unsafe_unretained id const obj, + __unsafe_unretained RLMProperty *const prop) { + switch (prop.type) { + case RLMPropertyTypeString: + case RLMPropertyTypeBool: + case RLMPropertyTypeDate: + case RLMPropertyTypeInt: + case RLMPropertyTypeFloat: + case RLMPropertyTypeDouble: + case RLMPropertyTypeData: + if (!RLMIsObjectValidForProperty(obj, prop)) { + @throw RLMException(@"Invalid value '%@' for property '%@'", obj, prop.name); + } + break; + case RLMPropertyTypeObject: + break; + case RLMPropertyTypeArray: { + if (obj != nil && obj != NSNull.null) { + if (![obj conformsToProtocol:@protocol(NSFastEnumeration)]) { + @throw RLMException(@"Array property value (%@) is not enumerable.", obj); + } + } + break; + } + case RLMPropertyTypeAny: + case RLMPropertyTypeLinkingObjects: + @throw RLMException(@"Invalid value '%@' for property '%@'", obj, prop.name); + } +} + +static NSUInteger createRowForObject(RLMClassInfo const& info) { + try { + return info.table()->add_empty_row(); + } + catch (std::exception const& e) { + @throw RLMException(e); + } +} + +/* If a row exists with the specified primary key value, return its index. Otherwise, return `realm::not_found`. + * + * Precondition: `info` must refer to a class which has a primary key property + * Precondition: `primaryValue` is a validated property value that has been coerced to `nil` + */ +static NSUInteger getRowForObjectWithPrimaryKey(RLMClassInfo const& info, id primaryValue) { + REALM_ASSERT_DEBUG(info.propertyForPrimaryKey()); + + RLMProperty *const primaryProperty = info.propertyForPrimaryKey(); + const NSUInteger primaryPropertyColumn = info.tableColumn(primaryProperty); + + switch (primaryProperty.type) { + case RLMPropertyTypeString: + return info.table()->find_first_string(primaryPropertyColumn, RLMStringDataWithNSString(primaryValue)); + + case RLMPropertyTypeInt: + if (primaryValue) { + return info.table()->find_first_int(primaryPropertyColumn, [primaryValue longLongValue]); + } else { + return info.table()->find_first_null(primaryPropertyColumn); + } + + default: + REALM_UNREACHABLE(); + } +} + +/* Create a row with the specified primary key value and return its index. + * + * Precondition: `info` must refer to a class which has a valid primary key property + * Precondition: a write transaction is in progress + * Precondition: no row already exists with the specified `primaryValue` for this model + */ +static NSUInteger createRowForObjectWithPrimaryKey(RLMClassInfo const& info, id primaryValue) { + REALM_ASSERT_DEBUG(info.propertyForPrimaryKey()); + REALM_ASSERT_DEBUG(info.realm.inWriteTransaction); + REALM_ASSERT_DEBUG(getRowForObjectWithPrimaryKey(info, primaryValue) == realm::not_found); + + RLMProperty *const primaryProperty = info.propertyForPrimaryKey(); + const NSUInteger primaryColumnIndex = info.tableColumn(primaryProperty); + + // create row + const NSUInteger rowIndex = createRowForObject(info); + Row row = info.table()->get(rowIndex); + + // set value for primary key + validateValueForProperty(primaryValue, primaryProperty); + primaryValue = RLMCoerceToNil(primaryValue); + + try { + switch (primaryProperty.type) { + case RLMPropertyTypeString: + REALM_ASSERT_DEBUG(!primaryValue || [primaryValue isKindOfClass:NSString.class]); + row.set_string_unique(primaryColumnIndex, RLMStringDataWithNSString(primaryValue)); + break; + + case RLMPropertyTypeInt: + if (primaryValue) { + REALM_ASSERT_DEBUG([primaryValue isKindOfClass:NSNumber.class]); + row.set_int_unique(primaryColumnIndex, [primaryValue longLongValue]); + } else { + row.set_null(primaryColumnIndex); // FIXME: Use `set_null_unique` once Core supports it + } + break; + + default: + REALM_UNREACHABLE(); + } + } + catch (std::exception const& e) { + @throw RLMException(e); + } + return rowIndex; +} + +/* If a row exists with the specified primary key value, returns its index. Otherwise, creates a new row with the + * specified primary key value and returns its index. The out parameter `foundExisting` will be set to indicate + * whether or not a new row was created. + * + * Precondition: `info` must refer to a class which has a valid primary key property + * Precondition: a write transaction is in progress + */ +static NSUInteger createOrGetRowForObjectWithPrimaryKey(RLMClassInfo const& info, id primaryValue, + bool* foundExisting = nullptr) { + REALM_ASSERT_DEBUG(info.propertyForPrimaryKey()); + REALM_ASSERT_DEBUG(info.realm.inWriteTransaction); + + const NSUInteger existingRow = getRowForObjectWithPrimaryKey(info, primaryValue); + if (existingRow == realm::not_found) { + *foundExisting = false; + return createRowForObjectWithPrimaryKey(info, primaryValue); + } else { + *foundExisting = true; + return existingRow; + } +} + +/* If the class has a primary key, calls `valueForProperty` with that key and creates or gets the row with + * this primary key value. Otherwise if the class has no primary key, creates a new row. The out parameter + * `foundExisting` will be set to indicate whether or not a new row was created. + * + * Precondition: a write transaction is in progress + */ +template +static NSUInteger createOrGetRowForObject(RLMClassInfo const& info, F valueForProperty, + bool createOrUpdate, bool* foundExisting) { + // try to get existing row if this class has a primary key + if (RLMProperty *primaryProperty = info.propertyForPrimaryKey()) { + // get primary value + const id primaryValue = valueForProperty(primaryProperty); + + // search for existing object based on primary key type, creating a new row if one does not exist + NSUInteger rowIndex = createOrGetRowForObjectWithPrimaryKey(info, RLMCoerceToNil(primaryValue), foundExisting); + + // ensure that `createOrUpdate` is set if we found an existing row + if (*foundExisting && !createOrUpdate) { + @throw RLMException(@"Can't create object with existing primary key value '%@'.", primaryValue); + } + return rowIndex; + } + // if no existing, create row + else { + *foundExisting = false; + return createRowForObject(info); + } +} + +void RLMAddObjectToRealm(__unsafe_unretained RLMObjectBase *const object, + __unsafe_unretained RLMRealm *const realm, + bool createOrUpdate) { + RLMVerifyInWriteTransaction(realm); + + // verify that object is unmanaged + if (object.invalidated) { + @throw RLMException(@"Adding a deleted or invalidated object to a Realm is not permitted"); + } + if (object->_realm) { + if (object->_realm == realm) { + // no-op + return; + } + // for differing realms users must explicitly create the object in the second realm + @throw RLMException(@"Object is already managed by another Realm"); + } + if (object->_observationInfo && object->_observationInfo->hasObservers()) { + @throw RLMException(@"Cannot add an object with observers to a Realm"); + } + + // set the realm and schema + NSString *objectClassName = object->_objectSchema.className; + auto& info = realm->_info[objectClassName]; + object->_info = &info; + object->_objectSchema = info.rlmObjectSchema; + object->_realm = realm; + + // get or create row + bool foundExisting; + auto primaryGetter = [=](__unsafe_unretained RLMProperty *const p) { return [object valueForKey:p.name]; }; + object->_row = (*info.table())[createOrGetRowForObject(info, primaryGetter, createOrUpdate, &foundExisting)]; + + RLMCreationOptions creationOptions = RLMCreationOptionsPromoteUnmanaged; + if (createOrUpdate) { + creationOptions |= RLMCreationOptionsCreateOrUpdate; + } + + // populate all properties + for (RLMProperty *prop in info.rlmObjectSchema.properties) { + // get object from ivar using key value coding + id value = nil; + if (prop.swiftIvar) { + if (prop.type == RLMPropertyTypeArray) { + value = static_cast(object_getIvar(object, prop.swiftIvar))._rlmArray; + } + else { // optional + value = static_cast(object_getIvar(object, prop.swiftIvar)).underlyingValue; + } + } + else if ([object respondsToSelector:prop.getterSel]) { + value = [object valueForKey:prop.getterName]; + } + + if (!value && !prop.optional) { + @throw RLMException(@"No value or default value specified for property '%@' in '%@'", + prop.name, info.rlmObjectSchema.className); + } + + // set the ivars for object and array properties to nil as otherwise the + // accessors retain objects that are no longer accessible via the properties + // this is mainly an issue when the object graph being added has cycles, + // as it's not obvious that the user has to set the *ivars* to nil to + // avoid leaking memory + if (prop.type == RLMPropertyTypeObject || prop.type == RLMPropertyTypeArray) { + if (!prop.swiftIvar) { + ((void(*)(id, SEL, id))objc_msgSend)(object, prop.setterSel, nil); + } + } + + // skip primary key when updating since it doesn't change + if (prop.isPrimary) + continue; + + // set in table with out validation + RLMDynamicSet(object, prop, RLMCoerceToNil(value), creationOptions); + } + + // set to proper accessor class + object_setClass(object, info.rlmObjectSchema.accessorClass); + + RLMInitializeSwiftAccessorGenerics(object); +} + +RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className, id value, bool createOrUpdate = false) { + if (createOrUpdate && RLMIsObjectSubclass([value class])) { + RLMObjectBase *obj = value; + if ([obj->_objectSchema.className isEqualToString:className] && obj->_realm == realm) { + // This is a no-op if value is an RLMObject of the same type already backed by the target realm. + return value; + } + } + + // verify writable + RLMVerifyInWriteTransaction(realm); + + // create the object + auto& info = realm->_info[className]; + RLMObjectBase *object = RLMCreateManagedAccessor(info.rlmObjectSchema.accessorClass, realm, &info); + + RLMCreationOptions creationOptions = createOrUpdate ? RLMCreationOptionsCreateOrUpdate : RLMCreationOptionsNone; + + // create row, and populate + if (NSArray *array = RLMDynamicCast(value)) { + // get or create our accessor + bool foundExisting; + NSArray *props = info.rlmObjectSchema.properties; + auto primaryGetter = [=](__unsafe_unretained RLMProperty *const p) { + return array[[props indexOfObject:p]]; + }; + object->_row = (*info.table())[createOrGetRowForObject(info, primaryGetter, createOrUpdate, &foundExisting)]; + + // populate + for (NSUInteger i = 0; i < array.count; i++) { + RLMProperty *prop = props[i]; + + // skip primary key when updating since it doesn't change + if (prop.isPrimary) + continue; + + id val = array[i]; + validateValueForProperty(val, prop); + RLMDynamicSet(object, prop, RLMCoerceToNil(val), creationOptions); + } + } + else { + __block bool foundExisting = false; + __block NSDictionary *defaultValues = nil; + auto getValue = ^(RLMProperty *prop) { + id propValue = RLMValidatedValueForProperty(value, prop.name, info.rlmObjectSchema.className); + if (!propValue && !foundExisting) { + if (!defaultValues) { + defaultValues = RLMDefaultValuesForObjectSchema(info.rlmObjectSchema); + } + propValue = defaultValues[prop.name]; + if (!propValue && (prop.type == RLMPropertyTypeObject || prop.type == RLMPropertyTypeArray)) { + propValue = NSNull.null; + } + } + return propValue; + }; + // get or create our accessor + object->_row = (*info.table())[createOrGetRowForObject(info, getValue, createOrUpdate, &foundExisting)]; + + // populate + for (RLMProperty *prop in info.rlmObjectSchema.properties) { + // skip primary key when updating since it doesn't change + if (prop.isPrimary) + continue; + + if (id propValue = getValue(prop)) { + validateValueForProperty(propValue, prop); + RLMDynamicSet(object, prop, RLMCoerceToNil(propValue), creationOptions); + } + else if (!foundExisting && !prop.optional) { + @throw RLMException(@"Property '%@' of object of type '%@' cannot be nil.", prop.name, info.rlmObjectSchema.className); + } + } + } + + RLMInitializeSwiftAccessorGenerics(object); + return object; +} + +void RLMDeleteObjectFromRealm(__unsafe_unretained RLMObjectBase *const object, + __unsafe_unretained RLMRealm *const realm) { + if (realm != object->_realm) { + @throw RLMException(@"Can only delete an object from the Realm it belongs to."); + } + + RLMVerifyInWriteTransaction(object->_realm); + + // move last row to row we are deleting + if (object->_row.is_attached()) { + RLMTrackDeletions(realm, ^{ + object->_row.get_table()->move_last_over(object->_row.get_index()); + }); + } + + // set realm to nil + object->_realm = nil; +} + +void RLMDeleteAllObjectsFromRealm(RLMRealm *realm) { + RLMVerifyInWriteTransaction(realm); + + // clear table for each object schema + for (auto& info : realm->_info) { + RLMClearTable(info.second); + } +} + +RLMResults *RLMGetObjects(RLMRealm *realm, NSString *objectClassName, NSPredicate *predicate) { + RLMVerifyRealmRead(realm); + + // create view from table and predicate + RLMClassInfo& info = realm->_info[objectClassName]; + if (!info.table()) { + // read-only realms may be missing tables since we can't add any + // missing ones on init + return [RLMResults resultsWithObjectInfo:info results:{}]; + } + + if (predicate) { + realm::Query query = RLMPredicateToQuery(predicate, info.rlmObjectSchema, realm.schema, realm.group); + return [RLMResults resultsWithObjectInfo:info + results:realm::Results(realm->_realm, std::move(query))]; + } + + return [RLMResults resultsWithObjectInfo:info + results:realm::Results(realm->_realm, *info.table())]; +} + +id RLMGetObject(RLMRealm *realm, NSString *objectClassName, id key) { + RLMVerifyRealmRead(realm); + + RLMClassInfo& info = realm->_info[objectClassName]; + auto primaryProperty = info.objectSchema->primary_key_property(); + if (!primaryProperty) { + @throw RLMException(@"%@ does not have a primary key", objectClassName); + } + + auto table = info.table(); + if (!table) { + // read-only realms may be missing tables since we can't add any + // missing ones on init + return nil; + } + + key = RLMCoerceToNil(key); + if (!key && !primaryProperty->is_nullable) { + @throw RLMException(@"Invalid null value for non-nullable primary key."); + } + + size_t row = realm::not_found; + switch (primaryProperty->type) { + case PropertyType::String: { + NSString *string = RLMDynamicCast(key); + if (!key || string) { + row = table->find_first_string(primaryProperty->table_column, RLMStringDataWithNSString(string)); + } else { + @throw RLMException(@"Invalid value '%@' of type '%@' for string primary key.", key, [key class]); + } + break; + } + case PropertyType::Int: + if (NSNumber *number = RLMDynamicCast(key)) { + row = table->find_first_int(primaryProperty->table_column, number.longLongValue); + } else if (!key) { + row = table->find_first_null(primaryProperty->table_column); + } else { + @throw RLMException(@"Invalid value '%@' of type '%@' for int primary key.", key, [key class]); + } + break; + default: + REALM_UNREACHABLE(); + } + + if (row == realm::not_found) { + return nil; + } + + return RLMCreateObjectAccessor(realm, info, row); +} + +RLMObjectBase *RLMCreateObjectAccessor(__unsafe_unretained RLMRealm *const realm, + RLMClassInfo& info, + NSUInteger index) { + return RLMCreateObjectAccessor(realm, info, (*info.table())[index]); +} + +// Create accessor and register with realm +RLMObjectBase *RLMCreateObjectAccessor(__unsafe_unretained RLMRealm *const realm, + RLMClassInfo& info, + realm::RowExpr row) { + RLMObjectBase *accessor = RLMCreateManagedAccessor(info.rlmObjectSchema.accessorClass, realm, &info); + accessor->_row = row; + RLMInitializeSwiftAccessorGenerics(accessor); + return accessor; +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMObservation.mm b/SiriKitExample/Pods/Realm/Realm/RLMObservation.mm new file mode 100644 index 0000000..e6538b6 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMObservation.mm @@ -0,0 +1,500 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMObservation.hpp" + +#import "RLMAccessor.h" +#import "RLMArray_Private.hpp" +#import "RLMListBase.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObject_Private.hpp" +#import "RLMProperty_Private.h" +#import "RLMRealm_Private.hpp" + +#import + +using namespace realm; + +namespace { + template + struct IteratorPair { + Iterator first; + Iterator second; + }; + template + Iterator begin(IteratorPair const& p) { + return p.first; + } + template + Iterator end(IteratorPair const& p) { + return p.second; + } + + template + auto reverse(Container const& c) { + return IteratorPair{c.rbegin(), c.rend()}; + } +} + +RLMObservationInfo::RLMObservationInfo(RLMClassInfo &objectSchema, std::size_t row, id object) +: object(object) +, objectSchema(&objectSchema) +{ + setRow(*objectSchema.table(), row); +} + +RLMObservationInfo::RLMObservationInfo(id object) +: object(object) +{ +} + +RLMObservationInfo::~RLMObservationInfo() { + if (prev) { + // Not the head of the linked list, so just detach from the list + REALM_ASSERT_DEBUG(prev->next == this); + prev->next = next; + if (next) { + REALM_ASSERT_DEBUG(next->prev == this); + next->prev = prev; + } + } + else if (objectSchema) { + // The head of the list, so remove self from the object schema's array + // of observation info, either replacing self with the next info or + // removing entirely if there is no next + auto end = objectSchema->observedObjects.end(); + auto it = find(objectSchema->observedObjects.begin(), end, this); + if (it != end) { + if (next) { + *it = next; + next->prev = nullptr; + } + else { + iter_swap(it, std::prev(end)); + objectSchema->observedObjects.pop_back(); + } + } + } + // Otherwise the observed object was unmanaged, so nothing to do + +#ifdef DEBUG + // ensure that incorrect cleanup fails noisily + object = (__bridge id)(void *)-1; + prev = (RLMObservationInfo *)-1; + next = (RLMObservationInfo *)-1; +#endif +} + +NSString *RLMObservationInfo::columnName(size_t col) const noexcept { + return objectSchema->propertyForTableColumn(col).name; +} + +void RLMObservationInfo::willChange(NSString *key, NSKeyValueChange kind, NSIndexSet *indexes) const { + if (indexes) { + forEach([=](__unsafe_unretained auto o) { + [o willChange:kind valuesAtIndexes:indexes forKey:key]; + }); + } + else { + forEach([=](__unsafe_unretained auto o) { + [o willChangeValueForKey:key]; + }); + } +} + +void RLMObservationInfo::didChange(NSString *key, NSKeyValueChange kind, NSIndexSet *indexes) const { + if (indexes) { + forEach([=](__unsafe_unretained auto o) { + [o didChange:kind valuesAtIndexes:indexes forKey:key]; + }); + } + else { + forEach([=](__unsafe_unretained auto o) { + [o didChangeValueForKey:key]; + }); + } +} + +void RLMObservationInfo::prepareForInvalidation() { + REALM_ASSERT_DEBUG(objectSchema); + REALM_ASSERT_DEBUG(!prev); + for (auto info = this; info; info = info->next) + info->invalidated = true; +} + +void RLMObservationInfo::setRow(realm::Table &table, size_t newRow) { + REALM_ASSERT_DEBUG(!row); + REALM_ASSERT_DEBUG(objectSchema); + row = table[newRow]; + for (auto info : objectSchema->observedObjects) { + if (info->row && info->row.get_index() == row.get_index()) { + prev = info; + next = info->next; + if (next) + next->prev = this; + info->next = this; + return; + } + } + objectSchema->observedObjects.push_back(this); +} + +void RLMObservationInfo::recordObserver(realm::Row& objectRow, RLMClassInfo *objectInfo, + __unsafe_unretained RLMObjectSchema *const objectSchema, + __unsafe_unretained NSString *const keyPath) { + ++observerCount; + if (row) { + return; + } + + // add ourselves to the list of observed objects if this is the first time + // an observer is being added to a managed object + if (objectRow) { + this->objectSchema = objectInfo; + setRow(*objectRow.get_table(), objectRow.get_index()); + return; + } + + // Arrays need a reference to their containing object to avoid having to + // go through the awful proxy object from mutableArrayValueForKey. + // For managed objects we do this when the object is added or created + // (and have to to support notifications from modifying an object which + // was never observed), but for Swift classes (both RealmSwift and + // RLMObject) we can't do it then because we don't know what the parent + // object is. + + NSUInteger sep = [keyPath rangeOfString:@"."].location; + NSString *key = sep == NSNotFound ? keyPath : [keyPath substringToIndex:sep]; + RLMProperty *prop = objectSchema[key]; + if (prop && prop.type == RLMPropertyTypeArray) { + id value = valueForKey(key); + RLMArray *array = [value isKindOfClass:[RLMListBase class]] ? [value _rlmArray] : value; + array->_key = key; + array->_parentObject = object; + } + else if (auto swiftIvar = prop.swiftIvar) { + if (auto optional = RLMDynamicCast(object_getIvar(object, swiftIvar))) { + optional.property = prop; + optional.object = object; + } + } +} + +void RLMObservationInfo::removeObserver() { + --observerCount; +} + +id RLMObservationInfo::valueForKey(NSString *key) { + if (invalidated) { + if ([key isEqualToString:RLMInvalidatedKey]) { + return @YES; + } + return cachedObjects[key]; + } + + if (key != lastKey) { + lastKey = key; + lastProp = objectSchema ? objectSchema->rlmObjectSchema[key] : nil; + } + + static auto superValueForKey = reinterpret_cast([NSObject methodForSelector:@selector(valueForKey:)]); + if (!lastProp) { + // Not a managed property, so use NSObject's implementation of valueForKey: + return RLMCoerceToNil(superValueForKey(object, @selector(valueForKey:), key)); + } + + auto getSuper = [&] { + return row ? RLMDynamicGet(object, lastProp) : RLMCoerceToNil(superValueForKey(object, @selector(valueForKey:), key)); + }; + + // We need to return the same object each time for observing over keypaths + // to work, so we store a cache of them here. We can't just cache them on + // the object as that leads to retain cycles. + if (lastProp.type == RLMPropertyTypeArray) { + RLMArray *value = cachedObjects[key]; + if (!value) { + value = getSuper(); + if (!cachedObjects) { + cachedObjects = [NSMutableDictionary new]; + } + cachedObjects[key] = value; + } + return value; + } + + if (lastProp.type == RLMPropertyTypeObject) { + size_t col = row.get_column_index(lastProp.name.UTF8String); + if (row.is_null_link(col)) { + [cachedObjects removeObjectForKey:key]; + return nil; + } + + RLMObjectBase *value = cachedObjects[key]; + if (value && value->_row.get_index() == row.get_link(col)) { + return value; + } + value = getSuper(); + if (!cachedObjects) { + cachedObjects = [NSMutableDictionary new]; + } + cachedObjects[key] = value; + return value; + } + + return getSuper(); +} + +RLMObservationInfo *RLMGetObservationInfo(RLMObservationInfo *info, size_t row, + RLMClassInfo& objectSchema) { + if (info) { + return info; + } + + for (RLMObservationInfo *info : objectSchema.observedObjects) { + if (info->isForRow(row)) { + return info; + } + } + + return nullptr; +} + +void RLMClearTable(RLMClassInfo &objectSchema) { + for (auto info : objectSchema.observedObjects) { + info->willChange(RLMInvalidatedKey); + } + + RLMTrackDeletions(objectSchema.realm, ^{ + objectSchema.table()->clear(); + + for (auto info : objectSchema.observedObjects) { + info->prepareForInvalidation(); + } + }); + + for (auto info : reverse(objectSchema.observedObjects)) { + info->didChange(RLMInvalidatedKey); + } + + objectSchema.observedObjects.clear(); +} + +void RLMTrackDeletions(__unsafe_unretained RLMRealm *const realm, dispatch_block_t block) { + std::vector *> observers; + + // Build up an array of observation info arrays which is indexed by table + // index (the object schemata may be in an entirely different order) + for (auto& info : realm->_info) { + if (info.second.observedObjects.empty()) { + continue; + } + size_t ndx = info.second.table()->get_index_in_group(); + if (ndx >= observers.size()) { + observers.resize(std::max(observers.size() * 2, ndx + 1)); + } + observers[ndx] = &info.second.observedObjects; + } + + // No need for change tracking if no objects are observed + if (observers.empty()) { + block(); + return; + } + + struct change { + RLMObservationInfo *info; + __unsafe_unretained NSString *property; + NSMutableIndexSet *indexes; + }; + + std::vector changes; + std::vector invalidated; + + // This callback is called by core with a list of row deletions and + // resulting link nullifications immediately before things are deleted and nullified + realm.group.set_cascade_notification_handler([&](realm::Group::CascadeNotification const& cs) { + for (auto const& link : cs.links) { + size_t table_ndx = link.origin_table->get_index_in_group(); + if (table_ndx >= observers.size() || !observers[table_ndx]) { + // The modified table has no observers + continue; + } + + for (auto observer : *observers[table_ndx]) { + if (!observer->isForRow(link.origin_row_ndx)) { + continue; + } + + NSString *name = observer->columnName(link.origin_col_ndx); + if (observer->getRow().get_table()->get_column_type(link.origin_col_ndx) != type_LinkList) { + changes.push_back({observer, name}); + continue; + } + + auto c = find_if(begin(changes), end(changes), [&](auto const& c) { + return c.info == observer && c.property == name; + }); + if (c == end(changes)) { + changes.push_back({observer, name, [NSMutableIndexSet new]}); + c = prev(end(changes)); + } + + // We know what row index is being removed from the LinkView, + // but what we actually want is the indexes in the LinkView that + // are going away + auto linkview = observer->getRow().get_linklist(link.origin_col_ndx); + size_t start = 0, index; + while ((index = linkview->find(link.old_target_row_ndx, start)) != realm::not_found) { + [c->indexes addIndex:index]; + start = index + 1; + } + } + } + + for (auto const& row : cs.rows) { + if (row.table_ndx >= observers.size() || !observers[row.table_ndx]) { + // The modified table has no observers + continue; + } + + for (auto observer : *observers[row.table_ndx]) { + if (observer->isForRow(row.row_ndx)) { + invalidated.push_back(observer); + break; + } + } + } + + // The relative order of these loops is very important + for (auto info : invalidated) { + info->willChange(RLMInvalidatedKey); + } + for (auto const& change : changes) { + change.info->willChange(change.property, NSKeyValueChangeRemoval, change.indexes); + } + for (auto info : invalidated) { + info->prepareForInvalidation(); + } + }); + + try { + block(); + } + catch (...) { + realm.group.set_cascade_notification_handler(nullptr); + throw; + } + + for (auto const& change : reverse(changes)) { + change.info->didChange(change.property, NSKeyValueChangeRemoval, change.indexes); + } + for (auto info : reverse(invalidated)) { + info->didChange(RLMInvalidatedKey); + } + + realm.group.set_cascade_notification_handler(nullptr); +} + +namespace { +template +void forEach(realm::BindingContext::ObserverState const& state, Func&& func) { + for (size_t i = 0, size = state.changes.size(); i < size; ++i) { + if (state.changes[i].kind != realm::BindingContext::ColumnInfo::Kind::None) { + func(i, state.changes[i], static_cast(state.info)); + } + } +} +} + +std::vector RLMGetObservedRows(RLMSchemaInfo const& schema) { + std::vector observers; + for (auto& table : schema) { + for (auto info : table.second.observedObjects) { + auto const& row = info->getRow(); + if (!row.is_attached()) + continue; + observers.push_back({ + row.get_table()->get_index_in_group(), + row.get_index(), + info}); + } + } + sort(begin(observers), end(observers)); + return observers; +} + +static NSKeyValueChange convert(realm::BindingContext::ColumnInfo::Kind kind) { + switch (kind) { + case realm::BindingContext::ColumnInfo::Kind::None: + case realm::BindingContext::ColumnInfo::Kind::SetAll: + return NSKeyValueChangeSetting; + case realm::BindingContext::ColumnInfo::Kind::Set: + return NSKeyValueChangeReplacement; + case realm::BindingContext::ColumnInfo::Kind::Insert: + return NSKeyValueChangeInsertion; + case realm::BindingContext::ColumnInfo::Kind::Remove: + return NSKeyValueChangeRemoval; + } +} + +static NSIndexSet *convert(realm::IndexSet const& in, NSMutableIndexSet *out) { + if (in.empty()) { + return nil; + } + + [out removeAllIndexes]; + for (auto range : in) { + [out addIndexesInRange:{range.first, range.second - range.first}]; + } + return out; +} + +void RLMWillChange(std::vector const& observed, + std::vector const& invalidated) { + for (auto info : invalidated) { + static_cast(info)->willChange(RLMInvalidatedKey); + } + if (!observed.empty()) { + NSMutableIndexSet *indexes = [NSMutableIndexSet new]; + for (auto const& o : observed) { + forEach(o, [&](size_t, auto const& change, RLMObservationInfo *info) { + info->willChange(info->columnName(change.initial_column_index), + convert(change.kind), convert(change.indices, indexes)); + }); + } + } + for (auto info : invalidated) { + static_cast(info)->prepareForInvalidation(); + } +} + +void RLMDidChange(std::vector const& observed, + std::vector const& invalidated) { + if (!observed.empty()) { + // Loop in reverse order to avoid O(N^2) behavior in Foundation + NSMutableIndexSet *indexes = [NSMutableIndexSet new]; + for (auto const& o : reverse(observed)) { + forEach(o, [&](size_t i, auto const& change, RLMObservationInfo *info) { + info->didChange(info->columnName(i), convert(change.kind), convert(change.indices, indexes)); + }); + } + } + for (auto const& info : reverse(invalidated)) { + static_cast(info)->didChange(RLMInvalidatedKey); + } +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMOptionalBase.mm b/SiriKitExample/Pods/Realm/Realm/RLMOptionalBase.mm new file mode 100644 index 0000000..8aad1c8 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMOptionalBase.mm @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMAccessor.h" +#import "RLMOptionalBase.h" +#import "RLMObject_Private.h" +#import "RLMObjectStore.h" +#import "RLMProperty_Private.h" +#import "RLMUtil.hpp" + +#import + +@interface RLMOptionalBase () +@property (nonatomic) id unmanagedValue; +@end + +@implementation RLMOptionalBase + +- (instancetype)init { + return self; +} + +- (id)underlyingValue { + if ((_object && _object->_realm) || _object.isInvalidated) { + return RLMDynamicGet(_object, _property); + } + else { + return _unmanagedValue; + } +} + +- (void)setUnderlyingValue:(id)underlyingValue { + if ((_object && _object->_realm) || _object.isInvalidated) { + if (_property.isPrimary) { + @throw RLMException(@"Primary key can't be changed after an object is inserted."); + } + RLMDynamicSet(_object, _property, underlyingValue, RLMCreationOptionsNone); + } + else { + NSString *propertyName = _property.name; + [_object willChangeValueForKey:propertyName]; + _unmanagedValue = underlyingValue; + [_object didChangeValueForKey:propertyName]; + } +} + +- (BOOL)isKindOfClass:(Class)aClass { + return [self.underlyingValue isKindOfClass:aClass] || RLMIsKindOfClass(object_getClass(self), aClass); +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { + return [self.underlyingValue methodSignatureForSelector:sel]; +} + +- (void)forwardInvocation:(NSInvocation *)invocation { + [invocation invokeWithTarget:self.underlyingValue]; +} + +- (id)forwardingTargetForSelector:(__unused SEL)sel { + return self.underlyingValue; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + if (id val = self.underlyingValue) { + return [val respondsToSelector:aSelector]; + } + return NO; +} + +- (void)doesNotRecognizeSelector:(SEL)aSelector { + [self.underlyingValue doesNotRecognizeSelector:aSelector]; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMPredicateUtil.mm b/SiriKitExample/Pods/Realm/Realm/RLMPredicateUtil.mm new file mode 100644 index 0000000..d2f722b --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMPredicateUtil.mm @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "RLMPredicateUtil.hpp" + +// NSConditionalExpressionType is new in OS X 10.11 and iOS 9.0 +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +#define CONDITIONAL_EXPRESSION_DECLARED (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#define CONDITIONAL_EXPRESSION_DECLARED (__IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) +#else +#define CONDITIONAL_EXPRESSION_DECLARED 0 +#endif + +#if !CONDITIONAL_EXPRESSION_DECLARED + +#define NSConditionalExpressionType 20 + +@interface NSExpression (NewIn1011And90) ++ (NSExpression *)expressionForConditional:(NSPredicate *)predicate trueExpression:(NSExpression *)trueExpression falseExpression:(NSExpression *)falseExpression; +- (NSExpression *)trueExpression; +- (NSExpression *)falseExpression; +@end + +#endif + +namespace { + +struct PredicateExpressionTransformer { + PredicateExpressionTransformer(ExpressionVisitor visitor) : m_visitor(visitor) { } + + NSExpression *visit(NSExpression *expression) const; + NSPredicate *visit(NSPredicate *predicate) const; + + ExpressionVisitor m_visitor; +}; + +NSExpression *PredicateExpressionTransformer::visit(NSExpression *expression) const { + expression = m_visitor(expression); + + switch (expression.expressionType) { + case NSFunctionExpressionType: { + NSMutableArray *arguments = [NSMutableArray array]; + for (NSExpression *argument in expression.arguments) { + [arguments addObject:visit(argument)]; + } + if (expression.operand) { + return [NSExpression expressionForFunction:visit(expression.operand) selectorName:expression.function arguments:arguments]; + } else { + return [NSExpression expressionForFunction:expression.function arguments:arguments]; + } + } + + case NSUnionSetExpressionType: + return [NSExpression expressionForUnionSet:visit(expression.leftExpression) with:visit(expression.rightExpression)]; + case NSIntersectSetExpressionType: + return [NSExpression expressionForIntersectSet:visit(expression.leftExpression) with:visit(expression.rightExpression)]; + case NSMinusSetExpressionType: + return [NSExpression expressionForMinusSet:visit(expression.leftExpression) with:visit(expression.rightExpression)]; + + case NSSubqueryExpressionType: + return [NSExpression expressionForSubquery:visit(expression.operand) usingIteratorVariable:expression.variable predicate:visit(expression.predicate)]; + + case NSAggregateExpressionType: { + NSMutableArray *subexpressions = [NSMutableArray array]; + for (NSExpression *subexpression in expression.collection) { + [subexpressions addObject:visit(subexpression)]; + } + return [NSExpression expressionForAggregate:subexpressions]; + } + + case NSConditionalExpressionType: + return [NSExpression expressionForConditional:visit(expression.predicate) trueExpression:visit(expression.trueExpression) falseExpression:visit(expression.falseExpression)]; + + default: + // The remaining expression types do not contain nested expressions or predicates. + return expression; + } +} + +NSPredicate *PredicateExpressionTransformer::visit(NSPredicate *predicate) const { + if ([predicate isKindOfClass:[NSCompoundPredicate class]]) { + NSCompoundPredicate *compoundPredicate = (NSCompoundPredicate *)predicate; + NSMutableArray *subpredicates = [NSMutableArray array]; + for (NSPredicate *subpredicate in compoundPredicate.subpredicates) { + [subpredicates addObject:visit(subpredicate)]; + } + return [[NSCompoundPredicate alloc] initWithType:compoundPredicate.compoundPredicateType subpredicates:subpredicates]; + } + if ([predicate isKindOfClass:[NSComparisonPredicate class]]) { + NSComparisonPredicate *comparisonPredicate = (NSComparisonPredicate *)predicate; + NSExpression *leftExpression = visit(comparisonPredicate.leftExpression); + NSExpression *rightExpression = visit(comparisonPredicate.rightExpression); + return [NSComparisonPredicate predicateWithLeftExpression:leftExpression rightExpression:rightExpression modifier:comparisonPredicate.comparisonPredicateModifier type:comparisonPredicate.predicateOperatorType options:comparisonPredicate.options]; + } + return predicate; +} + +} // anonymous namespace + +NSPredicate *transformPredicate(NSPredicate *predicate, ExpressionVisitor visitor) { + PredicateExpressionTransformer transformer(visitor); + return transformer.visit(predicate); +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMProperty.mm b/SiriKitExample/Pods/Realm/Realm/RLMProperty.mm new file mode 100644 index 0000000..2ce75f4 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMProperty.mm @@ -0,0 +1,569 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMProperty_Private.hpp" + +#import "RLMArray.h" +#import "RLMListBase.h" +#import "RLMObject.h" +#import "RLMObject_Private.h" +#import "RLMOptionalBase.h" +#import "RLMSchema_Private.h" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +BOOL RLMPropertyTypeIsNullable(RLMPropertyType propertyType) { + return propertyType != RLMPropertyTypeArray && propertyType != RLMPropertyTypeLinkingObjects; +} + +BOOL RLMPropertyTypeIsComputed(RLMPropertyType propertyType) { + return propertyType == RLMPropertyTypeLinkingObjects; +} + +static bool rawTypeIsComputedProperty(NSString *rawType) { + if ([rawType isEqualToString:@"@\"RLMLinkingObjects\""] || [rawType hasPrefix:@"@\"RLMLinkingObjects<"]) { + return true; + } + + return false; +} + +@implementation RLMProperty + ++ (instancetype)propertyForObjectStoreProperty:(const realm::Property &)prop { + return [[RLMProperty alloc] initWithName:@(prop.name.c_str()) + type:(RLMPropertyType)prop.type + objectClassName:prop.object_type.length() ? @(prop.object_type.c_str()) : nil + linkOriginPropertyName:prop.link_origin_property_name.length() ? @(prop.link_origin_property_name.c_str()) : nil + indexed:prop.is_indexed + optional:prop.is_nullable]; +} + +- (instancetype)initWithName:(NSString *)name + type:(RLMPropertyType)type + objectClassName:(NSString *)objectClassName + linkOriginPropertyName:(NSString *)linkOriginPropertyName + indexed:(BOOL)indexed + optional:(BOOL)optional { + self = [super init]; + if (self) { + _name = name; + _type = type; + _objectClassName = objectClassName; + _linkOriginPropertyName = linkOriginPropertyName; + _indexed = indexed; + _optional = optional; + [self setObjcCodeFromType]; + [self updateAccessors]; + } + + return self; +} + +- (void)setName:(NSString *)name { + _name = name; + [self updateAccessors]; +} + +- (void)updateAccessors { + // populate getter/setter names if generic + if (!_getterName) { + _getterName = _name; + } + if (!_setterName) { + // Objective-C setters only capitalize the first letter of the property name if it falls between 'a' and 'z' + int asciiCode = [_name characterAtIndex:0]; + BOOL shouldUppercase = asciiCode >= 'a' && asciiCode <= 'z'; + NSString *firstChar = [_name substringToIndex:1]; + firstChar = shouldUppercase ? firstChar.uppercaseString : firstChar; + _setterName = [NSString stringWithFormat:@"set%@%@:", firstChar, [_name substringFromIndex:1]]; + } + + _getterSel = NSSelectorFromString(_getterName); + _setterSel = NSSelectorFromString(_setterName); +} + +-(void)setObjcCodeFromType { + if (_optional) { + _objcType = '@'; + return; + } + switch (_type) { + case RLMPropertyTypeInt: + _objcType = 'q'; + break; + case RLMPropertyTypeBool: + _objcType = 'c'; + break; + case RLMPropertyTypeDouble: + _objcType = 'd'; + break; + case RLMPropertyTypeFloat: + _objcType = 'f'; + break; + case RLMPropertyTypeAny: + case RLMPropertyTypeArray: + case RLMPropertyTypeData: + case RLMPropertyTypeDate: + case RLMPropertyTypeObject: + case RLMPropertyTypeString: + case RLMPropertyTypeLinkingObjects: + _objcType = '@'; + break; + } +} + +// determine RLMPropertyType from objc code - returns true if valid type was found/set +- (BOOL)setTypeFromRawType { + const char *code = _objcRawType.UTF8String; + _objcType = *code; // first char of type attr + + // map to RLMPropertyType + switch (self.objcType) { + case 's': // short + case 'i': // int + case 'l': // long + case 'q': // long long + _type = RLMPropertyTypeInt; + return YES; + case 'f': + _type = RLMPropertyTypeFloat; + return YES; + case 'd': + _type = RLMPropertyTypeDouble; + return YES; + case 'c': // BOOL is stored as char - since rlm has no char type this is ok + case 'B': + _type = RLMPropertyTypeBool; + return YES; + case '@': { + _optional = true; + static const char arrayPrefix[] = "@\"RLMArray<"; + static const int arrayPrefixLen = sizeof(arrayPrefix) - 1; + + static const char numberPrefix[] = "@\"NSNumber<"; + static const int numberPrefixLen = sizeof(numberPrefix) - 1; + + static const char linkingObjectsPrefix[] = "@\"RLMLinkingObjects"; + static const int linkingObjectsPrefixLen = sizeof(linkingObjectsPrefix) - 1; + + if (strcmp(code, "@\"NSString\"") == 0) { + _type = RLMPropertyTypeString; + } + else if (strcmp(code, "@\"NSDate\"") == 0) { + _type = RLMPropertyTypeDate; + } + else if (strcmp(code, "@\"NSData\"") == 0) { + _type = RLMPropertyTypeData; + } + else if (strncmp(code, arrayPrefix, arrayPrefixLen) == 0) { + _optional = false; + // get object class from type string - @"RLMArray" + _type = RLMPropertyTypeArray; + _objectClassName = [[NSString alloc] initWithBytes:code + arrayPrefixLen + length:strlen(code + arrayPrefixLen) - 2 // drop trailing >" + encoding:NSUTF8StringEncoding]; + + Class cls = [RLMSchema classForString:_objectClassName]; + if (!cls) { + @throw RLMException(@"Property '%@' is of type 'RLMArray<%@>' which is not a supported RLMArray object type. " + @"RLMArrays can only contain instances of RLMObject subclasses. " + @"See https://realm.io/docs/objc/latest/#to-many for more information.", _name, _objectClassName); + } + } + else if (strncmp(code, numberPrefix, numberPrefixLen) == 0) { + // get number type from type string - @"NSNumber" + NSString *numberType = [[NSString alloc] initWithBytes:code + numberPrefixLen + length:strlen(code + numberPrefixLen) - 2 // drop trailing >" + encoding:NSUTF8StringEncoding]; + + if ([numberType isEqualToString:@"RLMInt"]) { + _type = RLMPropertyTypeInt; + } + else if ([numberType isEqualToString:@"RLMFloat"]) { + _type = RLMPropertyTypeFloat; + } + else if ([numberType isEqualToString:@"RLMDouble"]) { + _type = RLMPropertyTypeDouble; + } + else if ([numberType isEqualToString:@"RLMBool"]) { + _type = RLMPropertyTypeBool; + } + else { + @throw RLMException(@"Property '%@' is of type 'NSNumber<%@>' which is not a supported NSNumber object type. " + @"NSNumbers can only be RLMInt, RLMFloat, RLMDouble, and RLMBool at the moment. " + @"See https://realm.io/docs/objc/latest for more information.", _name, numberType); + } + } + else if (strncmp(code, linkingObjectsPrefix, linkingObjectsPrefixLen) == 0 && + (code[linkingObjectsPrefixLen] == '"' || code[linkingObjectsPrefixLen] == '<')) { + _type = RLMPropertyTypeLinkingObjects; + _optional = false; + + if (!_objectClassName || !_linkOriginPropertyName) { + @throw RLMException(@"Property '%@' is of type RLMLinkingObjects but +linkingObjectsProperties did not specify the class " + "or property that is the origin of the link.", _name); + } + + // If the property was declared with a protocol indicating the contained type, validate that it matches + // the class from the dictionary returned by +linkingObjectsProperties. + if (code[linkingObjectsPrefixLen] == '<') { + NSString *classNameFromProtocol = [[NSString alloc] initWithBytes:code + linkingObjectsPrefixLen + 1 + length:strlen(code + linkingObjectsPrefixLen) - 3 // drop trailing >" + encoding:NSUTF8StringEncoding]; + if (![_objectClassName isEqualToString:classNameFromProtocol]) { + @throw RLMException(@"Property '%@' was declared with type RLMLinkingObjects<%@>, but a conflicting " + "class name of '%@' was returned by +linkingObjectsProperties.", _name, + classNameFromProtocol, _objectClassName); + } + } + } + else if (strcmp(code, "@\"NSNumber\"") == 0) { + @throw RLMException(@"Property '%@' requires a protocol defining the contained type - example: NSNumber.", _name); + } + else if (strcmp(code, "@\"RLMArray\"") == 0) { + @throw RLMException(@"Property '%@' requires a protocol defining the contained type - example: RLMArray.", _name); + } + else { + NSString *className; + Class cls = nil; + if (code[1] == '\0') { + className = @"id"; + } + else { + // for objects strip the quotes and @ + className = [_objcRawType substringWithRange:NSMakeRange(2, _objcRawType.length-3)]; + cls = [RLMSchema classForString:className]; + } + + if (!cls) { + @throw RLMException(@"Property '%@' is declared as '%@', which is not a supported RLMObject property type. " + @"All properties must be primitives, NSString, NSDate, NSData, NSNumber, RLMArray, RLMLinkingObjects, or subclasses of RLMObject. " + @"See https://realm.io/docs/objc/latest/api/Classes/RLMObject.html for more information.", _name, className); + } + + _type = RLMPropertyTypeObject; + _optional = true; + _objectClassName = [cls className] ?: className; + } + return YES; + } + default: + return NO; + } +} + +- (bool)parseObjcProperty:(objc_property_t)property { + unsigned int count; + objc_property_attribute_t *attrs = property_copyAttributeList(property, &count); + + bool isReadOnly = false; + for (size_t i = 0; i < count; ++i) { + switch (*attrs[i].name) { + case 'T': + _objcRawType = @(attrs[i].value); + break; + case 'R': + isReadOnly = true; + break; + case 'N': + // nonatomic + break; + case 'D': + // dynamic + break; + case 'G': + _getterName = @(attrs[i].value); + break; + case 'S': + _setterName = @(attrs[i].value); + break; + default: + break; + } + } + free(attrs); + + return isReadOnly; +} + +- (instancetype)initSwiftPropertyWithName:(NSString *)name + indexed:(BOOL)indexed + linkPropertyDescriptor:(RLMPropertyDescriptor *)linkPropertyDescriptor + property:(objc_property_t)property + instance:(RLMObject *)obj { + self = [super init]; + if (!self) { + return nil; + } + + _name = name; + _indexed = indexed; + + if (linkPropertyDescriptor) { + _objectClassName = [linkPropertyDescriptor.objectClass className]; + _linkOriginPropertyName = linkPropertyDescriptor.propertyName; + } + + if ([self parseObjcProperty:property]) { + return nil; + } + + id propertyValue = [obj valueForKey:_name]; + + // FIXME: temporarily workaround added since Objective-C generics used in Swift show up as `@` + // * broken starting in Swift 3.0 Xcode 8 b1 + // * tested to still be broken in Swift 3.0 Xcode 8 b6 + // * if the Realm Objective-C Swift tests pass with this removed, it's been fixed + // * once it has been fixed, remove this entire conditional block (contents included) entirely + // * Bug Report: SR-2031 https://bugs.swift.org/browse/SR-2031 + if ([_objcRawType isEqualToString:@"@"]) { + if (propertyValue) { + _objcRawType = [NSString stringWithFormat:@"@\"%@\"", [propertyValue class]]; + } else if (linkPropertyDescriptor) { + // we're going to naively assume that the user used the correct type since we can't check it + _objcRawType = @"@\"RLMLinkingObjects\""; + } + } + + // convert array types to objc variant + if ([_objcRawType isEqualToString:@"@\"RLMArray\""]) { + _objcRawType = [NSString stringWithFormat:@"@\"RLMArray<%@>\"", [propertyValue objectClassName]]; + } + else if ([_objcRawType isEqualToString:@"@\"NSNumber\""]) { + const char *numberType = [propertyValue objCType]; + if (!numberType) { + @throw RLMException(@"Can't persist NSNumber without default value: use a Swift-native number type or provide a default value."); + } + switch (*numberType) { + case 'i': + case 'l': + case 'q': + _objcRawType = @"@\"NSNumber\""; + break; + case 'f': + _objcRawType = @"@\"NSNumber\""; + break; + case 'd': + _objcRawType = @"@\"NSNumber\""; + break; + case 'B': + case 'c': + _objcRawType = @"@\"NSNumber\""; + break; + default: + @throw RLMException(@"Can't persist NSNumber of type '%s': only integers, floats, doubles, and bools are currently supported.", numberType); + } + } + + auto throwForPropertyName = ^(NSString *propertyName){ + @throw RLMException(@"Can't persist property '%@' with incompatible type. " + "Add to Object.ignoredProperties() class method to ignore.", + propertyName); + }; + + if (![self setTypeFromRawType]) { + throwForPropertyName(self.name); + } + + if (_objcType == 'c') { + // Check if it's a BOOL or Int8 by trying to set it to 2 and seeing if + // it actually sets it to 1. + [obj setValue:@2 forKey:name]; + NSNumber *value = [obj valueForKey:name]; + _type = value.intValue == 2 ? RLMPropertyTypeInt : RLMPropertyTypeBool; + } + + // update getter/setter names + [self updateAccessors]; + + return self; +} + +- (instancetype)initWithName:(NSString *)name + indexed:(BOOL)indexed + linkPropertyDescriptor:(RLMPropertyDescriptor *)linkPropertyDescriptor + property:(objc_property_t)property +{ + self = [super init]; + if (!self) { + return nil; + } + + _name = name; + _indexed = indexed; + + if (linkPropertyDescriptor) { + _objectClassName = [linkPropertyDescriptor.objectClass className]; + _linkOriginPropertyName = linkPropertyDescriptor.propertyName; + } + + bool isReadOnly = [self parseObjcProperty:property]; + bool isComputedProperty = rawTypeIsComputedProperty(_objcRawType); + if (isReadOnly && !isComputedProperty) { + return nil; + } + + if (![self setTypeFromRawType]) { + @throw RLMException(@"Can't persist property '%@' with incompatible type. " + "Add to ignoredPropertyNames: method to ignore.", self.name); + } + + if (!isReadOnly && isComputedProperty) { + @throw RLMException(@"Property '%@' must be declared as readonly as %@ properties cannot be written to.", + self.name, RLMTypeToString(_type)); + } + + // update getter/setter names + [self updateAccessors]; + + return self; +} + +- (instancetype)initSwiftListPropertyWithName:(NSString *)name + ivar:(Ivar)ivar + objectClassName:(NSString *)objectClassName { + self = [super init]; + if (!self) { + return nil; + } + + _name = name; + _type = RLMPropertyTypeArray; + _objectClassName = objectClassName; + _objcType = 't'; + _swiftIvar = ivar; + + // no obj-c property for generic lists, and thus no getter/setter names + + return self; +} + +- (instancetype)initSwiftOptionalPropertyWithName:(NSString *)name + indexed:(BOOL)indexed + ivar:(Ivar)ivar + propertyType:(RLMPropertyType)propertyType { + self = [super init]; + if (!self) { + return nil; + } + + _name = name; + _type = propertyType; + _indexed = indexed; + _objcType = '@'; + _swiftIvar = ivar; + _optional = true; + + // no obj-c property for generic optionals, and thus no getter/setter names + + return self; +} + +- (instancetype)initSwiftLinkingObjectsPropertyWithName:(NSString *)name + ivar:(Ivar)ivar + objectClassName:(NSString *)objectClassName + linkOriginPropertyName:(NSString *)linkOriginPropertyName { + self = [super init]; + if (!self) { + return nil; + } + + _name = name; + _type = RLMPropertyTypeLinkingObjects; + _objectClassName = objectClassName; + _linkOriginPropertyName = linkOriginPropertyName; + _objcType = '@'; + _swiftIvar = ivar; + + // no obj-c property for generic linking objects properties, and thus no getter/setter names + + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + RLMProperty *prop = [[RLMProperty allocWithZone:zone] init]; + prop->_name = _name; + prop->_type = _type; + prop->_objcType = _objcType; + prop->_objectClassName = _objectClassName; + prop->_indexed = _indexed; + prop->_getterName = _getterName; + prop->_setterName = _setterName; + prop->_getterSel = _getterSel; + prop->_setterSel = _setterSel; + prop->_isPrimary = _isPrimary; + prop->_swiftIvar = _swiftIvar; + prop->_optional = _optional; + prop->_linkOriginPropertyName = _linkOriginPropertyName; + + return prop; +} + +- (RLMProperty *)copyWithNewName:(NSString *)name { + RLMProperty *prop = [self copy]; + prop.name = name; + return prop; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[RLMProperty class]]) { + return NO; + } + + return [self isEqualToProperty:object]; +} + +- (BOOL)isEqualToProperty:(RLMProperty *)property { + return _type == property->_type + && _indexed == property->_indexed + && _isPrimary == property->_isPrimary + && _optional == property->_optional + && [_name isEqualToString:property->_name] + && (_objectClassName == property->_objectClassName || [_objectClassName isEqualToString:property->_objectClassName]) + && (_linkOriginPropertyName == property->_linkOriginPropertyName || [_linkOriginPropertyName isEqualToString:property->_linkOriginPropertyName]); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@ {\n\ttype = %@;\n\tobjectClassName = %@;\n\tlinkOriginPropertyName = %@;\n\tindexed = %@;\n\tisPrimary = %@;\n\toptional = %@;\n}", self.name, RLMTypeToString(self.type), self.objectClassName, self.linkOriginPropertyName, self.indexed ? @"YES" : @"NO", self.isPrimary ? @"YES" : @"NO", self.optional ? @"YES" : @"NO"]; +} + +- (realm::Property)objectStoreCopy { + realm::Property p; + p.name = _name.UTF8String; + p.type = (realm::PropertyType)_type; + p.object_type = _objectClassName ? _objectClassName.UTF8String : ""; + p.is_indexed = _indexed; + p.is_nullable = _optional; + p.link_origin_property_name = _linkOriginPropertyName ? _linkOriginPropertyName.UTF8String : ""; + return p; +} + +@end + +@implementation RLMPropertyDescriptor + ++ (instancetype)descriptorWithClass:(Class)objectClass propertyName:(NSString *)propertyName +{ + RLMPropertyDescriptor *descriptor = [[RLMPropertyDescriptor alloc] init]; + descriptor->_objectClass = objectClass; + descriptor->_propertyName = propertyName; + return descriptor; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMQueryUtil.mm b/SiriKitExample/Pods/Realm/Realm/RLMQueryUtil.mm new file mode 100644 index 0000000..cf861e8 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMQueryUtil.mm @@ -0,0 +1,1378 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMQueryUtil.hpp" + +#import "RLMArray.h" +#import "RLMObjectSchema.h" +#import "RLMObject_Private.hpp" +#import "RLMPredicateUtil.hpp" +#import "RLMProperty.h" +#import "RLMSchema.h" +#import "RLMUtil.hpp" + +#import "object_store.hpp" +#import "results.hpp" + +#include + +using namespace realm; + +NSString * const RLMPropertiesComparisonTypeMismatchException = @"RLMPropertiesComparisonTypeMismatchException"; +NSString * const RLMUnsupportedTypesFoundInPropertyComparisonException = @"RLMUnsupportedTypesFoundInPropertyComparisonException"; + +NSString * const RLMPropertiesComparisonTypeMismatchReason = @"Property type mismatch between %@ and %@"; +NSString * const RLMUnsupportedTypesFoundInPropertyComparisonReason = @"Comparison between %@ and %@"; + +// small helper to create the many exceptions thrown when parsing predicates +static NSException *RLMPredicateException(NSString *name, NSString *format, ...) { + va_list args; + va_start(args, format); + NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [NSException exceptionWithName:name reason:reason userInfo:nil]; +} + +// check a precondition and throw an exception if it is not met +// this should be used iff the condition being false indicates a bug in the caller +// of the function checking its preconditions +static void RLMPrecondition(bool condition, NSString *name, NSString *format, ...) { + if (__builtin_expect(condition, 1)) { + return; + } + + va_list args; + va_start(args, format); + NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + @throw [NSException exceptionWithName:name reason:reason userInfo:nil]; +} + +// return the property for a validated column name +RLMProperty *RLMValidatedProperty(RLMObjectSchema *desc, NSString *columnName) { + RLMProperty *prop = desc[columnName]; + RLMPrecondition(prop, @"Invalid property name", + @"Property '%@' not found in object of type '%@'", columnName, desc.className); + return prop; +} + +namespace { +BOOL RLMPropertyTypeIsNumeric(RLMPropertyType propertyType) { + switch (propertyType) { + case RLMPropertyTypeInt: + case RLMPropertyTypeFloat: + case RLMPropertyTypeDouble: + return YES; + default: + return NO; + } +} + +// FIXME: TrueExpression and FalseExpression should be supported by core in some way + +struct TrueExpression : realm::Expression { + size_t find_first(size_t start, size_t end) const override + { + if (start != end) + return start; + + return realm::not_found; + } + void set_base_table(const Table*) override {} + const Table* get_base_table() const override { return nullptr; } + std::unique_ptr clone(QueryNodeHandoverPatches*) const override + { + return std::unique_ptr(new TrueExpression(*this)); + } +}; + +struct FalseExpression : realm::Expression { + size_t find_first(size_t, size_t) const override { return realm::not_found; } + void set_base_table(const Table*) override {} + const Table* get_base_table() const override { return nullptr; } + std::unique_ptr clone(QueryNodeHandoverPatches*) const override + { + return std::unique_ptr(new FalseExpression(*this)); + } +}; + +NSString *operatorName(NSPredicateOperatorType operatorType) +{ + switch (operatorType) { + case NSLessThanPredicateOperatorType: + return @"<"; + case NSLessThanOrEqualToPredicateOperatorType: + return @"<="; + case NSGreaterThanPredicateOperatorType: + return @">"; + case NSGreaterThanOrEqualToPredicateOperatorType: + return @">="; + case NSEqualToPredicateOperatorType: + return @"=="; + case NSNotEqualToPredicateOperatorType: + return @"!="; + case NSMatchesPredicateOperatorType: + return @"MATCHES"; + case NSLikePredicateOperatorType: + return @"LIKE"; + case NSBeginsWithPredicateOperatorType: + return @"BEGINSWITH"; + case NSEndsWithPredicateOperatorType: + return @"ENDSWITH"; + case NSInPredicateOperatorType: + return @"IN"; + case NSContainsPredicateOperatorType: + return @"CONTAINS"; + case NSBetweenPredicateOperatorType: + return @"BETWEEN"; + case NSCustomSelectorPredicateOperatorType: + return @"custom selector"; + } + + return [NSString stringWithFormat:@"unknown operator %lu", (unsigned long)operatorType]; +} + +Table& get_table(Group& group, RLMObjectSchema *objectSchema) +{ + return *ObjectStore::table_for_object_type(group, objectSchema.className.UTF8String); +} + +// A reference to a column within a query. Can be resolved to a Columns for use in query expressions. +class ColumnReference { +public: + ColumnReference(Query& query, Group& group, RLMSchema *schema, RLMProperty* property, const std::vector& links = {}) + : m_links(links), m_property(property), m_schema(schema), m_group(&group), m_query(&query), m_table(query.get_table().get()) + { + auto& table = walk_link_chain([](Table&, size_t, RLMPropertyType) { }); + m_index = table.get_column_index(m_property.name.UTF8String); + } + + template + auto resolve(SubQuery&&... subquery) const + { + static_assert(sizeof...(SubQuery) < 2, "resolve() takes at most one subquery"); + set_link_chain_on_table(); + if (type() != RLMPropertyTypeLinkingObjects) { + return m_table->template column(index(), std::forward(subquery)...); + } + else { + return resolve_backlink(std::forward(subquery)...); + } + } + + RLMProperty *property() const { return m_property; } + size_t index() const { return m_index; } + RLMPropertyType type() const { return property().type; } + Group& group() const { return *m_group; } + + RLMObjectSchema *link_target_object_schema() const + { + switch (type()) { + case RLMPropertyTypeObject: + case RLMPropertyTypeArray: + case RLMPropertyTypeLinkingObjects: + return m_schema[property().objectClassName]; + default: + REALM_ASSERT(false); + } + } + + bool has_links() const { return m_links.size(); } + + bool has_any_to_many_links() const { + return std::any_of(begin(m_links), end(m_links), [](RLMProperty *property) { + return property.type == RLMPropertyTypeArray || property.type == RLMPropertyTypeLinkingObjects; + }); + } + + ColumnReference last_link_column() const { + REALM_ASSERT(!m_links.empty()); + return {*m_query, *m_group, m_schema, m_links.back(), {m_links.begin(), m_links.end() - 1}}; + } + + ColumnReference column_ignoring_links(Query& query) const { + return {query, *m_group, m_schema, m_property}; + } + +private: + template + auto resolve_backlink(SubQuery&&... subquery) const + { + // We actually just want `if constexpr (std::is_same::value) { ... }`, + // so fake it by tag-dispatching on the conditional + return do_resolve_backlink(std::is_same(), std::forward(subquery)...); + } + + template + auto do_resolve_backlink(std::true_type, SubQuery&&... subquery) const + { + return with_link_origin(m_property, [&](Table& table, size_t col) { + return m_table->template column(table, col, std::forward(subquery)...); + }); + } + + template + Columns do_resolve_backlink(std::false_type, SubQuery&&...) const + { + // This can't actually happen as we only call resolve_backlink() if + // it's RLMPropertyTypeLinkingObjects + __builtin_unreachable(); + } + + template + Table& walk_link_chain(Func&& func) const + { + auto table = m_query->get_table().get(); + for (const auto& link : m_links) { + if (link.type != RLMPropertyTypeLinkingObjects) { + auto index = table->get_column_index(link.name.UTF8String); + func(*table, index, link.type); + table = table->get_link_target(index).get(); + } + else { + with_link_origin(link, [&](Table& link_origin_table, size_t link_origin_column) { + func(link_origin_table, link_origin_column, link.type); + table = &link_origin_table; + }); + } + } + return *table; + } + + template + auto with_link_origin(RLMProperty *prop, Func&& func) const + { + RLMObjectSchema *link_origin_schema = m_schema[prop.objectClassName]; + Table& link_origin_table = get_table(*m_group, link_origin_schema); + size_t link_origin_column = link_origin_table.get_column_index(prop.linkOriginPropertyName.UTF8String); + return func(link_origin_table, link_origin_column); + } + + void set_link_chain_on_table() const + { + walk_link_chain([&](Table& current_table, size_t column, RLMPropertyType type) { + if (type == RLMPropertyTypeLinkingObjects) { + m_table->backlink(current_table, column); + } + else { + m_table->link(column); + } + }); + } + + std::vector m_links; + RLMProperty *m_property; + RLMSchema *m_schema; + Group *m_group; + Query *m_query; + Table *m_table; + size_t m_index; +}; + +class CollectionOperation { +public: + enum Type { + Count, + Minimum, + Maximum, + Sum, + Average, + }; + + CollectionOperation(Type type, ColumnReference link_column, util::Optional column) + : m_type(type) + , m_link_column(std::move(link_column)) + , m_column(std::move(column)) + { + RLMPrecondition(m_link_column.type() == RLMPropertyTypeArray || m_link_column.type() == RLMPropertyTypeLinkingObjects, + @"Invalid predicate", @"Collection operation can only be applied to a property of type RLMArray."); + + switch (m_type) { + case Count: + RLMPrecondition(!m_column, @"Invalid predicate", @"Result of @count does not have any properties."); + break; + case Minimum: + case Maximum: + case Sum: + case Average: + RLMPrecondition(m_column && RLMPropertyTypeIsNumeric(m_column->type()), @"Invalid predicate", + @"%@ can only be applied to a numeric property.", name_for_type(m_type)); + break; + } + } + + CollectionOperation(NSString *operationName, ColumnReference link_column, util::Optional column = util::none) + : CollectionOperation(type_for_name(operationName), std::move(link_column), std::move(column)) + { + } + + Type type() const { return m_type; } + const ColumnReference& link_column() const { return m_link_column; } + const ColumnReference& column() const { return *m_column; } + + void validate_comparison(id value) const { + switch (m_type) { + case Count: + case Average: + RLMPrecondition([value isKindOfClass:[NSNumber class]], @"Invalid operand", + @"%@ can only be compared with a numeric value.", name_for_type(m_type)); + break; + case Minimum: + case Maximum: + case Sum: + RLMPrecondition(RLMIsObjectValidForProperty(value, m_column->property()), @"Invalid operand", + @"%@ on a property of type %@ cannot be compared with '%@'", + name_for_type(m_type), RLMTypeToString(m_column->type()), value); + break; + } + } + + void validate_comparison(const ColumnReference& column) const { + switch (m_type) { + case Count: + RLMPrecondition(RLMPropertyTypeIsNumeric(column.type()), @"Invalid operand", + @"%@ can only be compared with a numeric value.", name_for_type(m_type)); + break; + case Average: + case Minimum: + case Maximum: + case Sum: + RLMPrecondition(RLMPropertyTypeIsNumeric(column.type()), @"Invalid operand", + @"%@ on a property of type %@ cannot be compared with property of type '%@'", + name_for_type(m_type), RLMTypeToString(m_column->type()), RLMTypeToString(column.type())); + break; + } + } + +private: + static Type type_for_name(NSString *name) { + if ([name isEqualToString:@"@count"]) { + return Count; + } + if ([name isEqualToString:@"@min"]) { + return Minimum; + } + if ([name isEqualToString:@"@max"]) { + return Maximum; + } + if ([name isEqualToString:@"@sum"]) { + return Sum; + } + if ([name isEqualToString:@"@avg"]) { + return Average; + } + @throw RLMPredicateException(@"Invalid predicate", @"Unsupported collection operation '%@'", name); + } + + static NSString *name_for_type(Type type) { + switch (type) { + case Count: return @"@count"; + case Minimum: return @"@min"; + case Maximum: return @"@max"; + case Sum: return @"@sum"; + case Average: return @"@avg"; + } + } + + Type m_type; + ColumnReference m_link_column; + util::Optional m_column; +}; + +class QueryBuilder { +public: + QueryBuilder(Query& query, Group& group, RLMSchema *schema) + : m_query(query), m_group(group), m_schema(schema) { } + + void apply_predicate(NSPredicate *predicate, RLMObjectSchema *objectSchema); + + + void apply_collection_operator_expression(RLMObjectSchema *desc, NSString *keyPath, id value, NSComparisonPredicate *pred); + void apply_value_expression(RLMObjectSchema *desc, NSString *keyPath, id value, NSComparisonPredicate *pred); + void apply_column_expression(RLMObjectSchema *desc, NSString *leftKeyPath, NSString *rightKeyPath, NSComparisonPredicate *predicate); + void apply_subquery_count_expression(RLMObjectSchema *objectSchema, NSExpression *subqueryExpression, + NSPredicateOperatorType operatorType, NSExpression *right); + void apply_function_subquery_expression(RLMObjectSchema *objectSchema, NSExpression *functionExpression, + NSPredicateOperatorType operatorType, NSExpression *right); + void apply_function_expression(RLMObjectSchema *objectSchema, NSExpression *functionExpression, + NSPredicateOperatorType operatorType, NSExpression *right); + + + template + void add_numeric_constraint(RLMPropertyType datatype, + NSPredicateOperatorType operatorType, + A&& lhs, B&& rhs); + + template + void add_bool_constraint(NSPredicateOperatorType operatorType, A lhs, B rhs); + + template + void add_string_constraint(NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, + Columns &&column, + T value); + + void add_string_constraint(NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, + StringData value, + Columns&& column); + + template + void add_constraint(RLMPropertyType type, + NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, + L lhs, R rhs); + template + void do_add_constraint(RLMPropertyType type, NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, T... values); + void do_add_constraint(RLMPropertyType, NSPredicateOperatorType, NSComparisonPredicateOptions, id, realm::null); + + void add_between_constraint(const ColumnReference& column, id value); + + template + void add_binary_constraint(NSPredicateOperatorType operatorType, const ColumnReference& column, T value); + void add_binary_constraint(NSPredicateOperatorType operatorType, const ColumnReference& column, id value); + void add_binary_constraint(NSPredicateOperatorType operatorType, id value, const ColumnReference& column); + void add_binary_constraint(NSPredicateOperatorType, const ColumnReference&, const ColumnReference&); + + void add_link_constraint(NSPredicateOperatorType operatorType, const ColumnReference& column, RLMObject *obj); + void add_link_constraint(NSPredicateOperatorType operatorType, const ColumnReference& column, realm::null); + template + void add_link_constraint(NSPredicateOperatorType operatorType, T obj, const ColumnReference& column); + void add_link_constraint(NSPredicateOperatorType, const ColumnReference&, const ColumnReference&); + + template + void add_collection_operation_constraint(RLMPropertyType propertyType, NSPredicateOperatorType operatorType, T... values); + template + void add_collection_operation_constraint(NSPredicateOperatorType operatorType, + CollectionOperation collectionOperation, T... values); + + + CollectionOperation collection_operation_from_key_path(RLMObjectSchema *desc, NSString *keyPath); + ColumnReference column_reference_from_key_path(RLMObjectSchema *objectSchema, NSString *keyPath, bool isAggregate); + +private: + Query& m_query; + Group& m_group; + RLMSchema *m_schema; +}; + +// add a clause for numeric constraints based on operator type +template +void QueryBuilder::add_numeric_constraint(RLMPropertyType datatype, + NSPredicateOperatorType operatorType, + A&& lhs, B&& rhs) +{ + switch (operatorType) { + case NSLessThanPredicateOperatorType: + m_query.and_query(lhs < rhs); + break; + case NSLessThanOrEqualToPredicateOperatorType: + m_query.and_query(lhs <= rhs); + break; + case NSGreaterThanPredicateOperatorType: + m_query.and_query(lhs > rhs); + break; + case NSGreaterThanOrEqualToPredicateOperatorType: + m_query.and_query(lhs >= rhs); + break; + case NSEqualToPredicateOperatorType: + m_query.and_query(lhs == rhs); + break; + case NSNotEqualToPredicateOperatorType: + m_query.and_query(lhs != rhs); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' not supported for type %@", operatorName(operatorType), RLMTypeToString(datatype)); + } +} + +template +void QueryBuilder::add_bool_constraint(NSPredicateOperatorType operatorType, A lhs, B rhs) { + switch (operatorType) { + case NSEqualToPredicateOperatorType: + m_query.and_query(lhs == rhs); + break; + case NSNotEqualToPredicateOperatorType: + m_query.and_query(lhs != rhs); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' not supported for bool type", operatorName(operatorType)); + } +} + +template +void QueryBuilder::add_string_constraint(NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, + Columns &&column, + T value) { + bool caseSensitive = !(predicateOptions & NSCaseInsensitivePredicateOption); + bool diacriticInsensitive = (predicateOptions & NSDiacriticInsensitivePredicateOption); + RLMPrecondition(!diacriticInsensitive, @"Invalid predicate option", + @"NSDiacriticInsensitivePredicateOption not supported for string type"); + + switch (operatorType) { + case NSBeginsWithPredicateOperatorType: + m_query.and_query(column.begins_with(value, caseSensitive)); + break; + case NSEndsWithPredicateOperatorType: + m_query.and_query(column.ends_with(value, caseSensitive)); + break; + case NSContainsPredicateOperatorType: + m_query.and_query(column.contains(value, caseSensitive)); + break; + case NSEqualToPredicateOperatorType: + m_query.and_query(column.equal(value, caseSensitive)); + break; + case NSNotEqualToPredicateOperatorType: + m_query.and_query(column.not_equal(value, caseSensitive)); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' not supported for string type", operatorName(operatorType)); + } +} + +void QueryBuilder::add_string_constraint(NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, + StringData value, + Columns&& column) { + switch (operatorType) { + case NSEqualToPredicateOperatorType: + case NSNotEqualToPredicateOperatorType: + add_string_constraint(operatorType, predicateOptions, std::move(column), value); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' is not supported for string type with key path on right side of operator", + operatorName(operatorType)); + } +} + +id value_from_constant_expression_or_value(id value) { + if (NSExpression *exp = RLMDynamicCast(value)) { + RLMPrecondition(exp.expressionType == NSConstantValueExpressionType, + @"Invalid value", + @"Expressions within predicate aggregates must be constant values"); + return exp.constantValue; + } + return value; +} + +void validate_and_extract_between_range(id value, RLMProperty *prop, id *from, id *to) { + NSArray *array = RLMDynamicCast(value); + RLMPrecondition(array, @"Invalid value", @"object must be of type NSArray for BETWEEN operations"); + RLMPrecondition(array.count == 2, @"Invalid value", @"NSArray object must contain exactly two objects for BETWEEN operations"); + + *from = value_from_constant_expression_or_value(array.firstObject); + *to = value_from_constant_expression_or_value(array.lastObject); + RLMPrecondition(RLMIsObjectValidForProperty(*from, prop) && RLMIsObjectValidForProperty(*to, prop), + @"Invalid value", + @"NSArray objects must be of type %@ for BETWEEN operations", RLMTypeToString(prop.type)); +} + +void QueryBuilder::add_between_constraint(const ColumnReference& column, id value) { + if (column.has_any_to_many_links()) { + auto link_column = column.last_link_column(); + Query subquery = get_table(m_group, link_column.link_target_object_schema()).where(); + QueryBuilder(subquery, m_group, m_schema).add_between_constraint(column.column_ignoring_links(subquery), value); + + m_query.and_query(link_column.resolve(std::move(subquery)).count() > 0); + return; + } + + id from, to; + validate_and_extract_between_range(value, column.property(), &from, &to); + + RLMPropertyType type = column.type(); + + m_query.group(); + add_constraint(type, NSGreaterThanOrEqualToPredicateOperatorType, 0, column, from); + add_constraint(type, NSLessThanOrEqualToPredicateOperatorType, 0, column, to); + m_query.end_group(); +} + +template +void QueryBuilder::add_binary_constraint(NSPredicateOperatorType operatorType, + const ColumnReference& column, + T value) { + RLMPrecondition(!column.has_links(), @"Unsupported operator", @"NSData properties cannot be queried over an object link."); + + size_t index = column.index(); + switch (operatorType) { + case NSBeginsWithPredicateOperatorType: + m_query.begins_with(index, value); + break; + case NSEndsWithPredicateOperatorType: + m_query.ends_with(index, value); + break; + case NSContainsPredicateOperatorType: + m_query.contains(index, value); + break; + case NSEqualToPredicateOperatorType: + m_query.equal(index, value); + break; + case NSNotEqualToPredicateOperatorType: + m_query.not_equal(index, value); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' not supported for binary type", operatorName(operatorType)); + } +} + +void QueryBuilder::add_binary_constraint(NSPredicateOperatorType operatorType, const ColumnReference& column, id value) { + add_binary_constraint(operatorType, column, RLMBinaryDataForNSData(value)); +} + +void QueryBuilder::add_binary_constraint(NSPredicateOperatorType operatorType, id value, const ColumnReference& column) { + switch (operatorType) { + case NSEqualToPredicateOperatorType: + case NSNotEqualToPredicateOperatorType: + add_binary_constraint(operatorType, column, value); + break; + default: + @throw RLMPredicateException(@"Invalid operator type", + @"Operator '%@' is not supported for binary type with key path on right side of operator", + operatorName(operatorType)); + } +} + +void QueryBuilder::add_binary_constraint(NSPredicateOperatorType, const ColumnReference&, const ColumnReference&) { + @throw RLMPredicateException(@"Invalid predicate", @"Comparisons between two NSData properties are not supported"); +} + +void QueryBuilder::add_link_constraint(NSPredicateOperatorType operatorType, + const ColumnReference& column, RLMObject *obj) { + RLMPrecondition(operatorType == NSEqualToPredicateOperatorType || operatorType == NSNotEqualToPredicateOperatorType, + @"Invalid operator type", @"Only 'Equal' and 'Not Equal' operators supported for object comparison"); + + if (operatorType == NSEqualToPredicateOperatorType) { + m_query.and_query(column.resolve() == obj->_row); + } + else { + m_query.and_query(column.resolve() != obj->_row); + } +} + +void QueryBuilder::add_link_constraint(NSPredicateOperatorType operatorType, + const ColumnReference& column, + realm::null) { + RLMPrecondition(!column.has_links(), @"Unsupported operator", @"Multi-level object equality link queries are not supported."); + RLMPrecondition(operatorType == NSEqualToPredicateOperatorType || operatorType == NSNotEqualToPredicateOperatorType, + @"Invalid operator type", @"Only 'Equal' and 'Not Equal' operators supported for object comparison"); + if (operatorType == NSNotEqualToPredicateOperatorType) { + m_query.Not(); + } + + m_query.and_query(column.resolve().is_null()); +} + +template +void QueryBuilder::add_link_constraint(NSPredicateOperatorType operatorType, T obj, const ColumnReference& column) { + // Link constraints only support the equal-to and not-equal-to operators. The order of operands + // is not important for those comparisons so we can delegate to the other implementation. + add_link_constraint(operatorType, column, obj); +} + +void QueryBuilder::add_link_constraint(NSPredicateOperatorType, const ColumnReference&, const ColumnReference&) { + // This is not actually reachable as this case is caught earlier, but this + // overload is needed for the code to compile + @throw RLMPredicateException(@"Invalid predicate", @"Comparisons between two RLMArray properties are not supported"); +} + + +// iterate over an array of subpredicates, using @func to build a query from each +// one and ORing them together +template +void process_or_group(Query &query, id array, Func&& func) { + RLMPrecondition([array conformsToProtocol:@protocol(NSFastEnumeration)], + @"Invalid value", @"IN clause requires an array of items"); + + query.group(); + + bool first = true; + for (id item in array) { + if (!first) { + query.Or(); + } + first = false; + + func(item); + } + + if (first) { + // Queries can't be empty, so if there's zero things in the OR group + // validation will fail. Work around this by adding an expression which + // will never find any rows in a table. + query.and_query(std::unique_ptr(new FalseExpression)); + } + + query.end_group(); +} + +template +RequestedType convert(id value); + +template <> +Timestamp convert(id value) { + return RLMTimestampForNSDate(value); +} + +template <> +bool convert(id value) { + return [value boolValue]; +} + +template <> +Double convert(id value) { + return [value doubleValue]; +} + +template <> +Float convert(id value) { + return [value floatValue]; +} + +template <> +Int convert(id value) { + return [value longLongValue]; +} + +template <> +String convert(id value) { + return RLMStringDataWithNSString(value); +} + +template +realm::null value_of_type(realm::null) { + return realm::null(); +} + +template +auto value_of_type(id value) { + return ::convert(value); +} + +template +auto value_of_type(const ColumnReference& column) { + return column.resolve(); +} + + +template +void QueryBuilder::do_add_constraint(RLMPropertyType type, NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, T... values) +{ + static_assert(sizeof...(T) == 2, "do_add_constraint accepts only two values as arguments"); + + switch (type) { + case RLMPropertyTypeBool: + add_bool_constraint(operatorType, value_of_type(values)...); + break; + case RLMPropertyTypeDate: + add_numeric_constraint(type, operatorType, value_of_type(values)...); + break; + case RLMPropertyTypeDouble: + add_numeric_constraint(type, operatorType, value_of_type(values)...); + break; + case RLMPropertyTypeFloat: + add_numeric_constraint(type, operatorType, value_of_type(values)...); + break; + case RLMPropertyTypeInt: + add_numeric_constraint(type, operatorType, value_of_type(values)...); + break; + case RLMPropertyTypeString: + add_string_constraint(operatorType, predicateOptions, value_of_type(values)...); + break; + case RLMPropertyTypeData: + add_binary_constraint(operatorType, values...); + break; + case RLMPropertyTypeObject: + case RLMPropertyTypeArray: + case RLMPropertyTypeLinkingObjects: + add_link_constraint(operatorType, values...); + break; + default: + @throw RLMPredicateException(@"Unsupported predicate value type", + @"Object type %@ not supported", RLMTypeToString(type)); + } +} + +void QueryBuilder::do_add_constraint(RLMPropertyType, NSPredicateOperatorType, NSComparisonPredicateOptions, id, realm::null) +{ + // This is not actually reachable as this case is caught earlier, but this + // overload is needed for the code to compile + @throw RLMPredicateException(@"Invalid predicate expressions", + @"Predicate expressions must compare a keypath and another keypath or a constant value"); +} + +bool is_nsnull(id value) { + return !value || value == NSNull.null; +} + +template +bool is_nsnull(T) { + return false; +} + +template +void QueryBuilder::add_constraint(RLMPropertyType type, NSPredicateOperatorType operatorType, + NSComparisonPredicateOptions predicateOptions, L lhs, R rhs) +{ + // The expression operators are only overloaded for realm::null on the rhs + RLMPrecondition(!is_nsnull(lhs), @"Unsupported operator", + @"Nil is only supported on the right side of operators"); + + if (is_nsnull(rhs)) { + do_add_constraint(type, operatorType, predicateOptions, lhs, realm::null()); + } + else { + do_add_constraint(type, operatorType, predicateOptions, lhs, rhs); + } +} + +ColumnReference QueryBuilder::column_reference_from_key_path(RLMObjectSchema *objectSchema, NSString *keyPath, bool isAggregate) +{ + RLMProperty *property; + std::vector links; + + bool keyPathContainsToManyRelationship = false; + + NSUInteger start = 0, length = keyPath.length, end = NSNotFound; + do { + end = [keyPath rangeOfString:@"." options:0 range:{start, length - start}].location; + NSString *propertyName = [keyPath substringWithRange:{start, end == NSNotFound ? length - start : end - start}]; + property = objectSchema[propertyName]; + RLMPrecondition(property, @"Invalid property name", + @"Property '%@' not found in object of type '%@'", propertyName, objectSchema.className); + + if (property.type == RLMPropertyTypeArray || property.type == RLMPropertyTypeLinkingObjects) + keyPathContainsToManyRelationship = true; + + if (end != NSNotFound) { + RLMPrecondition(property.type == RLMPropertyTypeObject || property.type == RLMPropertyTypeArray || property.type == RLMPropertyTypeLinkingObjects, + @"Invalid value", @"Property '%@' is not a link in object of type '%@'", propertyName, objectSchema.className); + + links.push_back(property); + REALM_ASSERT(property.objectClassName); + objectSchema = m_schema[property.objectClassName]; + } + + start = end + 1; + } while (end != NSNotFound); + + if (isAggregate && !keyPathContainsToManyRelationship) { + @throw RLMPredicateException(@"Invalid predicate", + @"Aggregate operations can only be used on key paths that include an array property"); + } else if (!isAggregate && keyPathContainsToManyRelationship) { + @throw RLMPredicateException(@"Invalid predicate", + @"Key paths that include an array property must use aggregate operations"); + } + + return ColumnReference(m_query, m_group, m_schema, property, std::move(links)); +} + +void validate_property_value(const ColumnReference& column, + __unsafe_unretained id const value, + __unsafe_unretained NSString *const err, + __unsafe_unretained RLMObjectSchema *const objectSchema, + __unsafe_unretained NSString *const keyPath) { + RLMProperty *prop = column.property(); + if (prop.type == RLMPropertyTypeArray) { + RLMPrecondition([RLMObjectBaseObjectSchema(RLMDynamicCast(value)).className isEqualToString:prop.objectClassName], + @"Invalid value", err, prop.objectClassName, keyPath, objectSchema.className, value); + } + else { + RLMPrecondition(RLMIsObjectValidForProperty(value, prop), + @"Invalid value", err, RLMTypeToString(prop.type), keyPath, objectSchema.className, value); + } + if (RLMObjectBase *obj = RLMDynamicCast(value)) { + RLMPrecondition(!obj->_row.is_attached() || &column.group() == &obj->_realm.group, + @"Invalid value origin", @"Object must be from the Realm being queried"); + } +} + +template +struct ValueOfTypeWithCollectionOperationHelper; + +template <> +struct ValueOfTypeWithCollectionOperationHelper { + static auto convert(const CollectionOperation& operation) + { + assert(operation.type() == CollectionOperation::Count); + return operation.link_column().resolve().count(); + } +}; + +#define VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER(OperationType, function) \ +template \ +struct ValueOfTypeWithCollectionOperationHelper { \ + static auto convert(const CollectionOperation& operation) \ + { \ + REALM_ASSERT(operation.type() == OperationType); \ + auto targetColumn = operation.link_column().resolve().template column(operation.column().index()); \ + return targetColumn.function(); \ + } \ +} \ + +VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER(CollectionOperation::Minimum, min); +VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER(CollectionOperation::Maximum, max); +VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER(CollectionOperation::Sum, sum); +VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER(CollectionOperation::Average, average); +#undef VALUE_OF_TYPE_WITH_COLLECTION_OPERATOR_HELPER + +template +auto value_of_type_with_collection_operation(T&& value) { + return value_of_type(std::forward(value)); +} + +template +auto value_of_type_with_collection_operation(CollectionOperation operation) { + using helper = ValueOfTypeWithCollectionOperationHelper; + return helper::convert(operation); +} + +template +void QueryBuilder::add_collection_operation_constraint(RLMPropertyType propertyType, NSPredicateOperatorType operatorType, T... values) +{ + switch (propertyType) { + case RLMPropertyTypeInt: + add_numeric_constraint(propertyType, operatorType, value_of_type_with_collection_operation(values)...); + break; + case RLMPropertyTypeFloat: + add_numeric_constraint(propertyType, operatorType, value_of_type_with_collection_operation(values)...); + break; + case RLMPropertyTypeDouble: + add_numeric_constraint(propertyType, operatorType, value_of_type_with_collection_operation(values)...); + break; + default: + REALM_ASSERT(false && "Only numeric property types should hit this path."); + } +} + +template +void QueryBuilder::add_collection_operation_constraint(NSPredicateOperatorType operatorType, + CollectionOperation collectionOperation, T... values) +{ + static_assert(sizeof...(T) == 2, "add_collection_operation_constraint accepts only two values as arguments"); + + switch (collectionOperation.type()) { + case CollectionOperation::Count: + add_numeric_constraint(RLMPropertyTypeInt, operatorType, + value_of_type_with_collection_operation(values)...); + break; + case CollectionOperation::Minimum: + add_collection_operation_constraint(collectionOperation.column().type(), operatorType, values...); + break; + case CollectionOperation::Maximum: + add_collection_operation_constraint(collectionOperation.column().type(), operatorType, values...); + break; + case CollectionOperation::Sum: + add_collection_operation_constraint(collectionOperation.column().type(), operatorType, values...); + break; + case CollectionOperation::Average: + add_collection_operation_constraint(collectionOperation.column().type(), operatorType, values...); + break; + } +} + +bool key_path_contains_collection_operator(NSString *keyPath) { + return [keyPath rangeOfString:@"@"].location != NSNotFound; +} + +NSString *get_collection_operation_name_from_key_path(NSString *keyPath, NSString **leadingKeyPath, NSString **trailingKey) { + NSRange at = [keyPath rangeOfString:@"@"]; + if (at.location == NSNotFound || at.location >= keyPath.length - 1) { + @throw RLMPredicateException(@"Invalid key path", @"'%@' is not a valid key path'", keyPath); + } + + if (at.location == 0 || [keyPath characterAtIndex:at.location - 1] != '.') { + @throw RLMPredicateException(@"Invalid key path", @"'%@' is not a valid key path'", keyPath); + } + + NSRange trailingKeyRange = [keyPath rangeOfString:@"." options:0 range:{at.location, keyPath.length - at.location} locale:nil]; + + *leadingKeyPath = [keyPath substringToIndex:at.location - 1]; + if (trailingKeyRange.location == NSNotFound) { + *trailingKey = nil; + return [keyPath substringFromIndex:at.location]; + } else { + *trailingKey = [keyPath substringFromIndex:trailingKeyRange.location + 1]; + return [keyPath substringWithRange:{at.location, trailingKeyRange.location - at.location}]; + } +} + +CollectionOperation QueryBuilder::collection_operation_from_key_path(RLMObjectSchema *desc, NSString *keyPath) { + NSString *leadingKeyPath; + NSString *trailingKey; + NSString *collectionOperationName = get_collection_operation_name_from_key_path(keyPath, &leadingKeyPath, &trailingKey); + + ColumnReference linkColumn = column_reference_from_key_path(desc, leadingKeyPath, true); + util::Optional column; + if (trailingKey) { + RLMPrecondition([trailingKey rangeOfString:@"."].location == NSNotFound, @"Invalid key path", + @"Right side of collection operator may only have a single level key"); + NSString *fullKeyPath = [leadingKeyPath stringByAppendingFormat:@".%@", trailingKey]; + column = column_reference_from_key_path(desc, fullKeyPath, true); + } + + return {collectionOperationName, std::move(linkColumn), std::move(column)}; +} + +void QueryBuilder::apply_collection_operator_expression(RLMObjectSchema *desc, + NSString *keyPath, id value, + NSComparisonPredicate *pred) { + CollectionOperation operation = collection_operation_from_key_path(desc, keyPath); + operation.validate_comparison(value); + + if (pred.leftExpression.expressionType == NSKeyPathExpressionType) { + add_collection_operation_constraint(pred.predicateOperatorType, operation, operation, value); + } else { + add_collection_operation_constraint(pred.predicateOperatorType, operation, value, operation); + } +} + +void QueryBuilder::apply_value_expression(RLMObjectSchema *desc, + NSString *keyPath, id value, + NSComparisonPredicate *pred) +{ + if (key_path_contains_collection_operator(keyPath)) { + apply_collection_operator_expression(desc, keyPath, value, pred); + return; + } + + bool isAny = pred.comparisonPredicateModifier == NSAnyPredicateModifier; + ColumnReference column = column_reference_from_key_path(desc, keyPath, isAny); + + // check to see if this is a between query + if (pred.predicateOperatorType == NSBetweenPredicateOperatorType) { + add_between_constraint(std::move(column), value); + return; + } + + // turn "key.path IN collection" into ored together ==. "collection IN key.path" is handled elsewhere. + if (pred.predicateOperatorType == NSInPredicateOperatorType) { + process_or_group(m_query, value, [&](id item) { + id normalized = value_from_constant_expression_or_value(item); + validate_property_value(column, normalized, + @"Expected object of type %@ in IN clause for property '%@' on object of type '%@', but received: %@", desc, keyPath); + add_constraint(column.type(), NSEqualToPredicateOperatorType, pred.options, column, normalized); + }); + return; + } + + validate_property_value(column, value, @"Expected object of type %@ for property '%@' on object of type '%@', but received: %@", desc, keyPath); + if (pred.leftExpression.expressionType == NSKeyPathExpressionType) { + add_constraint(column.type(), pred.predicateOperatorType, pred.options, std::move(column), value); + } else { + add_constraint(column.type(), pred.predicateOperatorType, pred.options, value, std::move(column)); + } +} + +void QueryBuilder::apply_column_expression(RLMObjectSchema *desc, + NSString *leftKeyPath, NSString *rightKeyPath, + NSComparisonPredicate *predicate) +{ + bool left_key_path_contains_collection_operator = key_path_contains_collection_operator(leftKeyPath); + bool right_key_path_contains_collection_operator = key_path_contains_collection_operator(rightKeyPath); + if (left_key_path_contains_collection_operator && right_key_path_contains_collection_operator) { + @throw RLMPredicateException(@"Unsupported predicate", @"Key paths including aggregate operations cannot be compared with other aggregate operations."); + } + + if (left_key_path_contains_collection_operator) { + CollectionOperation left = collection_operation_from_key_path(desc, leftKeyPath); + ColumnReference right = column_reference_from_key_path(desc, rightKeyPath, false); + left.validate_comparison(right); + add_collection_operation_constraint(predicate.predicateOperatorType, left, left, std::move(right)); + return; + } + if (right_key_path_contains_collection_operator) { + ColumnReference left = column_reference_from_key_path(desc, leftKeyPath, false); + CollectionOperation right = collection_operation_from_key_path(desc, rightKeyPath); + right.validate_comparison(left); + add_collection_operation_constraint(predicate.predicateOperatorType, right, std::move(left), right); + return; + } + + bool isAny = false; + ColumnReference left = column_reference_from_key_path(desc, leftKeyPath, isAny); + ColumnReference right = column_reference_from_key_path(desc, rightKeyPath, isAny); + + // NOTE: It's assumed that column type must match and no automatic type conversion is supported. + RLMPrecondition(left.type() == right.type(), + RLMPropertiesComparisonTypeMismatchException, + RLMPropertiesComparisonTypeMismatchReason, + RLMTypeToString(left.type()), + RLMTypeToString(right.type())); + + // TODO: Should we handle special case where left row is the same as right row (tautology) + add_constraint(left.type(), predicate.predicateOperatorType, predicate.options, + std::move(left), std::move(right)); +} + +// Identify expressions of the form [SELF valueForKeyPath:] +bool is_self_value_for_key_path_function_expression(NSExpression *expression) +{ + if (expression.expressionType != NSFunctionExpressionType) + return false; + + if (expression.operand.expressionType != NSEvaluatedObjectExpressionType) + return false; + + return [expression.function isEqualToString:@"valueForKeyPath:"]; +} + +// -[NSPredicate predicateWithSubtitutionVariables:] results in function expressions of the form [SELF valueForKeyPath:] +// that apply_predicate cannot handle. Replace such expressions with equivalent NSKeyPathExpressionType expressions. +NSExpression *simplify_self_value_for_key_path_function_expression(NSExpression *expression) { + if (is_self_value_for_key_path_function_expression(expression)) { + if (NSString *keyPath = [expression.arguments.firstObject keyPath]) { + return [NSExpression expressionForKeyPath:keyPath]; + } + } + return expression; +} + +void QueryBuilder::apply_subquery_count_expression(RLMObjectSchema *objectSchema, + NSExpression *subqueryExpression, NSPredicateOperatorType operatorType, NSExpression *right) { + if (right.expressionType != NSConstantValueExpressionType || ![right.constantValue isKindOfClass:[NSNumber class]]) { + @throw RLMPredicateException(@"Invalid predicate expression", @"SUBQUERY(…).@count is only supported when compared with a constant number."); + } + int64_t value = [right.constantValue integerValue]; + + ColumnReference collectionColumn = column_reference_from_key_path(objectSchema, [subqueryExpression.collection keyPath], true); + RLMObjectSchema *collectionMemberObjectSchema = m_schema[collectionColumn.property().objectClassName]; + + // Eliminate references to the iteration variable in the subquery. + NSPredicate *subqueryPredicate = [subqueryExpression.predicate predicateWithSubstitutionVariables:@{ subqueryExpression.variable : [NSExpression expressionForEvaluatedObject] }]; + subqueryPredicate = transformPredicate(subqueryPredicate, simplify_self_value_for_key_path_function_expression); + + Query subquery = RLMPredicateToQuery(subqueryPredicate, collectionMemberObjectSchema, m_schema, m_group); + add_numeric_constraint(RLMPropertyTypeInt, operatorType, + collectionColumn.resolve(std::move(subquery)).count(), value); +} + +void QueryBuilder::apply_function_subquery_expression(RLMObjectSchema *objectSchema, NSExpression *functionExpression, + NSPredicateOperatorType operatorType, NSExpression *right) { + if (![functionExpression.function isEqualToString:@"valueForKeyPath:"] || functionExpression.arguments.count != 1) { + @throw RLMPredicateException(@"Invalid predicate", @"The '%@' function is not supported on the result of a SUBQUERY.", functionExpression.function); + } + + NSExpression *keyPathExpression = functionExpression.arguments.firstObject; + if ([keyPathExpression.keyPath isEqualToString:@"@count"]) { + apply_subquery_count_expression(objectSchema, functionExpression.operand, operatorType, right); + } else { + @throw RLMPredicateException(@"Invalid predicate", @"SUBQUERY is only supported when immediately followed by .@count that is compared with a constant number."); + } +} + +void QueryBuilder::apply_function_expression(RLMObjectSchema *objectSchema, NSExpression *functionExpression, + NSPredicateOperatorType operatorType, NSExpression *right) { + if (functionExpression.operand.expressionType == NSSubqueryExpressionType) { + apply_function_subquery_expression(objectSchema, functionExpression, operatorType, right); + } else { + @throw RLMPredicateException(@"Invalid predicate", @"The '%@' function is not supported.", functionExpression.function); + } +} + + +void QueryBuilder::apply_predicate(NSPredicate *predicate, RLMObjectSchema *objectSchema) +{ + // Compound predicates. + if ([predicate isMemberOfClass:[NSCompoundPredicate class]]) { + NSCompoundPredicate *comp = (NSCompoundPredicate *)predicate; + + switch ([comp compoundPredicateType]) { + case NSAndPredicateType: + if (comp.subpredicates.count) { + // Add all of the subpredicates. + m_query.group(); + for (NSPredicate *subp in comp.subpredicates) { + apply_predicate(subp, objectSchema); + } + m_query.end_group(); + } else { + // NSCompoundPredicate's documentation states that an AND predicate with no subpredicates evaluates to TRUE. + m_query.and_query(std::unique_ptr(new TrueExpression)); + } + break; + + case NSOrPredicateType: { + // Add all of the subpredicates with ors inbetween. + process_or_group(m_query, comp.subpredicates, [&](__unsafe_unretained NSPredicate *const subp) { + apply_predicate(subp, objectSchema); + }); + break; + } + + case NSNotPredicateType: + // Add the negated subpredicate + m_query.Not(); + apply_predicate(comp.subpredicates.firstObject, objectSchema); + break; + + default: + @throw RLMPredicateException(@"Invalid compound predicate type", + @"Only support AND, OR and NOT predicate types"); + } + } + else if ([predicate isMemberOfClass:[NSComparisonPredicate class]]) { + NSComparisonPredicate *compp = (NSComparisonPredicate *)predicate; + + // check modifier + RLMPrecondition(compp.comparisonPredicateModifier != NSAllPredicateModifier, + @"Invalid predicate", @"ALL modifier not supported"); + + NSExpressionType exp1Type = compp.leftExpression.expressionType; + NSExpressionType exp2Type = compp.rightExpression.expressionType; + + if (compp.comparisonPredicateModifier == NSAnyPredicateModifier) { + // for ANY queries + RLMPrecondition(exp1Type == NSKeyPathExpressionType && exp2Type == NSConstantValueExpressionType, + @"Invalid predicate", + @"Predicate with ANY modifier must compare a KeyPath with RLMArray with a value"); + } + + if (compp.predicateOperatorType == NSBetweenPredicateOperatorType || compp.predicateOperatorType == NSInPredicateOperatorType) { + // Inserting an array via %@ gives NSConstantValueExpressionType, but including it directly gives NSAggregateExpressionType + if (exp1Type == NSKeyPathExpressionType && (exp2Type == NSAggregateExpressionType || exp2Type == NSConstantValueExpressionType)) { + // "key.path IN %@", "key.path IN {…}", "key.path BETWEEN %@", or "key.path BETWEEN {…}". + exp2Type = NSConstantValueExpressionType; + } + else if (compp.predicateOperatorType == NSInPredicateOperatorType && exp1Type == NSConstantValueExpressionType && exp2Type == NSKeyPathExpressionType) { + // "%@ IN key.path" is equivalent to "ANY key.path IN %@". Rewrite the former into the latter. + compp = [NSComparisonPredicate predicateWithLeftExpression:compp.rightExpression rightExpression:compp.leftExpression + modifier:NSAnyPredicateModifier type:NSEqualToPredicateOperatorType options:0]; + exp1Type = NSKeyPathExpressionType; + exp2Type = NSConstantValueExpressionType; + } + else { + if (compp.predicateOperatorType == NSBetweenPredicateOperatorType) { + @throw RLMPredicateException(@"Invalid predicate", + @"Predicate with BETWEEN operator must compare a KeyPath with an aggregate with two values"); + } + else if (compp.predicateOperatorType == NSInPredicateOperatorType) { + @throw RLMPredicateException(@"Invalid predicate", + @"Predicate with IN operator must compare a KeyPath with an aggregate"); + } + } + } + + if (exp1Type == NSKeyPathExpressionType && exp2Type == NSKeyPathExpressionType) { + // both expression are KeyPaths + apply_column_expression(objectSchema, compp.leftExpression.keyPath, compp.rightExpression.keyPath, compp); + } + else if (exp1Type == NSKeyPathExpressionType && exp2Type == NSConstantValueExpressionType) { + // comparing keypath to value + apply_value_expression(objectSchema, compp.leftExpression.keyPath, compp.rightExpression.constantValue, compp); + } + else if (exp1Type == NSConstantValueExpressionType && exp2Type == NSKeyPathExpressionType) { + // comparing value to keypath + apply_value_expression(objectSchema, compp.rightExpression.keyPath, compp.leftExpression.constantValue, compp); + } + else if (exp1Type == NSFunctionExpressionType) { + apply_function_expression(objectSchema, compp.leftExpression, compp.predicateOperatorType, compp.rightExpression); + } + else if (exp1Type == NSSubqueryExpressionType) { + // The subquery expressions that we support are handled by the NSFunctionExpressionType case above. + @throw RLMPredicateException(@"Invalid predicate expression", @"SUBQUERY is only supported when immediately followed by .@count."); + } + else { + @throw RLMPredicateException(@"Invalid predicate expressions", + @"Predicate expressions must compare a keypath and another keypath or a constant value"); + } + } + else if ([predicate isEqual:[NSPredicate predicateWithValue:YES]]) { + m_query.and_query(std::unique_ptr(new TrueExpression)); + } else if ([predicate isEqual:[NSPredicate predicateWithValue:NO]]) { + m_query.and_query(std::unique_ptr(new FalseExpression)); + } + else { + // invalid predicate type + @throw RLMPredicateException(@"Invalid predicate", + @"Only support compound, comparison, and constant predicates"); + } +} + +size_t RLMValidatedColumnForSort(Table& table, NSString *propName) { + RLMPrecondition([propName rangeOfString:@"."].location == NSNotFound, + @"Invalid sort property", @"Cannot sort on '%@': sorting on key paths is not supported.", propName); + size_t column = table.get_column_index(propName.UTF8String); + RLMPrecondition(column != npos, @"Invalid sort property", + @"Cannot sort on property '%@' on object of type '%s': property not found.", + propName, ObjectStore::object_type_for_table_name(table.get_name()).data()); + + switch (auto type = static_cast(table.get_column_type(column))) { + case RLMPropertyTypeBool: + case RLMPropertyTypeDate: + case RLMPropertyTypeDouble: + case RLMPropertyTypeFloat: + case RLMPropertyTypeInt: + case RLMPropertyTypeString: + break; + + default: + @throw RLMPredicateException(@"Invalid sort property type", + @"Cannot sort on property '%@' on object of type '%s': sorting is only supported on bool, date, double, float, integer, and string properties, but property is of type %@.", + propName, ObjectStore::object_type_for_table_name(table.get_name()).data(), + RLMTypeToString(type)); + } + return column; +} + +} // namespace + +realm::Query RLMPredicateToQuery(NSPredicate *predicate, RLMObjectSchema *objectSchema, + RLMSchema *schema, Group &group) +{ + auto query = get_table(group, objectSchema).where(); + + // passing a nil predicate is a no-op + if (!predicate) { + return query; + } + + @autoreleasepool { + QueryBuilder(query, group, schema).apply_predicate(predicate, objectSchema); + } + + // Test the constructed query in core + std::string validateMessage = query.validate(); + RLMPrecondition(validateMessage.empty(), @"Invalid query", @"%.*s", + (int)validateMessage.size(), validateMessage.c_str()); + return query; +} + +realm::SortDescriptor RLMSortDescriptorFromDescriptors(realm::Table& table, NSArray *descriptors) { + std::vector> columnIndices; + std::vector ascending; + columnIndices.reserve(descriptors.count); + ascending.reserve(descriptors.count); + + for (RLMSortDescriptor *descriptor in descriptors) { + columnIndices.push_back({RLMValidatedColumnForSort(table, descriptor.property)}); + ascending.push_back(descriptor.ascending); + } + + return {table, std::move(columnIndices), std::move(ascending)}; +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMRealm.mm b/SiriKitExample/Pods/Realm/Realm/RLMRealm.mm new file mode 100644 index 0000000..a636760 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMRealm.mm @@ -0,0 +1,689 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMRealm_Private.hpp" + +#import "RLMAnalytics.hpp" +#import "RLMArray_Private.hpp" +#import "RLMRealmConfiguration_Private.hpp" +#import "RLMMigration_Private.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMProperty_Private.h" +#import "RLMObjectStore.h" +#import "RLMObject_Private.h" +#import "RLMObject_Private.hpp" +#import "RLMObservation.hpp" +#import "RLMProperty.h" +#import "RLMQueryUtil.hpp" +#import "RLMRealmUtil.hpp" +#import "RLMSchema_Private.hpp" +#import "RLMUpdateChecker.hpp" +#import "RLMUtil.hpp" + +#include "impl/realm_coordinator.hpp" +#include "object_store.hpp" +#include "schema.hpp" +#include "shared_realm.hpp" + +#include +#include +#include + +using namespace realm; +using util::File; + +@interface RLMRealm () +@property (nonatomic, strong) NSHashTable *notificationHandlers; +- (void)sendNotifications:(RLMNotification)notification; +@end + +void RLMDisableSyncToDisk() { + realm::disable_sync_to_disk(); +} + +// Notification Token +@interface RLMRealmNotificationToken : RLMNotificationToken +@property (nonatomic, strong) RLMRealm *realm; +@property (nonatomic, copy) RLMNotificationBlock block; +@end + +@implementation RLMRealmNotificationToken +- (void)stop { + [_realm verifyThread]; + [_realm.notificationHandlers removeObject:self]; + _realm = nil; + _block = nil; +} + +- (void)dealloc { + if (_realm || _block) { + NSLog(@"RLMNotificationToken released without unregistering a notification. You must hold " + @"on to the RLMNotificationToken returned from addNotificationBlock and call " + @"-[RLMNotificationToken stop] when you no longer wish to receive RLMRealm notifications."); + } +} +@end + +static bool shouldForciblyDisableEncryption() { + static bool disableEncryption = getenv("REALM_DISABLE_ENCRYPTION"); + return disableEncryption; +} + +NSData *RLMRealmValidatedEncryptionKey(NSData *key) { + if (shouldForciblyDisableEncryption()) { + return nil; + } + + if (key) { + if (key.length != 64) { + @throw RLMException(@"Encryption key must be exactly 64 bytes long"); + } +#if TARGET_OS_WATCH + @throw RLMException(@"Cannot open an encrypted Realm on watchOS."); +#endif + } + + return key; +} + +@implementation RLMRealm { + NSHashTable *_collectionEnumerators; +} + ++ (BOOL)isCoreDebug { + return realm::Version::has_feature(realm::feature_Debug); +} + ++ (void)initialize { + static bool initialized; + if (initialized) { + return; + } + initialized = true; + + RLMCheckForUpdates(); + RLMSendAnalytics(); +} + +- (BOOL)isEmpty { + return realm::ObjectStore::is_empty(self.group); +} + +- (void)verifyThread { + _realm->verify_thread(); +} + +- (BOOL)inWriteTransaction { + return _realm->is_in_transaction(); +} + +- (realm::Group &)group { + return _realm->read_group(); +} + +- (BOOL)autorefresh { + return _realm->auto_refresh(); +} + +- (void)setAutorefresh:(BOOL)autorefresh { + _realm->set_auto_refresh(autorefresh); +} + ++ (NSString *)writeableTemporaryPathForFile:(NSString *)fileName { + return [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; +} + ++ (instancetype)defaultRealm { + return [RLMRealm realmWithConfiguration:[RLMRealmConfiguration rawDefaultConfiguration] error:nil]; +} + ++ (instancetype)realmWithURL:(NSURL *)fileURL { + RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration]; + configuration.fileURL = fileURL; + return [RLMRealm realmWithConfiguration:configuration error:nil]; +} +// ARC tries to eliminate calls to autorelease when the value is then immediately +// returned, but this results in significantly different semantics between debug +// and release builds for RLMRealm, so force it to always autorelease. +static id RLMAutorelease(id value) { + // +1 __bridge_retained, -1 CFAutorelease + return value ? (__bridge id)CFAutorelease((__bridge_retained CFTypeRef)value) : nil; +} + +static void RLMRealmSetSchemaAndAlign(RLMRealm *realm, RLMSchema *targetSchema) { + realm.schema = targetSchema; + realm->_info = RLMSchemaInfo(realm, targetSchema, realm->_realm->schema()); +} + ++ (instancetype)realmWithSharedRealm:(SharedRealm)sharedRealm schema:(RLMSchema *)schema { + RLMRealm *realm = [RLMRealm new]; + realm->_realm = sharedRealm; + realm->_dynamic = YES; + RLMRealmSetSchemaAndAlign(realm, schema); + return RLMAutorelease(realm); +} + +REALM_NOINLINE void RLMRealmTranslateException(NSError **error) { + try { + throw; + } + catch (RealmFileException const& ex) { + switch (ex.kind()) { + case RealmFileException::Kind::PermissionDenied: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFilePermissionDenied, ex), error); + break; + case RealmFileException::Kind::IncompatibleLockFile: { + NSString *err = @"Realm file is currently open in another process " + "which cannot share access with this process. All " + "processes sharing a single file must be the same " + "architecture. For sharing files between the Realm " + "Browser and an iOS simulator, this means that you " + "must use a 64-bit simulator."; + RLMSetErrorOrThrow(RLMMakeError(RLMErrorIncompatibleLockFile, + File::PermissionDenied(err.UTF8String, ex.path())), error); + break; + } + case RealmFileException::Kind::NotFound: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFileNotFound, ex), error); + break; + case RealmFileException::Kind::Exists: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFileExists, ex), error); + break; + case RealmFileException::Kind::AccessError: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFileAccess, ex), error); + break; + case RealmFileException::Kind::FormatUpgradeRequired: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFileFormatUpgradeRequired, ex), error); + break; + default: + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFail, ex), error); + break; + } + } + catch (AddressSpaceExhausted const &ex) { + RLMSetErrorOrThrow(RLMMakeError(RLMErrorAddressSpaceExhausted, ex), error); + } + catch (SchemaMismatchException const& ex) { + RLMSetErrorOrThrow(RLMMakeError(RLMErrorSchemaMismatch, ex), error); + } + catch (std::system_error const& ex) { + RLMSetErrorOrThrow(RLMMakeError(ex), error); + } + catch (const std::exception &exp) { + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFail, exp), error); + } +} + ++ (instancetype)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error { + bool dynamic = configuration.dynamic; + bool readOnly = configuration.readOnly; + + { + Realm::Config& config = configuration.config; + + // try to reuse existing realm first + if (config.cache || dynamic) { + if (RLMRealm *realm = RLMGetThreadLocalCachedRealmForPath(config.path)) { + auto const& old_config = realm->_realm->config(); + if (old_config.read_only() != config.read_only()) { + @throw RLMException(@"Realm at path '%s' already opened with different read permissions", config.path.c_str()); + } + if (old_config.in_memory != config.in_memory) { + @throw RLMException(@"Realm at path '%s' already opened with different inMemory settings", config.path.c_str()); + } + if (realm->_dynamic != dynamic) { + @throw RLMException(@"Realm at path '%s' already opened with different dynamic settings", config.path.c_str()); + } + if (old_config.encryption_key != config.encryption_key) { + @throw RLMException(@"Realm at path '%s' already opened with different encryption key", config.path.c_str()); + } + return RLMAutorelease(realm); + } + } + } + + configuration = [configuration copy]; + Realm::Config& config = configuration.config; + + RLMRealm *realm = [RLMRealm new]; + realm->_dynamic = dynamic; + + // protects the realm cache and accessors cache + static std::mutex initLock; + std::lock_guard lock(initLock); + + try { + realm->_realm = Realm::get_shared_realm(config); + } + catch (...) { + RLMRealmTranslateException(error); + return nil; + } + + // if we have a cached realm on another thread, copy without a transaction + if (RLMRealm *cachedRealm = RLMGetAnyCachedRealmForPath(config.path)) { + RLMRealmSetSchemaAndAlign(realm, cachedRealm.schema); + } + else if (dynamic) { + RLMRealmSetSchemaAndAlign(realm, [RLMSchema dynamicSchemaFromObjectStoreSchema:realm->_realm->schema()]); + } + else { + // set/align schema or perform migration if needed + RLMSchema *schema = configuration.customSchema ?: RLMSchema.sharedSchema; + + Realm::MigrationFunction migrationFunction; + auto migrationBlock = configuration.migrationBlock; + if (migrationBlock && configuration.schemaVersion > 0) { + migrationFunction = [=](SharedRealm old_realm, SharedRealm realm, Schema& mutableSchema) { + RLMSchema *oldSchema = [RLMSchema dynamicSchemaFromObjectStoreSchema:old_realm->schema()]; + RLMRealm *oldRealm = [RLMRealm realmWithSharedRealm:old_realm schema:oldSchema]; + + // The destination RLMRealm can't just use the schema from the + // SharedRealm because it doesn't have information about whether or + // not a class was defined in Swift, which effects how new objects + // are created + RLMRealm *newRealm = [RLMRealm realmWithSharedRealm:realm schema:schema.copy]; + + [[[RLMMigration alloc] initWithRealm:newRealm oldRealm:oldRealm schema:mutableSchema] execute:migrationBlock]; + + oldRealm->_realm = nullptr; + newRealm->_realm = nullptr; + }; + } + + try { + realm->_realm->update_schema(schema.objectStoreCopy, config.schema_version, + std::move(migrationFunction)); + } + catch (...) { + RLMRealmTranslateException(error); + return nil; + } + + RLMRealmSetSchemaAndAlign(realm, schema); + RLMRealmCreateAccessors(realm.schema); + + if (!readOnly) { + // initializing the schema started a read transaction, so end it + [realm invalidate]; + } + } + + if (config.cache) { + RLMCacheRealm(config.path, realm); + } + + if (!readOnly) { + realm->_realm->m_binding_context = RLMCreateBindingContext(realm); + } + + return RLMAutorelease(realm); +} + ++ (void)resetRealmState { + RLMClearRealmCache(); + realm::_impl::RealmCoordinator::clear_cache(); + [RLMRealmConfiguration resetRealmConfigurationState]; +} + +- (void)verifyNotificationsAreSupported { + [self verifyThread]; + if (_realm->config().read_only()) { + @throw RLMException(@"Read-only Realms do not change and do not have change notifications"); + } + if (!_realm->can_deliver_notifications()) { + @throw RLMException(@"Can only add notification blocks from within runloops."); + } +} + +- (RLMNotificationToken *)addNotificationBlock:(RLMNotificationBlock)block { + if (!block) { + @throw RLMException(@"The notification block should not be nil"); + } + [self verifyNotificationsAreSupported]; + + _realm->read_group(); + + if (!_notificationHandlers) { + _notificationHandlers = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; + } + + RLMRealmNotificationToken *token = [[RLMRealmNotificationToken alloc] init]; + token.realm = self; + token.block = block; + [_notificationHandlers addObject:token]; + return token; +} + +- (void)sendNotifications:(RLMNotification)notification { + NSAssert(!_realm->config().read_only(), @"Read-only realms do not have notifications"); + + NSUInteger count = _notificationHandlers.count; + if (count == 0) { + return; + } + // call this realms notification blocks + if (count == 1) { + if (auto block = [_notificationHandlers.anyObject block]) { + block(notification, self); + } + } + else { + for (RLMRealmNotificationToken *token in _notificationHandlers.allObjects) { + if (auto block = token.block) { + block(notification, self); + } + } + } +} + +- (RLMRealmConfiguration *)configuration { + RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init]; + configuration.config = _realm->config(); + configuration.dynamic = _dynamic; + configuration.customSchema = _schema; + return configuration; +} + +- (void)beginWriteTransaction { + try { + _realm->begin_transaction(); + } + catch (std::exception &ex) { + @throw RLMException(ex); + } +} + +- (void)commitWriteTransaction { + [self commitWriteTransaction:nil]; +} + +- (BOOL)commitWriteTransaction:(NSError **)outError { + try { + _realm->commit_transaction(); + return YES; + } + catch (...) { + RLMRealmTranslateException(outError); + return NO; + } +} + +- (void)transactionWithBlock:(void(^)(void))block { + [self transactionWithBlock:block error:nil]; +} + +- (BOOL)transactionWithBlock:(void(^)(void))block error:(NSError **)outError { + [self beginWriteTransaction]; + block(); + if (_realm->is_in_transaction()) { + return [self commitWriteTransaction:outError]; + } + return YES; +} + +- (void)cancelWriteTransaction { + try { + _realm->cancel_transaction(); + } + catch (std::exception &ex) { + @throw RLMException(ex); + } +} + +- (void)invalidate { + if (_realm->is_in_transaction()) { + NSLog(@"WARNING: An RLMRealm instance was invalidated during a write " + "transaction and all pending changes have been rolled back."); + } + + [self detachAllEnumerators]; + + for (auto& objectInfo : _info) { + for (RLMObservationInfo *info : objectInfo.second.observedObjects) { + info->willChange(RLMInvalidatedKey); + } + } + + _realm->invalidate(); + + for (auto& objectInfo : _info) { + for (RLMObservationInfo *info : objectInfo.second.observedObjects) { + info->didChange(RLMInvalidatedKey); + } + objectInfo.second.releaseTable(); + } +} + +/** + Replaces all string columns in this Realm with a string enumeration column and compacts the + database file. + + Cannot be called from a write transaction. + + Compaction will not occur if other `RLMRealm` instances exist. + + While compaction is in progress, attempts by other threads or processes to open the database will + wait. + + Be warned that resource requirements for compaction is proportional to the amount of live data in + the database. + + Compaction works by writing the database contents to a temporary database file and then replacing + the database with the temporary one. The name of the temporary file is formed by appending + `.tmp_compaction_space` to the name of the database. + + @return YES if the compaction succeeded. + */ +- (BOOL)compact { + // compact() automatically ends the read transaction, but we need to clean + // up cached state and send invalidated notifications when that happens, so + // explicitly end it first unless we're in a write transaction (in which + // case compact() will throw an exception) + if (!_realm->is_in_transaction()) { + [self invalidate]; + } + + try { + return _realm->compact(); + } + catch (std::exception const& ex) { + @throw RLMException(ex); + } +} + +- (void)dealloc { + if (_realm) { + if (_realm->is_in_transaction()) { + [self cancelWriteTransaction]; + NSLog(@"WARNING: An RLMRealm instance was deallocated during a write transaction and all " + "pending changes have been rolled back. Make sure to retain a reference to the " + "RLMRealm for the duration of the write transaction."); + } + } +} + +- (BOOL)refresh { + return _realm->refresh(); +} + +- (void)addObject:(__unsafe_unretained RLMObject *const)object { + RLMAddObjectToRealm(object, self, false); +} + +- (void)addObjects:(id)array { + for (RLMObject *obj in array) { + if (![obj isKindOfClass:[RLMObject class]]) { + @throw RLMException(@"Cannot insert objects of type %@ with addObjects:. Only RLMObjects are supported.", + NSStringFromClass(obj.class)); + } + [self addObject:obj]; + } +} + +- (void)addOrUpdateObject:(RLMObject *)object { + // verify primary key + if (!object.objectSchema.primaryKeyProperty) { + @throw RLMException(@"'%@' does not have a primary key and can not be updated", object.objectSchema.className); + } + + RLMAddObjectToRealm(object, self, true); +} + +- (void)addOrUpdateObjectsFromArray:(id)array { + for (RLMObject *obj in array) { + [self addOrUpdateObject:obj]; + } +} + +- (void)deleteObject:(RLMObject *)object { + RLMDeleteObjectFromRealm(object, self); +} + +- (void)deleteObjects:(id)array { + if ([array respondsToSelector:@selector(realm)] && [array respondsToSelector:@selector(deleteObjectsFromRealm)]) { + if (self != (RLMRealm *)[array realm]) { + @throw RLMException(@"Can only delete objects from the Realm they belong to."); + } + [array deleteObjectsFromRealm]; + } + else if ([array conformsToProtocol:@protocol(NSFastEnumeration)]) { + for (id obj in array) { + if ([obj isKindOfClass:RLMObjectBase.class]) { + RLMDeleteObjectFromRealm(obj, self); + } + } + } + else { + @throw RLMException(@"Invalid array type - container must be an RLMArray, RLMArray, or NSArray of RLMObjects"); + } +} + +- (void)deleteAllObjects { + RLMDeleteAllObjectsFromRealm(self); +} + +- (RLMResults *)allObjects:(NSString *)objectClassName { + return RLMGetObjects(self, objectClassName, nil); +} + +- (RLMResults *)objects:(NSString *)objectClassName where:(NSString *)predicateFormat, ... { + va_list args; + va_start(args, predicateFormat); + RLMResults *results = [self objects:objectClassName where:predicateFormat args:args]; + va_end(args); + return results; +} + +- (RLMResults *)objects:(NSString *)objectClassName where:(NSString *)predicateFormat args:(va_list)args { + return [self objects:objectClassName withPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]]; +} + +- (RLMResults *)objects:(NSString *)objectClassName withPredicate:(NSPredicate *)predicate { + return RLMGetObjects(self, objectClassName, predicate); +} + +- (RLMObject *)objectWithClassName:(NSString *)className forPrimaryKey:(id)primaryKey { + return RLMGetObject(self, className, primaryKey); +} + ++ (uint64_t)schemaVersionAtURL:(NSURL *)fileURL encryptionKey:(NSData *)key error:(NSError **)error { + try { + RLMRealmConfiguration *config = [[RLMRealmConfiguration alloc] init]; + config.fileURL = fileURL; + config.encryptionKey = RLMRealmValidatedEncryptionKey(key); + + uint64_t version = Realm::get_schema_version(config.config); + if (version == realm::ObjectStore::NotVersioned) { + RLMSetErrorOrThrow([NSError errorWithDomain:RLMErrorDomain code:RLMErrorFail userInfo:@{NSLocalizedDescriptionKey:@"Cannot open an uninitialized realm in read-only mode"}], error); + } + return version; + } + catch (std::exception &exp) { + RLMSetErrorOrThrow(RLMMakeError(RLMErrorFail, exp), error); + return RLMNotVersioned; + } +} + ++ (nullable NSError *)migrateRealm:(RLMRealmConfiguration *)configuration { + // Preserves backwards compatibility + NSError *error; + [self performMigrationForConfiguration:configuration error:&error]; + return error; +} + ++ (BOOL)performMigrationForConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error { + if (RLMGetAnyCachedRealmForPath(configuration.config.path)) { + @throw RLMException(@"Cannot migrate Realms that are already open."); + } + + NSError *localError; // Prevents autorelease + BOOL success; + @autoreleasepool { + success = [RLMRealm realmWithConfiguration:configuration error:&localError] != nil; + } + if (!success && error) { + *error = localError; // Must set outside pool otherwise will free anyway + } + return success; +} + +- (RLMObject *)createObject:(NSString *)className withValue:(id)value { + return (RLMObject *)RLMCreateObjectInRealmWithValue(self, className, value, false); +} + +- (BOOL)writeCopyToURL:(NSURL *)fileURL encryptionKey:(NSData *)key error:(NSError **)error { + key = RLMRealmValidatedEncryptionKey(key); + NSString *path = fileURL.path; + + try { + _realm->write_copy(path.UTF8String, {static_cast(key.bytes), key.length}); + return YES; + } + catch (...) { + __autoreleasing NSError *dummyError; + if (!error) { + error = &dummyError; + } + RLMRealmTranslateException(error); + return NO; + } + + return NO; +} + +- (void)registerEnumerator:(RLMFastEnumerator *)enumerator { + if (!_collectionEnumerators) { + _collectionEnumerators = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; + } + [_collectionEnumerators addObject:enumerator]; + +} + +- (void)unregisterEnumerator:(RLMFastEnumerator *)enumerator { + [_collectionEnumerators removeObject:enumerator]; +} + +- (void)detachAllEnumerators { + for (RLMFastEnumerator *enumerator in _collectionEnumerators) { + [enumerator detach]; + } + _collectionEnumerators = nil; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMRealmConfiguration.mm b/SiriKitExample/Pods/Realm/Realm/RLMRealmConfiguration.mm new file mode 100644 index 0000000..93539b3 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMRealmConfiguration.mm @@ -0,0 +1,295 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMRealmConfiguration_Private.h" + +#import "RLMObjectSchema_Private.hpp" +#import "RLMRealm_Private.h" +#import "RLMSchema_Private.hpp" +#import "RLMUtil.hpp" + +#import "schema.hpp" +#import "shared_realm.hpp" + +static NSString *const c_RLMRealmConfigurationProperties[] = { + @"fileURL", + @"inMemoryIdentifier", + @"encryptionKey", + @"readOnly", + @"schemaVersion", + @"migrationBlock", + @"deleteRealmIfMigrationNeeded", + @"dynamic", + @"customSchema", +}; + +static NSString *const c_defaultRealmFileName = @"default.realm"; +RLMRealmConfiguration *s_defaultConfiguration; + +static NSString *defaultDirectoryForBundleIdentifier(NSString *bundleIdentifier) { +#if TARGET_OS_TV + (void)bundleIdentifier; + // tvOS prohibits writing to the Documents directory, so we use the Library/Caches directory instead. + return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; +#elif TARGET_OS_IPHONE + (void)bundleIdentifier; + // On iOS the Documents directory isn't user-visible, so put files there + return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; +#else + // On OS X it is, so put files in Application Support. If we aren't running + // in a sandbox, put it in a subdirectory based on the bundle identifier + // to avoid accidentally sharing files between applications + NSString *path = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]; + if (![[NSProcessInfo processInfo] environment][@"APP_SANDBOX_CONTAINER_ID"]) { + if (!bundleIdentifier) { + bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; + } + if (!bundleIdentifier) { + bundleIdentifier = [NSBundle mainBundle].executablePath.lastPathComponent; + } + + path = [path stringByAppendingPathComponent:bundleIdentifier]; + + // create directory + [[NSFileManager defaultManager] createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:nil]; + } + return path; +#endif +} + +NSString *RLMRealmPathForFileAndBundleIdentifier(NSString *fileName, NSString *bundleIdentifier) { + return [defaultDirectoryForBundleIdentifier(bundleIdentifier) + stringByAppendingPathComponent:fileName]; +} + +NSString *RLMRealmPathForFile(NSString *fileName) { + static NSString *directory = defaultDirectoryForBundleIdentifier(nil); + return [directory stringByAppendingPathComponent:fileName]; +} + +@implementation RLMRealmConfiguration { + realm::Realm::Config _config; +} + +- (realm::Realm::Config&)config { + return _config; +} + ++ (instancetype)defaultConfiguration { + return [[self rawDefaultConfiguration] copy]; +} + ++ (void)setDefaultConfiguration:(RLMRealmConfiguration *)configuration { + if (!configuration) { + @throw RLMException(@"Cannot set the default configuration to nil."); + } + @synchronized(c_defaultRealmFileName) { + s_defaultConfiguration = [configuration copy]; + } +} + ++ (RLMRealmConfiguration *)rawDefaultConfiguration { + @synchronized(c_defaultRealmFileName) { + if (!s_defaultConfiguration) { + s_defaultConfiguration = [[RLMRealmConfiguration alloc] init]; + } + } + return s_defaultConfiguration; +} + ++ (void)resetRealmConfigurationState { + @synchronized(c_defaultRealmFileName) { + s_defaultConfiguration = nil; + } +} + +- (instancetype)init { + self = [super init]; + if (self) { + static NSURL *defaultRealmURL = [NSURL fileURLWithPath:RLMRealmPathForFile(c_defaultRealmFileName)]; + self.fileURL = defaultRealmURL; + self.schemaVersion = 0; + } + + return self; +} + +- (instancetype)copyWithZone:(NSZone *)zone { + RLMRealmConfiguration *configuration = [[[self class] allocWithZone:zone] init]; + configuration->_config = _config; + configuration->_dynamic = _dynamic; + configuration->_migrationBlock = _migrationBlock; + configuration->_customSchema = _customSchema; + return configuration; +} + +- (NSString *)description { + NSMutableString *string = [NSMutableString stringWithFormat:@"%@ {\n", self.class]; + for (NSString *key : c_RLMRealmConfigurationProperties) { + NSString *description = [[self valueForKey:key] description]; + description = [description stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]; + + [string appendFormat:@"\t%@ = %@;\n", key, description]; + } + return [string stringByAppendingString:@"}"]; +} + +static void RLMNSStringToStdString(std::string &out, NSString *in) { + out.resize([in maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + if (out.empty()) { + return; + } + + NSUInteger size = out.size(); + [in getBytes:&out[0] + maxLength:size + usedLength:&size + encoding:NSUTF8StringEncoding + options:0 range:{0, in.length} remainingRange:nullptr]; + out.resize(size); +} + +- (NSURL *)fileURL { + return _config.in_memory ? nil : [NSURL fileURLWithPath:@(_config.path.c_str())]; +} + +- (void)setFileURL:(NSURL *)fileURL { + NSString *path = fileURL.path; + if (path.length == 0) { + @throw RLMException(@"Realm path must not be empty"); + } + + RLMNSStringToStdString(_config.path, path); + _config.in_memory = false; +} + +- (NSString *)inMemoryIdentifier { + if (!_config.in_memory) { + return nil; + } + return [@(_config.path.c_str()) lastPathComponent]; +} + +- (void)setInMemoryIdentifier:(NSString *)inMemoryIdentifier { + if (inMemoryIdentifier.length == 0) { + @throw RLMException(@"In-memory identifier must not be empty"); + } + + RLMNSStringToStdString(_config.path, [NSTemporaryDirectory() stringByAppendingPathComponent:inMemoryIdentifier]); + _config.in_memory = true; +} + +- (NSData *)encryptionKey { + return _config.encryption_key.empty() ? nil : [NSData dataWithBytes:_config.encryption_key.data() length:_config.encryption_key.size()]; +} + +- (void)setEncryptionKey:(NSData * __nullable)encryptionKey { + if (NSData *key = RLMRealmValidatedEncryptionKey(encryptionKey)) { + auto bytes = static_cast(key.bytes); + _config.encryption_key.assign(bytes, bytes + key.length); + } + else { + _config.encryption_key.clear(); + } +} + +- (BOOL)readOnly { + return _config.read_only(); +} + +- (void)setReadOnly:(BOOL)readOnly { + if (readOnly) { + if (self.deleteRealmIfMigrationNeeded) { + @throw RLMException(@"Cannot set `readOnly` when `deleteRealmIfMigrationNeeded` is set."); + } + _config.schema_mode = realm::SchemaMode::ReadOnly; + } + else if (self.readOnly) { + _config.schema_mode = realm::SchemaMode::Automatic; + } +} + +- (uint64_t)schemaVersion { + return _config.schema_version; +} + +- (void)setSchemaVersion:(uint64_t)schemaVersion { + if (schemaVersion == RLMNotVersioned) { + @throw RLMException(@"Cannot set schema version to %llu (RLMNotVersioned)", RLMNotVersioned); + } + _config.schema_version = schemaVersion; +} + +- (BOOL)deleteRealmIfMigrationNeeded { + return _config.schema_mode == realm::SchemaMode::ResetFile; +} + +- (void)setDeleteRealmIfMigrationNeeded:(BOOL)deleteRealmIfMigrationNeeded { + if (deleteRealmIfMigrationNeeded) { + if (self.readOnly) { + @throw RLMException(@"Cannot set `deleteRealmIfMigrationNeeded` when `readOnly` is set."); + } + _config.schema_mode = realm::SchemaMode::ResetFile; + } + else if (self.deleteRealmIfMigrationNeeded) { + _config.schema_mode = realm::SchemaMode::Automatic; + } +} + +- (NSArray *)objectClasses { + return [_customSchema.objectSchema valueForKeyPath:@"objectClass"]; +} + +- (void)setObjectClasses:(NSArray *)objectClasses { + self.customSchema = [RLMSchema schemaWithObjectClasses:objectClasses]; +} + +- (void)setDynamic:(bool)dynamic { + _dynamic = dynamic; + _config.cache = !dynamic; +} + +- (bool)cache { + return _config.cache; +} + +- (void)setCache:(bool)cache { + _config.cache = cache; +} + +- (bool)disableFormatUpgrade { + return _config.disable_format_upgrade; +} + +- (void)setDisableFormatUpgrade:(bool)disableFormatUpgrade { + _config.disable_format_upgrade = disableFormatUpgrade; +} + +- (realm::SchemaMode)schemaMode { + return _config.schema_mode; +} + +- (void)setSchemaMode:(realm::SchemaMode)mode { + _config.schema_mode = mode; +} + +@end + diff --git a/SiriKitExample/Pods/Realm/Realm/RLMRealmUtil.mm b/SiriKitExample/Pods/Realm/Realm/RLMRealmUtil.mm new file mode 100644 index 0000000..72d1051 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMRealmUtil.mm @@ -0,0 +1,142 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMRealmUtil.hpp" + +#import "RLMObjectSchema_Private.hpp" +#import "RLMObservation.hpp" +#import "RLMRealm_Private.hpp" +#import "RLMUtil.hpp" + +#import +#import + +#import "binding_context.hpp" + +#import +#import +#import +#import +#import +#import + +// Global realm state +static std::mutex s_realmCacheMutex; +static std::map s_realmsPerPath; + +void RLMCacheRealm(std::string const& path, RLMRealm *realm) { + std::lock_guard lock(s_realmCacheMutex); + NSMapTable *realms = s_realmsPerPath[path]; + if (!realms) { + s_realmsPerPath[path] = realms = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsObjectPersonality + valueOptions:NSPointerFunctionsWeakMemory]; + } + [realms setObject:realm forKey:@(pthread_mach_thread_np(pthread_self()))]; +} + +RLMRealm *RLMGetAnyCachedRealmForPath(std::string const& path) { + std::lock_guard lock(s_realmCacheMutex); + return [s_realmsPerPath[path] objectEnumerator].nextObject; +} + +RLMRealm *RLMGetThreadLocalCachedRealmForPath(std::string const& path) { + mach_port_t threadID = pthread_mach_thread_np(pthread_self()); + std::lock_guard lock(s_realmCacheMutex); + return [s_realmsPerPath[path] objectForKey:@(threadID)]; +} + +void RLMClearRealmCache() { + std::lock_guard lock(s_realmCacheMutex); + s_realmsPerPath.clear(); +} + +namespace { +class RLMNotificationHelper : public realm::BindingContext { +public: + RLMNotificationHelper(RLMRealm *realm) : _realm(realm) { } + + bool can_deliver_notifications() const noexcept override { + // The main thread may not be in a run loop yet if we're called from + // something like `applicationDidFinishLaunching:`, but it presumably will + // be in the future + if ([NSThread isMainThread]) { + return true; + } + // Current mode indicates why the current callout from the runloop was made, + // and is null if a runloop callout isn't currently being processed + if (auto mode = CFRunLoopCopyCurrentMode(CFRunLoopGetCurrent())) { + CFRelease(mode); + return true; + } + return false; + } + + void changes_available() override { + @autoreleasepool { + auto realm = _realm; + if (realm && !realm.autorefresh) { + [realm sendNotifications:RLMRealmRefreshRequiredNotification]; + } + } + } + + std::vector get_observed_rows() override { + @autoreleasepool { + if (auto realm = _realm) { + [realm detachAllEnumerators]; + return RLMGetObservedRows(realm->_info); + } + return {}; + } + } + + void will_change(std::vector const& observed, std::vector const& invalidated) override { + @autoreleasepool { + RLMWillChange(observed, invalidated); + } + } + + void did_change(std::vector const& observed, std::vector const& invalidated) override { + try { + @autoreleasepool { + RLMDidChange(observed, invalidated); + [_realm sendNotifications:RLMRealmDidChangeNotification]; + } + } + catch (...) { + // This can only be called during a write transaction if it was + // called due to the transaction beginning, so cancel it to ensure + // exceptions thrown here behave the same as exceptions thrown when + // actually beginning the write + if (_realm.inWriteTransaction) { + [_realm cancelWriteTransaction]; + } + throw; + } + } + +private: + // This is owned by the realm, so it needs to not retain the realm + __weak RLMRealm *const _realm; +}; +} // anonymous namespace + + +std::unique_ptr RLMCreateBindingContext(RLMRealm *realm) { + return std::unique_ptr(new RLMNotificationHelper(realm)); +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMResults.mm b/SiriKitExample/Pods/Realm/Realm/RLMResults.mm new file mode 100644 index 0000000..8aeb6e1 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMResults.mm @@ -0,0 +1,444 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMResults_Private.h" + +#import "RLMArray_Private.hpp" +#import "RLMCollection_Private.hpp" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObject_Private.hpp" +#import "RLMObservation.hpp" +#import "RLMProperty_Private.h" +#import "RLMQueryUtil.hpp" +#import "RLMRealm_Private.hpp" +#import "RLMSchema_Private.h" +#import "RLMUtil.hpp" + +#import "results.hpp" + +#import +#import +#import + +using namespace realm; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincomplete-implementation" +@implementation RLMNotificationToken +@end +#pragma clang diagnostic pop + +// +// RLMResults implementation +// +@implementation RLMResults { + realm::Results _results; + RLMRealm *_realm; + RLMClassInfo *_info; +} + +- (instancetype)initPrivate { + self = [super init]; + return self; +} + +static void assertKeyPathIsNotNested(NSString *keyPath) { + if ([keyPath rangeOfString:@"."].location != NSNotFound) { + @throw RLMException(@"Nested key paths are not supported yet for KVC collection operators."); + } +} + +[[gnu::noinline]] +[[noreturn]] +static void throwError(NSString *aggregateMethod) { + try { + throw; + } + catch (realm::InvalidTransactionException const&) { + @throw RLMException(@"Cannot modify Results outside of a write transaction"); + } + catch (realm::IncorrectThreadException const&) { + @throw RLMException(@"Realm accessed from incorrect thread"); + } + catch (realm::Results::InvalidatedException const&) { + @throw RLMException(@"RLMResults has been invalidated"); + } + catch (realm::Results::DetatchedAccessorException const&) { + @throw RLMException(@"Object has been invalidated"); + } + catch (realm::Results::IncorrectTableException const& e) { + @throw RLMException(@"Object type '%s' does not match RLMResults type '%s'.", + e.actual.data(), e.expected.data()); + } + catch (realm::Results::OutOfBoundsIndexException const& e) { + @throw RLMException(@"Index %zu is out of bounds (must be less than %zu)", + e.requested, e.valid_count); + } + catch (realm::Results::UnsupportedColumnTypeException const& e) { + @throw RLMException(@"%@ is not supported for %@ property '%s'", + aggregateMethod, + RLMTypeToString((RLMPropertyType)e.column_type), + e.column_name.data()); + } +} + +template +static auto translateErrors(Function&& f, NSString *aggregateMethod=nil) { + try { + return f(); + } + catch (...) { + throwError(aggregateMethod); + } +} + ++ (instancetype)resultsWithObjectInfo:(RLMClassInfo&)info + results:(realm::Results)results { + RLMResults *ar = [[self alloc] initPrivate]; + ar->_results = std::move(results); + ar->_realm = info.realm; + ar->_info = &info; + return ar; +} + ++ (instancetype)emptyDetachedResults { + return [[self alloc] initPrivate]; +} + +static inline void RLMResultsValidateInWriteTransaction(__unsafe_unretained RLMResults *const ar) { + ar->_realm->_realm->verify_thread(); + ar->_realm->_realm->verify_in_write(); +} + +- (BOOL)isInvalidated { + return translateErrors([&] { return !_results.is_valid(); }); +} + +- (NSUInteger)count { + return translateErrors([&] { return _results.size(); }); +} + +- (NSString *)objectClassName { + return RLMStringDataToNSString(_results.get_object_type()); +} + +- (RLMObjectSchema *)objectSchema { + return _info->rlmObjectSchema; +} + +- (RLMClassInfo *)objectInfo { + return _info; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state + objects:(__unused __unsafe_unretained id [])buffer + count:(NSUInteger)len { + __autoreleasing RLMFastEnumerator *enumerator; + if (state->state == 0) { + enumerator = [[RLMFastEnumerator alloc] initWithCollection:self objectSchema:*_info]; + state->extra[0] = (long)enumerator; + state->extra[1] = self.count; + } + else { + enumerator = (__bridge id)(void *)state->extra[0]; + } + + return [enumerator countByEnumeratingWithState:state count:len]; +} + +- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat, ... { + va_list args; + va_start(args, predicateFormat); + NSUInteger index = [self indexOfObjectWhere:predicateFormat args:args]; + va_end(args); + return index; +} + +- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat args:(va_list)args { + return [self indexOfObjectWithPredicate:[NSPredicate predicateWithFormat:predicateFormat + arguments:args]]; +} + +- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate { + if (_results.get_mode() == Results::Mode::Empty) { + return NSNotFound; + } + + Query query = translateErrors([&] { return _results.get_query(); }); + query.and_query(RLMPredicateToQuery(predicate, _info->rlmObjectSchema, _realm.schema, _realm.group)); + query.sync_view_if_needed(); + +#if REALM_VER_MAJOR >= 2 + size_t indexInTable; + if (const auto& sort = _results.get_sort()) { + // A sort order is specified so we need to return the first match given that ordering. + TableView table_view = query.find_all(); + table_view.sort(sort); + if (!table_view.size()) { + return NSNotFound; + } + indexInTable = table_view.get_source_ndx(0); + } else { + indexInTable = query.find(); + } + if (indexInTable == realm::not_found) { + return NSNotFound; + } + return RLMConvertNotFound(_results.index_of(indexInTable)); +#else + TableView table_view; + if (const auto& sort = _results.get_sort()) { + // A sort order is specified so we need to return the first match given that ordering. + table_view = query.find_all(); + table_view.sort(sort); + } else { + table_view = query.find_all(0, -1, 1); + } + if (!table_view.size()) { + return NSNotFound; + } + return _results.index_of(table_view.get_source_ndx(0)); +#endif +} + +- (id)objectAtIndex:(NSUInteger)index { + return translateErrors([&] { + return RLMCreateObjectAccessor(_realm, *_info, _results.get(index)); + }); +} + +- (id)firstObject { + auto row = translateErrors([&] { return _results.first(); }); + return row ? RLMCreateObjectAccessor(_realm, *_info, *row) : nil; +} + +- (id)lastObject { + auto row = translateErrors([&] { return _results.last(); }); + return row ? RLMCreateObjectAccessor(_realm, *_info, *row) : nil; +} + +- (NSUInteger)indexOfObject:(RLMObject *)object { + if (!object || (!object->_realm && !object.invalidated)) { + return NSNotFound; + } + + return translateErrors([&] { + return RLMConvertNotFound(_results.index_of(object->_row)); + }); +} + +- (id)valueForKeyPath:(NSString *)keyPath { + if ([keyPath characterAtIndex:0] == '@') { + if ([keyPath isEqualToString:@"@count"]) { + return @(self.count); + } + NSRange operatorRange = [keyPath rangeOfString:@"." options:NSLiteralSearch]; + NSUInteger keyPathLength = keyPath.length; + NSUInteger separatorIndex = operatorRange.location != NSNotFound ? operatorRange.location : keyPathLength; + NSString *operatorName = [keyPath substringWithRange:NSMakeRange(1, separatorIndex - 1)]; + SEL opSelector = NSSelectorFromString([NSString stringWithFormat:@"_%@ForKeyPath:", operatorName]); + BOOL isValidOperator = [self respondsToSelector:opSelector]; + if (!isValidOperator) { + @throw RLMException(@"Unsupported KVC collection operator found in key path '%@'", keyPath); + } + else if (separatorIndex >= keyPathLength - 1) { + @throw RLMException(@"Missing key path for KVC collection operator %@ in key path '%@'", operatorName, keyPath); + } + NSString *operatorKeyPath = [keyPath substringFromIndex:separatorIndex + 1]; + if (isValidOperator) { + return ((id(*)(id, SEL, id))objc_msgSend)(self, opSelector, operatorKeyPath); + } + } + return [super valueForKeyPath:keyPath]; +} + +- (id)valueForKey:(NSString *)key { + return translateErrors([&] { + return RLMCollectionValueForKey(self, key); + }); +} + +- (void)setValue:(id)value forKey:(NSString *)key { + translateErrors([&] { RLMResultsValidateInWriteTransaction(self); }); + RLMCollectionSetValueForKey(self, key, value); +} + +- (NSNumber *)_aggregateForKeyPath:(NSString *)keyPath method:(util::Optional (Results::*)(size_t))method methodName:(NSString *)methodName { + assertKeyPathIsNotNested(keyPath); + return [self aggregate:keyPath method:method methodName:methodName]; +} + +- (NSNumber *)_minForKeyPath:(NSString *)keyPath { + return [self _aggregateForKeyPath:keyPath method:&Results::min methodName:@"@min"]; +} + +- (NSNumber *)_maxForKeyPath:(NSString *)keyPath { + return [self _aggregateForKeyPath:keyPath method:&Results::max methodName:@"@max"]; +} + +- (NSNumber *)_sumForKeyPath:(NSString *)keyPath { + return [self _aggregateForKeyPath:keyPath method:&Results::sum methodName:@"@sum"]; +} + +- (NSNumber *)_avgForKeyPath:(NSString *)keyPath { + return [self _aggregateForKeyPath:keyPath method:&Results::average methodName:@"@avg"]; +} + +- (NSArray *)_unionOfObjectsForKeyPath:(NSString *)keyPath { + assertKeyPathIsNotNested(keyPath); + return translateErrors([&] { + return RLMCollectionValueForKey(self, keyPath); + }); +} + +- (NSArray *)_distinctUnionOfObjectsForKeyPath:(NSString *)keyPath { + return [NSSet setWithArray:[self _unionOfObjectsForKeyPath:keyPath]].allObjects; +} + +- (NSArray *)_unionOfArraysForKeyPath:(NSString *)keyPath { + assertKeyPathIsNotNested(keyPath); + if ([keyPath isEqualToString:@"self"]) { + @throw RLMException(@"self is not a valid key-path for a KVC array collection operator as 'unionOfArrays'."); + } + + return translateErrors([&] { + NSArray *nestedResults = RLMCollectionValueForKey(self, keyPath); + NSMutableArray *flatArray = [NSMutableArray arrayWithCapacity:nestedResults.count]; + for (id array in nestedResults) { + NSArray *nsArray = RLMCollectionValueForKey(array, @"self"); + [flatArray addObjectsFromArray:nsArray]; + } + return flatArray; + }); +} + +- (NSArray *)_distinctUnionOfArraysForKeyPath:(__unused NSString *)keyPath { + return [NSSet setWithArray:[self _unionOfArraysForKeyPath:keyPath]].allObjects; +} + +- (RLMResults *)objectsWhere:(NSString *)predicateFormat, ... { + va_list args; + va_start(args, predicateFormat); + RLMResults *results = [self objectsWhere:predicateFormat args:args]; + va_end(args); + return results; +} + +- (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args { + return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]]; +} + +- (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate { + return translateErrors([&] { + if (_results.get_mode() == Results::Mode::Empty) { + return self; + } + auto query = RLMPredicateToQuery(predicate, _info->rlmObjectSchema, _realm.schema, _realm.group); + return [RLMResults resultsWithObjectInfo:*_info results:_results.filter(std::move(query))]; + }); +} + +- (RLMResults *)sortedResultsUsingProperty:(NSString *)property ascending:(BOOL)ascending { + return [self sortedResultsUsingDescriptors:@[[RLMSortDescriptor sortDescriptorWithProperty:property ascending:ascending]]]; +} + +- (RLMResults *)sortedResultsUsingDescriptors:(NSArray *)properties { + return translateErrors([&] { + if (_results.get_mode() == Results::Mode::Empty) { + return self; + } + + return [RLMResults resultsWithObjectInfo:*_info results:_results.sort(RLMSortDescriptorFromDescriptors(*_info->table(), properties))]; + }); +} + +- (id)objectAtIndexedSubscript:(NSUInteger)index { + return [self objectAtIndex:index]; +} + +- (id)aggregate:(NSString *)property method:(util::Optional (Results::*)(size_t))method methodName:(NSString *)methodName { + size_t column = _info->tableColumn(property); + auto value = translateErrors([&] { return (_results.*method)(column); }, methodName); + if (!value) { + return nil; + } + return RLMMixedToObjc(*value); +} + +- (id)minOfProperty:(NSString *)property { + return [self aggregate:property method:&Results::min methodName:@"minOfProperty"]; +} + +- (id)maxOfProperty:(NSString *)property { + return [self aggregate:property method:&Results::max methodName:@"maxOfProperty"]; +} + +- (id)sumOfProperty:(NSString *)property { + return [self aggregate:property method:&Results::sum methodName:@"sumOfProperty"]; +} + +- (id)averageOfProperty:(NSString *)property { + return [self aggregate:property method:&Results::average methodName:@"averageOfProperty"]; +} + +- (void)deleteObjectsFromRealm { + return translateErrors([&] { + if (_results.get_mode() == Results::Mode::Table) { + RLMResultsValidateInWriteTransaction(self); + RLMClearTable(*self.objectInfo); + } + else { + RLMTrackDeletions(_realm, ^{ _results.clear(); }); + } + }); +} + +- (NSString *)description { + return RLMDescriptionWithMaxDepth(@"RLMResults", self, RLMDescriptionMaxDepth); +} + +- (NSUInteger)indexInSource:(NSUInteger)index { + return translateErrors([&] { return _results.get(index).get_index(); }); +} + +- (realm::TableView)tableView { + return translateErrors([&] { return _results.get_tableview(); }); +} + +// The compiler complains about the method's argument type not matching due to +// it not having the generic type attached, but it doesn't seem to be possible +// to actually include the generic type +// http://www.openradar.me/radar?id=6135653276319744 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmismatched-parameter-types" +- (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMResults *, RLMCollectionChange *, NSError *))block { + [_realm verifyNotificationsAreSupported]; + return RLMAddNotificationBlock(self, _results, block, true); +} +#pragma clang diagnostic pop + +- (BOOL)isAttached +{ + return !!_realm; +} + +@end + +@implementation RLMLinkingObjects +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMSchema.mm b/SiriKitExample/Pods/Realm/Realm/RLMSchema.mm new file mode 100644 index 0000000..a3899bd --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMSchema.mm @@ -0,0 +1,338 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMSchema_Private.h" + +#import "RLMAccessor.h" +#import "RLMObject_Private.hpp" +#import "RLMObjectSchema_Private.hpp" +#import "RLMProperty_Private.h" +#import "RLMRealm_Private.hpp" +#import "RLMSwiftSupport.h" +#import "RLMUtil.hpp" + +#import "object_store.hpp" +#import "schema.hpp" + +#import + +#import +#include + +using namespace realm; + +const uint64_t RLMNotVersioned = realm::ObjectStore::NotVersioned; + +// RLMSchema private properties +@interface RLMSchema () +@property (nonatomic, readwrite) NSMutableDictionary *objectSchemaByName; +@end + +static RLMSchema *s_sharedSchema = [[RLMSchema alloc] init]; +static NSMutableDictionary *s_localNameToClass = [[NSMutableDictionary alloc] init]; +static NSMutableDictionary *s_privateObjectSubclasses = [[NSMutableDictionary alloc] init]; + +static enum class SharedSchemaState { + Uninitialized, + Initializing, + Initialized +} s_sharedSchemaState = SharedSchemaState::Uninitialized; + +@implementation RLMSchema { + NSArray *_objectSchema; + realm::Schema _objectStoreSchema; +} + +// Caller must @synchronize on s_localNameToClass +static RLMObjectSchema *RLMRegisterClass(Class cls) { + if (RLMObjectSchema *schema = s_privateObjectSubclasses[[cls className]]) { + return schema; + } + + auto prevState = s_sharedSchemaState; + s_sharedSchemaState = SharedSchemaState::Initializing; + RLMObjectSchema *schema = [RLMObjectSchema schemaForObjectClass:cls]; + s_sharedSchemaState = prevState; + + // set unmanaged class on shared shema for unmanaged object creation + schema.unmanagedClass = RLMUnmanagedAccessorClassForObjectClass(schema.objectClass, schema); + + // override sharedSchema class methods for performance + RLMReplaceSharedSchemaMethod(cls, schema); + + s_privateObjectSubclasses[schema.className] = schema; + if ([cls shouldIncludeInDefaultSchema] && prevState != SharedSchemaState::Initialized) { + s_sharedSchema.objectSchemaByName[schema.className] = schema; + } + + return schema; +} + +// Caller must @synchronize on s_localNameToClass +static void RLMRegisterClassLocalNames(Class *classes, NSUInteger count) { + for (NSUInteger i = 0; i < count; i++) { + Class cls = classes[i]; + + if (!RLMIsObjectSubclass(cls) || RLMIsGeneratedClass(cls)) { + continue; + } + + NSString *className = NSStringFromClass(cls); + if ([RLMSwiftSupport isSwiftClassName:className]) { + className = [RLMSwiftSupport demangleClassName:className]; + } + // NSStringFromClass demangles the names for top-level Swift classes + // but not for nested classes. _T indicates it's a Swift symbol, t + // indicates it's a type, and C indicates it's a class. + else if ([className hasPrefix:@"_TtC"]) { + @throw RLMException(@"RLMObject subclasses cannot be nested within other declarations. Please move %@ to global scope.", className); + } + + if (Class existingClass = s_localNameToClass[className]) { + if (existingClass != cls) { + @throw RLMException(@"RLMObject subclasses with the same name cannot be included twice in the same target. " + @"Please make sure '%@' is only linked once to your current target.", className); + } + continue; + } + + s_localNameToClass[className] = cls; + RLMReplaceClassNameMethod(cls, className); + } +} + +- (instancetype)init { + self = [super init]; + if (self) { + _objectSchemaByName = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (NSArray *)objectSchema { + if (!_objectSchema) { + _objectSchema = [_objectSchemaByName allValues]; + } + return _objectSchema; +} + +- (void)setObjectSchema:(NSArray *)objectSchema { + _objectSchema = objectSchema; + _objectSchemaByName = [NSMutableDictionary dictionaryWithCapacity:objectSchema.count]; + for (RLMObjectSchema *object in objectSchema) { + [_objectSchemaByName setObject:object forKey:object.className]; + } +} + +- (RLMObjectSchema *)schemaForClassName:(NSString *)className { + if (RLMObjectSchema *schema = _objectSchemaByName[className]) { + return schema; // fast path for already-initialized schemas + } else if (Class cls = [RLMSchema classForString:className]) { + [cls sharedSchema]; // initialize the schema + return _objectSchemaByName[className]; // try again + } else { + return nil; + } +} + +- (RLMObjectSchema *)objectForKeyedSubscript:(__unsafe_unretained NSString *const)className { + RLMObjectSchema *schema = [self schemaForClassName:className]; + if (!schema) { + @throw RLMException(@"Object type '%@' not managed by the Realm", className); + } + return schema; +} + ++ (instancetype)schemaWithObjectClasses:(NSArray *)classes { + NSUInteger count = classes.count; + auto classArray = std::make_unique<__unsafe_unretained Class[]>(count); + [classes getObjects:classArray.get() range:NSMakeRange(0, count)]; + + RLMSchema *schema = [[self alloc] init]; + @synchronized(s_localNameToClass) { + RLMRegisterClassLocalNames(classArray.get(), count); + + schema->_objectSchemaByName = [NSMutableDictionary dictionaryWithCapacity:count]; + for (Class cls in classes) { + if (!RLMIsObjectSubclass(cls)) { + @throw RLMException(@"Can't add non-Object type '%@' to a schema.", cls); + } + schema->_objectSchemaByName[[cls className]] = RLMRegisterClass(cls); + } + } + + NSMutableArray *errors = [NSMutableArray new]; + // Verify that all of the targets of links are included in the class list + [schema->_objectSchemaByName enumerateKeysAndObjectsUsingBlock:^(id, RLMObjectSchema *objectSchema, BOOL *) { + for (RLMProperty *prop in objectSchema.properties) { + if (prop.type != RLMPropertyTypeObject && prop.type != RLMPropertyTypeArray) { + continue; + } + if (!schema->_objectSchemaByName[prop.objectClassName]) { + [errors addObject:[NSString stringWithFormat:@"- '%@.%@' links to class '%@', which is missing from the list of classes managed by the Realm", objectSchema.className, prop.name, prop.objectClassName]]; + } + } + }]; + if (errors.count) { + @throw RLMException(@"Invalid class subset list:\n%@", [errors componentsJoinedByString:@"\n"]); + } + + return schema; +} + ++ (RLMObjectSchema *)sharedSchemaForClass:(Class)cls { + @synchronized(s_localNameToClass) { + // We create instances of Swift objects during schema init, and they + // obviously need to not also try to initialize the schema + if (s_sharedSchemaState == SharedSchemaState::Initializing) { + return nil; + } + + RLMRegisterClassLocalNames(&cls, 1); + return RLMRegisterClass(cls); + } +} + ++ (instancetype)partialSharedSchema { + return s_sharedSchema; +} + +// schema based on runtime objects ++ (instancetype)sharedSchema { + @synchronized(s_localNameToClass) { + // We replace this method with one which just returns s_sharedSchema + // once initialization is complete, but we still need to check if it's + // already complete because it may have been done by another thread + // while we were waiting for the lock + if (s_sharedSchemaState == SharedSchemaState::Initialized) { + return s_sharedSchema; + } + + if (s_sharedSchemaState == SharedSchemaState::Initializing) { + @throw RLMException(@"Illegal recursive call of +[%@ %@]. Note: Properties of Swift `Object` classes must not be prepopulated with queried results from a Realm.", self, NSStringFromSelector(_cmd)); + } + + s_sharedSchemaState = SharedSchemaState::Initializing; + try { + // Make sure we've discovered all classes + { + unsigned int numClasses; + using malloc_ptr = std::unique_ptr<__unsafe_unretained Class[], decltype(&free)>; + malloc_ptr classes(objc_copyClassList(&numClasses), &free); + RLMRegisterClassLocalNames(classes.get(), numClasses); + } + + [s_localNameToClass enumerateKeysAndObjectsUsingBlock:^(NSString *, Class cls, BOOL *) { + RLMRegisterClass(cls); + }]; + } + catch (...) { + s_sharedSchemaState = SharedSchemaState::Uninitialized; + throw; + } + + // Replace this method with one that doesn't need to acquire a lock + Class metaClass = objc_getMetaClass(class_getName(self)); + IMP imp = imp_implementationWithBlock(^{ return s_sharedSchema; }); + class_replaceMethod(metaClass, @selector(sharedSchema), imp, "@@:"); + + s_sharedSchemaState = SharedSchemaState::Initialized; + } + + return s_sharedSchema; +} + +// schema based on tables in a realm ++ (instancetype)dynamicSchemaFromObjectStoreSchema:(Schema const&)objectStoreSchema { + // cache descriptors for all subclasses of RLMObject + NSMutableArray *schemaArray = [NSMutableArray arrayWithCapacity:objectStoreSchema.size()]; + for (auto &objectSchema : objectStoreSchema) { + RLMObjectSchema *schema = [RLMObjectSchema objectSchemaForObjectStoreSchema:objectSchema]; + [schemaArray addObject:schema]; + } + + // set class array and mapping + RLMSchema *schema = [RLMSchema new]; + schema.objectSchema = schemaArray; + return schema; +} + ++ (Class)classForString:(NSString *)className { + if (Class cls = s_localNameToClass[className]) { + return cls; + } + + if (Class cls = NSClassFromString(className)) { + return RLMIsObjectSubclass(cls) ? cls : nil; + } + + // className might be the local name of a Swift class we haven't registered + // yet, so scan them all then recheck + { + unsigned int numClasses; + std::unique_ptr<__unsafe_unretained Class[], decltype(&free)> classes(objc_copyClassList(&numClasses), &free); + RLMRegisterClassLocalNames(classes.get(), numClasses); + } + + return s_localNameToClass[className]; +} + +- (id)copyWithZone:(NSZone *)zone { + RLMSchema *schema = [[RLMSchema allocWithZone:zone] init]; + schema->_objectSchemaByName = [[NSMutableDictionary allocWithZone:zone] + initWithDictionary:_objectSchemaByName copyItems:YES]; + return schema; +} + +- (BOOL)isEqualToSchema:(RLMSchema *)schema { + if (_objectSchemaByName.count != schema->_objectSchemaByName.count) { + return NO; + } + __block BOOL matches = YES; + [_objectSchemaByName enumerateKeysAndObjectsUsingBlock:^(NSString *name, RLMObjectSchema *objectSchema, BOOL *stop) { + if (![schema->_objectSchemaByName[name] isEqualToObjectSchema:objectSchema]) { + *stop = YES; + matches = NO; + } + }]; + return matches; +} + +- (NSString *)description { + NSMutableString *objectSchemaString = [NSMutableString string]; + NSArray *sort = @[[NSSortDescriptor sortDescriptorWithKey:@"className" ascending:YES]]; + for (RLMObjectSchema *objectSchema in [self.objectSchema sortedArrayUsingDescriptors:sort]) { + [objectSchemaString appendFormat:@"\t%@\n", + [objectSchema.description stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"]]; + } + return [NSString stringWithFormat:@"Schema {\n%@}", objectSchemaString]; +} + +- (Schema)objectStoreCopy { + if (_objectStoreSchema.size() == 0) { + std::vector schema; + schema.reserve(_objectSchemaByName.count); + [_objectSchemaByName enumerateKeysAndObjectsUsingBlock:[&](NSString *, RLMObjectSchema *objectSchema, BOOL *) { + schema.push_back(objectSchema.objectStoreCopy); + }]; + _objectStoreSchema = std::move(schema); + } + return _objectStoreSchema; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMSwiftSupport.m b/SiriKitExample/Pods/Realm/Realm/RLMSwiftSupport.m new file mode 100644 index 0000000..e16c79e --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMSwiftSupport.m @@ -0,0 +1,31 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMSwiftSupport.h" + +@implementation RLMSwiftSupport + ++ (BOOL)isSwiftClassName:(NSString *)className { + return [className rangeOfString:@"."].location != NSNotFound; +} + ++ (NSString *)demangleClassName:(NSString *)className { + return [className substringFromIndex:[className rangeOfString:@"."].location + 1]; +} + +@end diff --git a/SiriKitExample/Pods/Realm/Realm/RLMUpdateChecker.mm b/SiriKitExample/Pods/Realm/Realm/RLMUpdateChecker.mm new file mode 100644 index 0000000..e282ee8 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMUpdateChecker.mm @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMUpdateChecker.hpp" + +#import "RLMRealm.h" +#import "RLMUtil.hpp" + +#if TARGET_IPHONE_SIMULATOR && !defined(REALM_COCOA_VERSION) +#import "RLMVersion.h" +#endif + +void RLMCheckForUpdates() { +#if TARGET_IPHONE_SIMULATOR + if (getenv("REALM_DISABLE_UPDATE_CHECKER") || RLMIsRunningInPlayground()) { + return; + } + + auto handler = ^(NSData *data, NSURLResponse *response, NSError *error) { + if (error || ((NSHTTPURLResponse *)response).statusCode != 200) { + return; + } + + NSString *latestVersion = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (![REALM_COCOA_VERSION isEqualToString:latestVersion]) { + NSLog(@"Version %@ of Realm is now available: https://github.com/realm/realm-cocoa/blob/v%@/CHANGELOG.md", latestVersion, latestVersion); + } + }; + + NSString *url = [NSString stringWithFormat:@"https://static.realm.io/update/cocoa?%@", REALM_COCOA_VERSION]; + [[NSURLSession.sharedSession dataTaskWithURL:[NSURL URLWithString:url] completionHandler:handler] resume]; +#endif +} diff --git a/SiriKitExample/Pods/Realm/Realm/RLMUtil.mm b/SiriKitExample/Pods/Realm/Realm/RLMUtil.mm new file mode 100644 index 0000000..5b5ab80 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/RLMUtil.mm @@ -0,0 +1,353 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2014 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#import "RLMUtil.hpp" + +#import "RLMArray_Private.hpp" +#import "RLMListBase.h" +#import "RLMObjectSchema_Private.hpp" +#import "RLMObjectStore.h" +#import "RLMObject_Private.hpp" +#import "RLMProperty_Private.h" +#import "RLMSchema_Private.h" +#import "RLMSwiftSupport.h" + +#import "shared_realm.hpp" + +#import +#import + +#include +#include + +#if !defined(REALM_COCOA_VERSION) +#import "RLMVersion.h" +#endif + +static inline bool nsnumber_is_like_integer(__unsafe_unretained NSNumber *const obj) +{ + char data_type = [obj objCType][0]; + return data_type == *@encode(bool) || + data_type == *@encode(char) || + data_type == *@encode(short) || + data_type == *@encode(int) || + data_type == *@encode(long) || + data_type == *@encode(long long) || + data_type == *@encode(unsigned short) || + data_type == *@encode(unsigned int) || + data_type == *@encode(unsigned long) || + data_type == *@encode(unsigned long long); +} + +static inline bool nsnumber_is_like_bool(__unsafe_unretained NSNumber *const obj) +{ + // @encode(BOOL) is 'B' on iOS 64 and 'c' + // objcType is always 'c'. Therefore compare to "c". + if ([obj objCType][0] == 'c') { + return true; + } + + if (nsnumber_is_like_integer(obj)) { + int value = [obj intValue]; + return value == 0 || value == 1; + } + + return false; +} + +static inline bool nsnumber_is_like_float(__unsafe_unretained NSNumber *const obj) +{ + char data_type = [obj objCType][0]; + return data_type == *@encode(float) || + data_type == *@encode(short) || + data_type == *@encode(int) || + data_type == *@encode(long) || + data_type == *@encode(long long) || + data_type == *@encode(unsigned short) || + data_type == *@encode(unsigned int) || + data_type == *@encode(unsigned long) || + data_type == *@encode(unsigned long long) || + // A double is like float if it fits within float bounds + (data_type == *@encode(double) && ABS([obj doubleValue]) <= FLT_MAX); +} + +static inline bool nsnumber_is_like_double(__unsafe_unretained NSNumber *const obj) +{ + char data_type = [obj objCType][0]; + return data_type == *@encode(double) || + data_type == *@encode(float) || + data_type == *@encode(short) || + data_type == *@encode(int) || + data_type == *@encode(long) || + data_type == *@encode(long long) || + data_type == *@encode(unsigned short) || + data_type == *@encode(unsigned int) || + data_type == *@encode(unsigned long) || + data_type == *@encode(unsigned long long); +} + +BOOL RLMIsObjectValidForProperty(__unsafe_unretained id const obj, + __unsafe_unretained RLMProperty *const property) { + if (property.optional && !RLMCoerceToNil(obj)) { + return YES; + } + + switch (property.type) { + case RLMPropertyTypeString: + return [obj isKindOfClass:[NSString class]]; + case RLMPropertyTypeBool: + if ([obj isKindOfClass:[NSNumber class]]) { + return nsnumber_is_like_bool(obj); + } + return NO; + case RLMPropertyTypeDate: + return [obj isKindOfClass:[NSDate class]]; + case RLMPropertyTypeInt: + if (NSNumber *number = RLMDynamicCast(obj)) { + return nsnumber_is_like_integer(number); + } + return NO; + case RLMPropertyTypeFloat: + if (NSNumber *number = RLMDynamicCast(obj)) { + return nsnumber_is_like_float(number); + } + return NO; + case RLMPropertyTypeDouble: + if (NSNumber *number = RLMDynamicCast(obj)) { + return nsnumber_is_like_double(number); + } + return NO; + case RLMPropertyTypeData: + return [obj isKindOfClass:[NSData class]]; + case RLMPropertyTypeAny: + return NO; + case RLMPropertyTypeObject: + case RLMPropertyTypeLinkingObjects: { + // only NSNull, nil, or objects which derive from RLMObject and match the given + // object class are valid + RLMObjectBase *objBase = RLMDynamicCast(obj); + return objBase && [objBase->_objectSchema.className isEqualToString:property.objectClassName]; + } + case RLMPropertyTypeArray: { + if (RLMArray *array = RLMDynamicCast(obj)) { + return [array.objectClassName isEqualToString:property.objectClassName]; + } + if (RLMListBase *list = RLMDynamicCast(obj)) { + return [list._rlmArray.objectClassName isEqualToString:property.objectClassName]; + } + if ([obj conformsToProtocol:@protocol(NSFastEnumeration)]) { + // check each element for compliance + for (id el in (id)obj) { + RLMObjectBase *obj = RLMDynamicCast(el); + if (!obj || ![obj->_objectSchema.className isEqualToString:property.objectClassName]) { + return NO; + } + } + return YES; + } + if (!obj || obj == NSNull.null) { + return YES; + } + return NO; + } + } + @throw RLMException(@"Invalid RLMPropertyType specified"); +} + +NSDictionary *RLMDefaultValuesForObjectSchema(__unsafe_unretained RLMObjectSchema *const objectSchema) { + if (!objectSchema.isSwiftClass) { + return [objectSchema.objectClass defaultPropertyValues]; + } + + NSMutableDictionary *defaults = nil; + if ([objectSchema.objectClass isSubclassOfClass:RLMObject.class]) { + defaults = [NSMutableDictionary dictionaryWithDictionary:[objectSchema.objectClass defaultPropertyValues]]; + } + else { + defaults = [NSMutableDictionary dictionary]; + } + RLMObject *defaultObject = [[objectSchema.objectClass alloc] init]; + for (RLMProperty *prop in objectSchema.properties) { + if (!defaults[prop.name] && defaultObject[prop.name]) { + defaults[prop.name] = defaultObject[prop.name]; + } + } + return defaults; +} + +static NSException *RLMException(NSString *reason, NSDictionary *additionalUserInfo) { + NSMutableDictionary *userInfo = @{RLMRealmVersionKey: REALM_COCOA_VERSION, + RLMRealmCoreVersionKey: @REALM_VERSION}.mutableCopy; + if (additionalUserInfo != nil) { + [userInfo addEntriesFromDictionary:additionalUserInfo]; + } + NSException *e = [NSException exceptionWithName:RLMExceptionName + reason:reason + userInfo:userInfo]; + return e; +} + +NSException *RLMException(NSString *fmt, ...) { + va_list args; + va_start(args, fmt); + NSException *e = RLMException([[NSString alloc] initWithFormat:fmt arguments:args], @{}); + va_end(args); + return e; +} + +NSException *RLMException(std::exception const& exception) { + return RLMException(@"%@", @(exception.what())); +} + +NSError *RLMMakeError(RLMError code, std::exception const& exception) { + return [NSError errorWithDomain:RLMErrorDomain + code:code + userInfo:@{NSLocalizedDescriptionKey: @(exception.what()), + @"Error Code": @(code)}]; +} + +NSError *RLMMakeError(RLMError code, const realm::util::File::AccessError& exception) { + return [NSError errorWithDomain:RLMErrorDomain + code:code + userInfo:@{NSLocalizedDescriptionKey: @(exception.what()), + NSFilePathErrorKey: @(exception.get_path().c_str()), + @"Error Code": @(code)}]; +} + +NSError *RLMMakeError(RLMError code, const realm::RealmFileException& exception) { + NSString *underlying = @(exception.underlying().c_str()); + return [NSError errorWithDomain:RLMErrorDomain + code:code + userInfo:@{NSLocalizedDescriptionKey: @(exception.what()), + NSFilePathErrorKey: @(exception.path().c_str()), + @"Error Code": @(code), + @"Underlying": underlying.length == 0 ? @"n/a" : underlying}]; +} + +NSError *RLMMakeError(std::system_error const& exception) { + BOOL isGenericCategoryError = (exception.code().category() == std::generic_category()); + NSString *category = @(exception.code().category().name()); + NSString *errorDomain = isGenericCategoryError ? NSPOSIXErrorDomain : RLMUnknownSystemErrorDomain; + + return [NSError errorWithDomain:errorDomain + code:exception.code().value() + userInfo:@{NSLocalizedDescriptionKey: @(exception.what()), + @"Error Code": @(exception.code().value()), + @"Category": category}]; +} + +NSError *RLMMakeError(NSException *exception) { + return [NSError errorWithDomain:RLMErrorDomain + code:0 + userInfo:@{NSLocalizedDescriptionKey: exception.reason}]; +} + +void RLMSetErrorOrThrow(NSError *error, NSError **outError) { + if (outError) { + *outError = error; + } + else { + NSString *msg = error.localizedDescription; + if (error.userInfo[NSFilePathErrorKey]) { + msg = [NSString stringWithFormat:@"%@: %@", error.userInfo[NSFilePathErrorKey], error.localizedDescription]; + } + @throw RLMException(msg, @{NSUnderlyingErrorKey: error}); + } +} + +// Determines if class1 descends from class2 +static inline BOOL RLMIsSubclass(Class class1, Class class2) { + class1 = class_getSuperclass(class1); + return RLMIsKindOfClass(class1, class2); +} + +static bool treatFakeObjectAsRLMObject = false; + +void RLMSetTreatFakeObjectAsRLMObject(BOOL flag) { + treatFakeObjectAsRLMObject = flag; +} + +BOOL RLMIsObjectOrSubclass(Class klass) { + if (RLMIsKindOfClass(klass, RLMObjectBase.class)) { + return YES; + } + + if (treatFakeObjectAsRLMObject) { + static Class FakeObjectClass = NSClassFromString(@"FakeObject"); + return RLMIsKindOfClass(klass, FakeObjectClass); + } + return NO; +} + +BOOL RLMIsObjectSubclass(Class klass) { + if (RLMIsSubclass(class_getSuperclass(klass), RLMObjectBase.class)) { + return YES; + } + + if (treatFakeObjectAsRLMObject) { + static Class FakeObjectClass = NSClassFromString(@"FakeObject"); + return RLMIsSubclass(klass, FakeObjectClass); + } + return NO; +} + +BOOL RLMIsDebuggerAttached() +{ + int name[] = { + CTL_KERN, + KERN_PROC, + KERN_PROC_PID, + getpid() + }; + + struct kinfo_proc info; + size_t info_size = sizeof(info); + if (sysctl(name, sizeof(name)/sizeof(name[0]), &info, &info_size, NULL, 0) == -1) { + NSLog(@"sysctl() failed: %s", strerror(errno)); + return false; + } + + return (info.kp_proc.p_flag & P_TRACED) != 0; +} + +BOOL RLMIsRunningInPlayground() { + return [[NSBundle mainBundle].bundleIdentifier hasPrefix:@"com.apple.dt.playground."]; +} + +id RLMMixedToObjc(realm::Mixed const& mixed) { + switch (mixed.get_type()) { + case realm::type_String: + return RLMStringDataToNSString(mixed.get_string()); + case realm::type_Int: + return @(mixed.get_int()); + case realm::type_Float: + return @(mixed.get_float()); + case realm::type_Double: + return @(mixed.get_double()); + case realm::type_Bool: + return @(mixed.get_bool()); + case realm::type_Timestamp: + return RLMTimestampToNSDate(mixed.get_timestamp()); + case realm::type_Binary: + return RLMBinaryDataToNSData(mixed.get_binary()); + case realm::type_Link: + case realm::type_LinkList: + default: + @throw RLMException(@"Invalid data type for RLMPropertyTypeAny property."); + } +} diff --git a/SiriKitExample/Pods/Realm/Realm/module.modulemap b/SiriKitExample/Pods/Realm/Realm/module.modulemap new file mode 100644 index 0000000..54297b8 --- /dev/null +++ b/SiriKitExample/Pods/Realm/Realm/module.modulemap @@ -0,0 +1,27 @@ +framework module Realm { + umbrella header "Realm.h" + + export * + module * { export * } + + explicit module Private { + header "RLMAccessor.h" + header "RLMArray_Private.h" + header "RLMListBase.h" + header "RLMObjectBase_Dynamic.h" + header "RLMObjectSchema_Private.h" + header "RLMObjectStore.h" + header "RLMObject_Private.h" + header "RLMOptionalBase.h" + header "RLMProperty_Private.h" + header "RLMRealmConfiguration_Private.h" + header "RLMRealm_Private.h" + header "RLMResults_Private.h" + header "RLMSchema_Private.h" + } + + explicit module Dynamic { + header "RLMRealm_Dynamic.h" + header "RLMObjectBase_Dynamic.h" + } +} diff --git a/SiriKitExample/Pods/Realm/build.sh b/SiriKitExample/Pods/Realm/build.sh new file mode 100755 index 0000000..4f690b3 --- /dev/null +++ b/SiriKitExample/Pods/Realm/build.sh @@ -0,0 +1,1261 @@ +#!/bin/sh + +################################################################################## +# Custom build tool for Realm Objective-C binding. +# +# (C) Copyright 2011-2015 by realm.io. +################################################################################## + +# Warning: pipefail is not a POSIX compatible option, but on OS X it works just fine. +# OS X uses a POSIX complain version of bash as /bin/sh, but apparently it does +# not strip away this feature. Also, this will fail if somebody forces the script +# to be run with zsh. +set -o pipefail +set -e + +# You can override the version of the core library +: ${REALM_CORE_VERSION:=1.5.0} # set to "current" to always use the current build + +# You can override the xcmode used +: ${XCMODE:=xcodebuild} # must be one of: xcodebuild (default), xcpretty, xctool + +# Provide a fallback value for TMPDIR, relevant for Xcode Bots +: ${TMPDIR:=$(getconf DARWIN_USER_TEMP_DIR)} + +PATH=/usr/libexec:$PATH + +if ! [ -z "${JENKINS_HOME}" ]; then + XCPRETTY_PARAMS="--no-utf --report junit --output build/reports/junit.xml" + CODESIGN_PARAMS="CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO" +fi + +export REALM_SKIP_DEBUGGER_CHECKS=YES + +usage() { +cat <&1 >/dev/null) + if [[ $? -ne 0 ]]; then + echo "Downloading core failed:\n${ERROR}" + exit 1 + fi + set -e # re-enable flag + mv "${CORE_TMP_TAR}" "${CORE_TAR}" + fi + + ( + cd "${TMP_DIR}" + rm -rf core + tar xf "${CORE_TAR}" --xz + mv core core-${REALM_CORE_VERSION} + ) + + rm -rf core-${REALM_CORE_VERSION} core + mv ${TMP_DIR}/core-${REALM_CORE_VERSION} . + ln -s core-${REALM_CORE_VERSION} core +} + +COMMAND="$1" + +# Use Debug config if command ends with -debug, otherwise default to Release +case "$COMMAND" in + *-debug) + COMMAND="${COMMAND%-debug}" + CONFIGURATION="Debug" + ;; + *) CONFIGURATION=${CONFIGURATION:-Release} +esac +export CONFIGURATION + +source "$(dirname "$0")/scripts/swift-version.sh" + +case "$COMMAND" in + + ###################################### + # Clean + ###################################### + "clean") + find . -type d -name build -exec rm -r "{}" +\; + exit 0 + ;; + + ###################################### + # Core + ###################################### + "download-core") + if [ "$REALM_CORE_VERSION" = "current" ]; then + echo "Using version of core already in core/ directory" + exit 0 + fi + if [ -d core -a -d ../realm-core -a ! -L core ]; then + # Allow newer versions than expected for local builds as testing + # with unreleased versions is one of the reasons to use a local build + if ! $(grep -i "${REALM_CORE_VERSION} Release notes" core/release_notes.txt >/dev/null); then + echo "Local build of core is out of date." + exit 1 + else + echo "The core library seems to be up to date." + fi + elif ! [ -L core ]; then + echo "core is not a symlink. Deleting..." + rm -rf core + download_core + # With a prebuilt version we only want to check the first non-empty + # line so that checking out an older commit will download the + # appropriate version of core if the already-present version is too new + elif ! $(grep -m 1 . core/release_notes.txt | grep -i "${REALM_CORE_VERSION} RELEASE NOTES" >/dev/null); then + download_core + else + echo "The core library seems to be up to date." + fi + exit 0 + ;; + + ###################################### + # Swift versioning + ###################################### + "set-swift-version") + version="$2" + if [[ -z "$version" ]]; then + version="$REALM_SWIFT_VERSION" + fi + + SWIFT_VERSION_FILE="RealmSwift/SwiftVersion.swift" + CONTENTS="let swiftLanguageVersion = \"$version\"" + if [ ! -f "$SWIFT_VERSION_FILE" ] || ! grep -q "$CONTENTS" "$SWIFT_VERSION_FILE"; then + echo "$CONTENTS" > "$SWIFT_VERSION_FILE" + fi + + exit 0 + ;; + + "prelaunch-simulator") + sh $(dirname $0)/scripts/reset-simulators.sh + ;; + + ###################################### + # Building + ###################################### + "build") + sh build.sh ios-static + sh build.sh ios-dynamic + sh build.sh ios-swift + sh build.sh watchos + sh build.sh watchos-swift + sh build.sh tvos + sh build.sh tvos-swift + sh build.sh osx + sh build.sh osx-swift + exit 0 + ;; + + "ios-static") + build_combined 'Realm iOS static' Realm iphoneos iphonesimulator "-static" + exit 0 + ;; + + "ios-dynamic") + build_combined Realm Realm iphoneos iphonesimulator + exit 0 + ;; + + "ios-swift") + sh build.sh ios-dynamic + build_combined RealmSwift RealmSwift iphoneos iphonesimulator '' "/swift-$REALM_SWIFT_VERSION" + cp -R build/ios/Realm.framework build/ios/swift-$REALM_SWIFT_VERSION + exit 0 + ;; + + "watchos") + build_combined Realm Realm watchos watchsimulator + exit 0 + ;; + + "watchos-swift") + sh build.sh watchos + build_combined RealmSwift RealmSwift watchos watchsimulator '' "/swift-$REALM_SWIFT_VERSION" + cp -R build/watchos/Realm.framework build/watchos/swift-$REALM_SWIFT_VERSION + exit 0 + ;; + + "tvos") + build_combined Realm Realm appletvos appletvsimulator + exit 0 + ;; + + "tvos-swift") + sh build.sh tvos + build_combined RealmSwift RealmSwift appletvos appletvsimulator '' "/swift-$REALM_SWIFT_VERSION" + cp -R build/tvos/Realm.framework build/tvos/swift-$REALM_SWIFT_VERSION + exit 0 + ;; + + "osx") + xc "-scheme Realm -configuration $CONFIGURATION" + clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/Realm.framework" "build/osx" "Realm.framework" + exit 0 + ;; + + "osx-swift") + sh build.sh osx + xc "-scheme 'RealmSwift' -configuration $CONFIGURATION build" + destination="build/osx/swift-$REALM_SWIFT_VERSION" + clean_retrieve "build/DerivedData/Realm/Build/Products/$CONFIGURATION/RealmSwift.framework" "$destination" "RealmSwift.framework" + cp -R build/osx/Realm.framework "$destination" + exit 0 + ;; + + ###################################### + # Analysis + ###################################### + + "analyze-osx") + xc "-scheme Realm -configuration $CONFIGURATION analyze" + exit 0 + ;; + + ###################################### + # Testing + ###################################### + "test") + set +e # Run both sets of tests even if the first fails + failed=0 + sh build.sh test-ios-static || failed=1 + sh build.sh test-ios-dynamic || failed=1 + sh build.sh test-ios-swift || failed=1 + sh build.sh test-ios-devices || failed=1 + sh build.sh test-tvos-devices || failed=1 + sh build.sh test-osx || failed=1 + sh build.sh test-osx-swift || failed=1 + exit $failed + ;; + + "test-all") + set +e + failed=0 + sh build.sh test || failed=1 + sh build.sh test-debug || failed=1 + exit $failed + ;; + + "test-ios-static") + test_ios_static "name=iPhone 6" + exit 0 + ;; + + "test-ios7-static") + test_ios_static "name=iPhone 5S,OS=7.1" + exit 0 + ;; + + "test-ios-dynamic") + xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' build" + xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test 'ARCHS=\$(ARCHS_STANDARD_32_BIT)'" + xc "-scheme Realm -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test" + exit 0 + ;; + + "test-ios-swift") + xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' build" + xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test 'ARCHS=\$(ARCHS_STANDARD_32_BIT)'" + xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk iphonesimulator -destination 'name=iPhone 6' test" + exit 0 + ;; + + "test-ios-devices") + failed=0 + trap "failed=1" ERR + sh build.sh test-ios-devices-objc + sh build.sh test-ios-devices-swift + exit $failed + ;; + + "test-ios-devices-objc") + test_devices iphoneos "Realm iOS static" "$CONFIGURATION" + exit $? + ;; + + "test-ios-devices-swift") + test_devices iphoneos "RealmSwift" "$CONFIGURATION" + exit $? + ;; + + "test-tvos") + xc "-scheme Realm -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=Apple TV 1080p' test" + exit $? + ;; + + "test-tvos-swift") + xc "-scheme RealmSwift -configuration $CONFIGURATION -sdk appletvsimulator -destination 'name=Apple TV 1080p' test" + exit $? + ;; + + "test-tvos-devices") + test_devices appletvos TestHost "$CONFIGURATION" + ;; + + "test-osx") + COVERAGE_PARAMS="" + if [[ "$CONFIGURATION" == "Debug" ]]; then + COVERAGE_PARAMS="GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES" + fi + xc "-scheme Realm -configuration $CONFIGURATION test $COVERAGE_PARAMS" + exit 0 + ;; + + "test-osx-swift") + xc "-scheme RealmSwift -configuration $CONFIGURATION test" + exit 0 + ;; + + ###################################### + # Full verification + ###################################### + "verify") + sh build.sh verify-cocoapods + sh build.sh verify-docs + sh build.sh verify-osx + sh build.sh verify-osx-debug + sh build.sh verify-osx-swift + sh build.sh verify-osx-swift-debug + sh build.sh verify-ios-static + sh build.sh verify-ios-static-debug + sh build.sh verify-ios7-static + sh build.sh verify-ios7-static-debug + sh build.sh verify-ios-dynamic + sh build.sh verify-ios-dynamic-debug + sh build.sh verify-ios-swift + sh build.sh verify-ios-swift-debug + sh build.sh verify-ios-device-objc + sh build.sh verify-ios-device-swift + sh build.sh verify-watchos + sh build.sh verify-tvos + sh build.sh verify-tvos-debug + sh build.sh verify-tvos-device + sh build.sh verify-swiftlint + ;; + + "verify-cocoapods") + if [[ -d .git ]]; then + # Verify the current branch, unless one was already specified in the sha environment variable. + if [[ -z $sha ]]; then + export sha=$(git rev-parse --abbrev-ref HEAD) + fi + + if [[ $(git log -1 @{push}..) != "" ]] || ! git diff-index --quiet HEAD; then + echo "WARNING: verify-cocoapods will test the latest revision of $sha found on GitHub." + echo " Any unpushed local changes will not be tested." + echo "" + sleep 1 + fi + fi + + cd examples/installation + sh build.sh test-ios-objc-cocoapods + sh build.sh test-ios-objc-cocoapods-dynamic + sh build.sh test-ios-swift-cocoapods + sh build.sh test-osx-objc-cocoapods + sh build.sh test-osx-swift-cocoapods + sh build.sh test-watchos-objc-cocoapods + sh build.sh test-watchos-swift-cocoapods + ;; + + "verify-osx-encryption") + REALM_ENCRYPT_ALL=YES sh build.sh test-osx + exit 0 + ;; + + "verify-osx") + sh build.sh test-osx + sh build.sh analyze-osx + sh build.sh examples-osx + + ( + cd examples/osx/objc/build/DerivedData/RealmExamples/Build/Products/$CONFIGURATION + DYLD_FRAMEWORK_PATH=. ./JSONImport >/dev/null + ) + exit 0 + ;; + + "verify-osx-swift") + sh build.sh test-osx-swift + exit 0 + ;; + + "verify-ios-static") + sh build.sh test-ios-static + sh build.sh examples-ios + ;; + + "verify-ios7-static") + sh build.sh test-ios7-static + ;; + + "verify-ios-dynamic") + sh build.sh test-ios-dynamic + ;; + + "verify-ios-swift") + sh build.sh test-ios-swift + sh build.sh examples-ios-swift + ;; + + "verify-ios-device-objc") + sh build.sh test-ios-devices-objc + exit 0 + ;; + + "verify-ios-device-swift") + sh build.sh test-ios-devices-swift + exit 0 + ;; + + "verify-docs") + sh build.sh docs + for lang in swift objc; do + undocumented="docs/${lang}_output/undocumented.json" + if ruby -rjson -e "j = JSON.parse(File.read('docs/${lang}_output/undocumented.json')); exit j['warnings'].length != 0"; then + echo "Undocumented Realm $lang declarations:" + cat "$undocumented" + exit 1 + fi + done + exit 0 + ;; + + "verify-watchos") + sh build.sh watchos-swift + exit 0 + ;; + + "verify-tvos") + sh build.sh test-tvos + sh build.sh test-tvos-swift + sh build.sh examples-tvos + sh build.sh examples-tvos-swift + exit 0 + ;; + + "verify-tvos-device") + sh build.sh test-tvos-devices + exit 0 + ;; + + "verify-swiftlint") + swiftlint lint --strict + exit 0 + ;; + + ###################################### + # Docs + ###################################### + "docs") + build_docs objc + build_docs swift + exit 0 + ;; + + ###################################### + # Examples + ###################################### + "examples") + sh build.sh clean + sh build.sh examples-ios + sh build.sh examples-ios-swift + sh build.sh examples-osx + sh build.sh examples-tvos + sh build.sh examples-tvos-swift + exit 0 + ;; + + "examples-ios") + sh build.sh prelaunch-simulator + workspace="examples/ios/objc/RealmExamples.xcworkspace" + pod install --project-directory="$workspace/.." --no-repo-update + xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme RACTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + + if [ ! -z "${JENKINS_HOME}" ]; then + xc "-workspace $workspace -scheme Extension -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + fi + + exit 0 + ;; + + "examples-ios-swift") + if [ "$REALM_SWIFT_VERSION" == "2.3" ]; then # Skip Swift 2.3 examples for now. + exit 0 + fi + sh build.sh prelaunch-simulator + workspace="examples/ios/swift-$REALM_SWIFT_VERSION/RealmExamples.xcworkspace" + xc "-workspace $workspace -scheme Simple -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme TableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Migration -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Encryption -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme Backlink -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme GroupedTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + if [ "$REALM_SWIFT_VERSION" == "2.2" ]; then # Only Swift 2.2 has the ReactKitTableView example + pod install --project-directory="$workspace/.." --no-repo-update + xc "-workspace $workspace -scheme ReactKitTableView -configuration $CONFIGURATION -destination 'name=iPhone 6' build ${CODESIGN_PARAMS}" + fi + exit 0 + ;; + + "examples-osx") + xc "-workspace examples/osx/objc/RealmExamples.xcworkspace -scheme JSONImport -configuration ${CONFIGURATION} build ${CODESIGN_PARAMS}" + ;; + + "examples-tvos") + workspace="examples/tvos/objc/RealmExamples.xcworkspace" + xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=Apple TV 1080p' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=Apple TV 1080p' build ${CODESIGN_PARAMS}" + exit 0 + ;; + + "examples-tvos-swift") + if [ "$REALM_SWIFT_VERSION" == "2.3" ]; then # Skip Swift 2.3 examples for now. + exit 0 + fi + workspace="examples/tvos/swift-$REALM_SWIFT_VERSION/RealmExamples.xcworkspace" + xc "-workspace $workspace -scheme DownloadCache -configuration $CONFIGURATION -destination 'name=Apple TV 1080p' build ${CODESIGN_PARAMS}" + xc "-workspace $workspace -scheme PreloadedData -configuration $CONFIGURATION -destination 'name=Apple TV 1080p' build ${CODESIGN_PARAMS}" + exit 0 + ;; + + ###################################### + # Versioning + ###################################### + "get-version") + version_file="Realm/Realm-Info.plist" + echo "$(PlistBuddy -c "Print :CFBundleVersion" "$version_file")" + exit 0 + ;; + + "set-version") + realm_version="$2" + version_files="Realm/Realm-Info.plist" + + if [ -z "$realm_version" ]; then + echo "You must specify a version." + exit 1 + fi + for version_file in $version_files; do + PlistBuddy -c "Set :CFBundleVersion $realm_version" "$version_file" + PlistBuddy -c "Set :CFBundleShortVersionString $realm_version" "$version_file" + done + exit 0 + ;; + + ###################################### + # Bitcode Detection + ###################################### + + "binary-has-bitcode") + BINARY="$2" + # Although grep has a '-q' flag to prevent logging to stdout, grep + # behaves differently when used, so redirect stdout to /dev/null. + if otool -l "$BINARY" | grep "segname __LLVM" > /dev/null 2>&1; then + exit 0 + fi + # Work around rdar://21826157 by checking for bitcode in thin binaries + + # Get architectures for binary + archs="$(lipo -info "$BINARY" | rev | cut -d ':' -f1 | rev)" + + archs_array=( $archs ) + if [[ ${#archs_array[@]} < 2 ]]; then + exit 1 # Early exit if not a fat binary + fi + + TEMPDIR=$(mktemp -d $TMPDIR/realm-bitcode-check.XXXX) + + for arch in $archs; do + lipo -thin "$arch" "$BINARY" -output "$TEMPDIR/$arch" + if otool -l "$TEMPDIR/$arch" | grep -q "segname __LLVM"; then + exit 0 + fi + done + exit 1 + ;; + + ###################################### + # CocoaPods + ###################################### + "cocoapods-setup") + if [ ! -d core ]; then + sh build.sh download-core + rm core + mv core-* core + fi + + if [[ "$2" != "swift" ]]; then + if [ ! -d Realm/ObjectStore/src ]; then + cat >&2 <&1 | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1 + if [ "$failed" = "1" ] && cat build/build.log | grep -E 'DTXProxyChannel|DTXChannel|out of date and needs to be rebuilt'; then + echo "Known Xcode error detected. Running job again." + failed=0 + sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1 + elif [ "$failed" = "1" ] && tail ~/Library/Logs/CoreSimulator/CoreSimulator.log | grep -E "Operation not supported|Failed to lookup com.apple.coreservices.lsuseractivity.simulatorsupport"; then + echo "Known Xcode error detected. Running job again." + failed=0 + sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1 + fi + if [ "$failed" = "1" ]; then + echo "\n\n***\nbuild/build.log\n***\n\n" && cat build/build.log + echo "\n\n***\nCoreSimulator.log\n***\n\n" && tail -n2000 ~/Library/Logs/CoreSimulator/CoreSimulator.log + exit 1 + fi + fi + + if [ "$target" = "osx" ] && [ "$configuration" = "Debug" ]; then + gcovr -r . -f ".*Realm.*" -e ".*Tests.*" -e ".*core.*" --xml > build/reports/coverage-report.xml + WS=$(pwd | sed "s/\//\\\\\//g") + sed -i ".bak" "s/\./${WS}/" build/reports/coverage-report.xml + fi + ;; + + ###################################### + # Release packaging + ###################################### + + "package-examples") + cd tightdb_objc + ./scripts/package_examples.rb + zip --symlinks -r realm-examples.zip examples -x "examples/installation/*" + ;; + + "package-test-examples") + if ! VERSION=$(echo realm-objc-*.zip | grep -o '\d*\.\d*\.\d*-[a-z]*'); then + VERSION=$(echo realm-objc-*.zip | grep -o '\d*\.\d*\.\d*') + fi + OBJC="realm-objc-${VERSION}" + SWIFT="realm-swift-${VERSION}" + unzip ${OBJC}.zip + + cp $0 ${OBJC} + cp -r $(dirname $0)/scripts ${OBJC} + cd ${OBJC} + sh build.sh examples-ios + sh build.sh examples-tvos + sh build.sh examples-osx + cd .. + rm -rf ${OBJC} + + unzip ${SWIFT}.zip + + cp $0 ${SWIFT} + cp -r $(dirname $0)/scripts ${SWIFT} + cd ${SWIFT} + sh build.sh examples-ios-swift + sh build.sh examples-tvos-swift + cd .. + rm -rf ${SWIFT} + ;; + + "package-ios-static") + cd tightdb_objc + + sh build.sh prelaunch-simulator + sh build.sh test-ios-static + sh build.sh ios-static + + cd build/ios-static + zip --symlinks -r realm-framework-ios.zip Realm.framework + ;; + + "package-ios-dynamic") + cd tightdb_objc + + sh build.sh prelaunch-simulator + sh build.sh ios-dynamic + cd build/ios + zip --symlinks -r realm-dynamic-framework-ios.zip Realm.framework + ;; + + "package-osx") + cd tightdb_objc + sh build.sh test-osx + + cd build/DerivedData/Realm/Build/Products/Release + zip --symlinks -r realm-framework-osx.zip Realm.framework + ;; + + "package-ios-swift") + cd tightdb_objc + for version in 2.2 2.3 3.0; do + REALM_SWIFT_VERSION="$version" sh build.sh prelaunch-simulator + REALM_SWIFT_VERSION="$version" sh build.sh ios-swift + done + + cd build/ios + zip --symlinks -r realm-swift-framework-ios.zip swift-2.2 swift-2.3 swift-3.0 + ;; + + "package-osx-swift") + cd tightdb_objc + for version in 2.2 2.3 3.0; do + REALM_SWIFT_VERSION="$version" sh build.sh prelaunch-simulator + REALM_SWIFT_VERSION="$version" sh build.sh osx-swift + done + + cd build/osx + zip --symlinks -r realm-swift-framework-osx.zip swift-2.2 swift-2.3 swift-3.0 + ;; + + "package-watchos") + cd tightdb_objc + sh build.sh watchos + + cd build/watchos + zip --symlinks -r realm-framework-watchos.zip Realm.framework + ;; + + "package-watchos-swift") + cd tightdb_objc + for version in 2.2 2.3 3.0; do + REALM_SWIFT_VERSION="$version" sh build.sh prelaunch-simulator + REALM_SWIFT_VERSION="$version" sh build.sh watchos-swift + done + + cd build/watchos + zip --symlinks -r realm-swift-framework-watchos.zip swift-2.2 swift-2.3 swift-3.0 + ;; + + "package-tvos") + cd tightdb_objc + sh build.sh tvos + + cd build/tvos + zip --symlinks -r realm-framework-tvos.zip Realm.framework + ;; + + "package-tvos-swift") + cd tightdb_objc + for version in 2.2 2.3 3.0; do + REALM_SWIFT_VERSION="$version" sh build.sh prelaunch-simulator + REALM_SWIFT_VERSION="$version" sh build.sh tvos-swift + done + + cd build/tvos + zip --symlinks -r realm-swift-framework-tvos.zip swift-2.2 swift-2.3 swift-3.0 + ;; + + "package-release") + LANG="$2" + TEMPDIR=$(mktemp -d $TMPDIR/realm-release-package-${LANG}.XXXX) + + cd tightdb_objc + VERSION=$(sh build.sh get-version) + cd .. + + FOLDER=${TEMPDIR}/realm-${LANG}-${VERSION} + + mkdir -p ${FOLDER}/osx ${FOLDER}/ios ${FOLDER}/watchos ${FOLDER}/tvos + + if [[ "${LANG}" == "objc" ]]; then + mkdir -p ${FOLDER}/ios/static + mkdir -p ${FOLDER}/ios/dynamic + mkdir -p ${FOLDER}/Swift + + ( + cd ${FOLDER}/osx + unzip ${WORKSPACE}/realm-framework-osx.zip + ) + + ( + cd ${FOLDER}/ios/static + unzip ${WORKSPACE}/realm-framework-ios.zip + ) + + ( + cd ${FOLDER}/ios/dynamic + unzip ${WORKSPACE}/realm-dynamic-framework-ios.zip + ) + + ( + cd ${FOLDER}/watchos + unzip ${WORKSPACE}/realm-framework-watchos.zip + ) + + ( + cd ${FOLDER}/tvos + unzip ${WORKSPACE}/realm-framework-tvos.zip + ) + else + ( + cd ${FOLDER}/osx + unzip ${WORKSPACE}/realm-swift-framework-osx.zip + ) + + ( + cd ${FOLDER}/ios + unzip ${WORKSPACE}/realm-swift-framework-ios.zip + ) + + ( + cd ${FOLDER}/watchos + unzip ${WORKSPACE}/realm-swift-framework-watchos.zip + ) + + ( + cd ${FOLDER}/tvos + unzip ${WORKSPACE}/realm-swift-framework-tvos.zip + ) + fi + + ( + cd ${WORKSPACE}/tightdb_objc + cp -R plugin ${FOLDER} + cp LICENSE ${FOLDER}/LICENSE.txt + if [[ "${LANG}" == "objc" ]]; then + cp Realm/Swift/RLMSupport.swift ${FOLDER}/Swift/ + fi + ) + + ( + cd ${FOLDER} + unzip ${WORKSPACE}/realm-examples.zip + cd examples + if [[ "${LANG}" == "objc" ]]; then + rm -rf ios/swift-* tvos/swift-* + else + rm -rf ios/objc ios/rubymotion osx tvos/objc + fi + ) + + cat > ${FOLDER}/docs.webloc < + + + + URL + https://realm.io/docs/${LANG}/${VERSION} + + +EOF + + ( + cd ${TEMPDIR} + zip --symlinks -r realm-${LANG}-${VERSION}.zip realm-${LANG}-${VERSION} + mv realm-${LANG}-${VERSION}.zip ${WORKSPACE} + ) + ;; + + "test-package-release") + # Generate a release package locally for testing purposes + # Real releases should always be done via Jenkins + if [ -z "${WORKSPACE}" ]; then + echo 'WORKSPACE must be set to a directory to assemble the release in' + exit 1 + fi + if [ -d "${WORKSPACE}" ]; then + echo 'WORKSPACE directory should not already exist' + exit 1 + fi + + REALM_SOURCE="$(pwd)" + mkdir -p "$WORKSPACE" + WORKSPACE="$(cd "$WORKSPACE" && pwd)" + export WORKSPACE + cd $WORKSPACE + git clone --recursive $REALM_SOURCE tightdb_objc + + echo 'Packaging iOS' + sh tightdb_objc/build.sh package-ios-static + cp tightdb_objc/build/ios-static/realm-framework-ios.zip . + sh tightdb_objc/build.sh package-ios-dynamic + cp tightdb_objc/build/ios/realm-dynamic-framework-ios.zip . + sh tightdb_objc/build.sh package-ios-swift + cp tightdb_objc/build/ios/realm-swift-framework-ios.zip . + + echo 'Packaging OS X' + sh tightdb_objc/build.sh package-osx + cp tightdb_objc/build/DerivedData/Realm/Build/Products/Release/realm-framework-osx.zip . + sh tightdb_objc/build.sh package-osx-swift + cp tightdb_objc/build/osx/realm-swift-framework-osx.zip . + + echo 'Packaging watchOS' + sh tightdb_objc/build.sh package-watchos + cp tightdb_objc/build/watchos/realm-framework-watchos.zip . + sh tightdb_objc/build.sh package-watchos-swift + cp tightdb_objc/build/watchos/realm-swift-framework-watchos.zip . + + echo 'Packaging tvOS' + sh tightdb_objc/build.sh package-tvos + cp tightdb_objc/build/tvos/realm-framework-tvos.zip . + sh tightdb_objc/build.sh package-tvos-swift + cp tightdb_objc/build/tvos/realm-swift-framework-tvos.zip . + + echo 'Packaging examples' + sh tightdb_objc/build.sh package-examples + cp tightdb_objc/realm-examples.zip . + + echo 'Building final release packages' + sh tightdb_objc/build.sh package-release objc + sh tightdb_objc/build.sh package-release swift + + echo 'Testing packaged examples' + sh tightdb_objc/build.sh package-test-examples + ;; + + "github-release") + if [ -z "${GITHUB_ACCESS_TOKEN}" ]; then + echo 'GITHUB_ACCESS_TOKEN must be set to create GitHub releases' + exit 1 + fi + ./scripts/github_release.rb + ;; + + "add-empty-changelog") + empty_section=$(cat < CHANGELOG.md + echo >> CHANGELOG.md + echo "$changelog" >> CHANGELOG.md + ;; + + *) + echo "Unknown command '$COMMAND'" + usage + exit 1 + ;; +esac diff --git a/SiriKitExample/Pods/Realm/core/librealm-ios.a b/SiriKitExample/Pods/Realm/core/librealm-ios.a new file mode 100644 index 0000000000000000000000000000000000000000..796dfb144b7dc905eb2b69800e09860bed715ddd GIT binary patch literal 45497424 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 @%X)Rn>jP{ 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

su|cQU;wC=*{19wL- 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

w*+e>d`3jyoT#pS>?bC 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