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 0000000..42526a2
Binary files /dev/null and b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-1.png differ
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 0000000..42526a2
Binary files /dev/null and b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1-2.png differ
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 0000000..42526a2
Binary files /dev/null and b/iMessagesExample/MessagesExtension/Assets.xcassets/poll.imageset/poll-hands1.png differ
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