diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6320170
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## Build generated
+build/
+DerivedData
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+
+## Other
+*.xccheckout
+*.moved-aside
+*.xcuserstate
\ No newline at end of file
diff --git a/AllFeedDatasource.swift b/AllFeedDatasource.swift
new file mode 100644
index 0000000..71c3ac3
--- /dev/null
+++ b/AllFeedDatasource.swift
@@ -0,0 +1,55 @@
+//
+// AllFeedDatasource.swift
+// comblie
+//
+// Created by Cal on 11/16/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class AllFeedDatasource: NSObject, UITableViewDataSource {
+
+ var tableView : UITableView
+ var items : NSMutableArray
+ var parent : UITableViewController
+
+ init(tableView : UITableView, parent : UITableViewController) {
+ self.items = ["a","a", "a","a"]
+ self.parent = parent
+ self.tableView = tableView
+ self.tableView.registerNib(UINib(nibName: "VineFeedCell", bundle: nil), forCellReuseIdentifier: "VineFeed")
+ self.tableView.registerNib(UINib(nibName: "TwitterTweetCell", bundle: nil), forCellReuseIdentifier: "TwitterTweet")
+ self.tableView.registerNib(UINib(nibName: "TumblrPhotoCell", bundle: nil), forCellReuseIdentifier: "TumblrPhoto")
+ self.tableView.registerNib(UINib(nibName: "InstagramFeedCell", bundle: nil), forCellReuseIdentifier: "InstagramFeed")
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.items.count
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ // Configure the cell...
+
+ var cell : UITableViewCell!
+ if (indexPath.row == 1) {
+ cell = tableView.dequeueReusableCellWithIdentifier("VineFeed", forIndexPath: indexPath)
+ } else if (indexPath.row == 0) {
+ let currentCell = tableView.dequeueReusableCellWithIdentifier("TwitterTweet", forIndexPath: indexPath) as! TwitterTweetCellController
+ currentCell.retweetTextHeight.constant = CGFloat(0)
+ currentCell.parent = self.parent
+ cell = currentCell
+ } else if (indexPath.row == 2) {
+ cell = tableView.dequeueReusableCellWithIdentifier("TumblrPhoto", forIndexPath: indexPath)
+ } else if (indexPath.row == 3) {
+ cell = tableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath)
+ }
+ // Configure the cell...
+ return cell
+ }
+}
diff --git a/AllFeedTableViewController.swift b/AllFeedTableViewController.swift
new file mode 100644
index 0000000..16ce4b3
--- /dev/null
+++ b/AllFeedTableViewController.swift
@@ -0,0 +1,82 @@
+//
+// AllFeedTableViewController.swift
+// comblie
+//
+// Created by Cal on 10/24/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class AllFeedTableViewController: UITableViewController {
+
+ var dataSource : AllFeedDatasource!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ dataSource = AllFeedDatasource(tableView: self.tableView, parent: self)
+ self.tableView.dataSource = dataSource
+
+ self.edgesForExtendedLayout = UIRectEdge.None
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
+ self.tableView.rowHeight = UITableViewAutomaticDimension;
+ self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average"
+ self.tableView.allowsSelection = false
+
+ self.tableView.registerNib(UINib(nibName: "VineFeedCell", bundle: nil), forCellReuseIdentifier: "VineFeed")
+ self.tableView.registerNib(UINib(nibName: "TwitterTweetCell", bundle: nil), forCellReuseIdentifier: "TwitterTweet")
+ self.tableView.registerNib(UINib(nibName: "TumblrPhotoCell", bundle: nil), forCellReuseIdentifier: "TumblrPhoto")
+ self.tableView.registerNib(UINib(nibName: "InstagramFeedCell", bundle: nil), forCellReuseIdentifier: "InstagramFeed")
+
+ }
+
+
+
+
+ /*
+ // Override to support conditional editing of the table view.
+ override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the specified item to be editable.
+ return true
+ }
+ */
+
+ /*
+ // Override to support editing the table view.
+ override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
+ if editingStyle == .Delete {
+ // Delete the row from the data source
+ tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
+ } else if editingStyle == .Insert {
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
+ }
+ }
+ */
+
+ /*
+ // Override to support rearranging the table view.
+ override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
+
+ }
+ */
+
+ /*
+ // Override to support conditional rearranging of the table view.
+ override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the item to be re-orderable.
+ return true
+ }
+ */
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/CommentCell.xib b/CommentCell.xib
new file mode 100644
index 0000000..9ba9161
--- /dev/null
+++ b/CommentCell.xib
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+ HelveticaNeue-Roman
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CommentCellController.swift b/CommentCellController.swift
new file mode 100644
index 0000000..b810e5d
--- /dev/null
+++ b/CommentCellController.swift
@@ -0,0 +1,31 @@
+//
+// CommentCellController.swift
+// comblie
+//
+// Created by Cal on 11/8/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class CommentCellController: UITableViewCell {
+
+ @IBOutlet weak var profileImage: UIImageView!
+ @IBOutlet weak var postUsername: UILabel!
+ @IBOutlet weak var postComment: UILabel!
+ @IBOutlet weak var postTime: UILabel!
+
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage.frame.height/2)
+ }
+
+ override func setSelected(selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+
+ // Configure the view for the selected state
+ }
+
+}
diff --git a/CommentsController.swift b/CommentsController.swift
new file mode 100644
index 0000000..b49d268
--- /dev/null
+++ b/CommentsController.swift
@@ -0,0 +1,203 @@
+//
+// CommentsController.swift
+// comblie
+//
+// Created by Cal on 11/7/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class CommentsController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
+
+ //MARK: Properties
+ @IBOutlet weak var topTableView: UITableView!
+ @IBOutlet weak var topTableHeight: NSLayoutConstraint!
+ @IBOutlet weak var tableView: UITableView!
+ @IBOutlet weak var likesText: UILabel!
+ @IBOutlet weak var commentBox: UITextField!
+ @IBOutlet weak var bottomSpacing: NSLayoutConstraint!
+
+ var postHeight : CGFloat!
+ var cell : UITableViewCell!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ //UITableView
+
+ //Set delegate controls and datasource
+ self.tableView.delegate = self
+ self.tableView.dataSource = self
+ self.topTableView.delegate = self
+ self.topTableView.dataSource = self
+
+ //Register XIBs for cell reuse
+ self.topTableView.registerNib(UINib(nibName: "FacebookStatusCell", bundle: nil), forCellReuseIdentifier: "FacebookStatus")
+ self.topTableView.registerNib(UINib(nibName: "TwitterTweetCell", bundle: nil), forCellReuseIdentifier: "TwitterTweet")
+ self.topTableView.registerNib(UINib(nibName: "TwitterPhotoCell", bundle: nil), forCellReuseIdentifier: "TwitterPhoto")
+ self.topTableView.registerNib(UINib(nibName: "TumblrPhotoCell", bundle: nil), forCellReuseIdentifier: "TumblrPhoto")
+ self.topTableView.registerNib(UINib(nibName: "TumblrBlogCell", bundle: nil), forCellReuseIdentifier: "TumblrBlog")
+ self.topTableView.registerNib(UINib(nibName: "InstagramFeedCell", bundle: nil), forCellReuseIdentifier: "InstagramFeed")
+ self.tableView.registerNib(UINib(nibName: "CommentCell", bundle: nil), forCellReuseIdentifier: "Comment")
+
+ //Styles Tableviews and sets autoheight
+ self.tableView.estimatedRowHeight = 44
+ self.tableView.rowHeight = UITableViewAutomaticDimension
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
+
+ self.topTableView.estimatedRowHeight = 44
+ self.topTableView.rowHeight = UITableViewAutomaticDimension
+ self.topTableView.separatorStyle = UITableViewCellSeparatorStyle.None
+ self.topTableHeight.constant = self.postHeight
+ self.registerForKeyboardNotifications()
+
+ configureLikesText()
+ styleTextField()
+ }
+
+ //MARK: Actions
+
+ @IBAction func cancel(sender: UIButton) {
+ self.dismissViewControllerAnimated(true, completion: nil)
+ }
+
+ //UITableView
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ return 1
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ if tableView == self.topTableView {
+ return 1
+ } else {
+ return 3
+ }
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+
+ //For top table view
+ if tableView == self.topTableView {
+ let currentCell = self.topTableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath) as! InstagramFeedCellController
+ currentCell.likeCommentBox.alpha = CGFloat(1)
+ currentCell.postTime.removeFromSuperview()
+ currentCell.playButton.alpha = CGFloat(0)
+ currentCell.userInteractionEnabled = false
+ cell = currentCell
+
+ }
+ //For comments table view
+ else {
+ cell = self.tableView.dequeueReusableCellWithIdentifier("Comment", forIndexPath: indexPath)
+ }
+ return cell
+ }
+
+ //Other
+ func styleTextField() {
+
+ let spacerViewLeft = UIView(frame:CGRect(x:0, y:0, width:5, height:self.commentBox.frame.height));
+ self.commentBox.leftViewMode = UITextFieldViewMode.Always
+ self.commentBox.leftView = spacerViewLeft
+
+
+ // Remove auto correct
+ self.commentBox.autocorrectionType = .No
+ // Set the delegate for listening
+ self.commentBox.delegate = self
+
+ }
+
+ func configureLikesText() {
+ var user = "Sara Sampaio "
+ var userMutableString = NSMutableAttributedString()
+ userMutableString = NSMutableAttributedString(string: user, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeue-Medium",
+ size: 10.5)!])
+
+ var sectionOne = "and "
+ var sectionOneMutableString = NSMutableAttributedString()
+ sectionOneMutableString = NSMutableAttributedString(string: sectionOne, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeue-Roman",
+ size: 10.5)!])
+
+ var othersCount = "21,653 others "
+ var othersCountMutableString = NSMutableAttributedString()
+ othersCountMutableString = NSMutableAttributedString(string: othersCount, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeue-Medium",
+ size: 10.5)!])
+
+ var sectionTwo = "liked this."
+ var sectionTwoMutableString = NSMutableAttributedString()
+ sectionTwoMutableString = NSMutableAttributedString(string: sectionTwo, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeue-Roman",
+ size: 10.5)!])
+
+ userMutableString.appendAttributedString(sectionOneMutableString)
+ userMutableString.appendAttributedString(othersCountMutableString)
+ userMutableString.appendAttributedString(sectionTwoMutableString)
+ self.likesText.attributedText = userMutableString
+ }
+
+ // Dynamic keyboard & textfield
+
+ // Allows the return button to dismiss the keyboard
+ func textFieldShouldReturn(textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+ // Call this method somewhere in your view controller setup code.
+ func registerForKeyboardNotifications() {
+ let notificationCenter = NSNotificationCenter.defaultCenter()
+ notificationCenter.addObserver(self,
+ selector: "keyboardWillBeShown:",
+ name: UIKeyboardWillShowNotification,
+ object: nil)
+ notificationCenter.addObserver(self,
+ selector: "keyboardWillBeHidden:",
+ name: UIKeyboardWillHideNotification,
+ object: nil)
+ }
+
+ // Called when the UIKeyboardDidShowNotification is sent.
+ func keyboardWillBeShown(sender: NSNotification) {
+
+ let info: NSDictionary = sender.userInfo!
+ let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue
+ let keyboardSize: CGSize = value.CGRectValue().size
+
+ // MOVE THE CONTENT UP FOR THE KEYBOARD
+ moveForKeyboard(keyboardSize.height)
+
+ }
+
+ // Called when the UIKeyboardWillHideNotification is sent
+ func keyboardWillBeHidden(sender: NSNotification) {
+ hideAfterKeyboard()
+ }
+
+ func moveForKeyboard(keySize : CGFloat) {
+ bottomSpacing.constant = keySize
+ UIView.animateWithDuration(0) {
+ self.view.layoutIfNeeded()
+ }
+ }
+
+ func hideAfterKeyboard() {
+ bottomSpacing.constant = CGFloat(0.0)
+ }
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/ConversationCell.xib b/ConversationCell.xib
new file mode 100644
index 0000000..e700cc3
--- /dev/null
+++ b/ConversationCell.xib
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+
+ HelveticaNeueLTStd-Md
+
+
+ HelveticaNeueLTStd-Roman
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ConversationListDatasource.swift b/ConversationListDatasource.swift
new file mode 100644
index 0000000..a4d8606
--- /dev/null
+++ b/ConversationListDatasource.swift
@@ -0,0 +1,43 @@
+//
+// ConversationListDatasource.swift
+// comblie
+//
+// Created by Cal on 11/16/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class ConversationListDatasource: NSObject, UITableViewDataSource {
+
+ var tableView : UITableView
+ var items : NSMutableArray
+
+ init(tableView : UITableView) {
+ self.items = ["a","a","a","a","a","a","a","a","a","a"]
+ self.tableView = tableView
+ self.tableView.registerNib(UINib(nibName: "ConversationCell", bundle: nil), forCellReuseIdentifier: "ConversationCell")
+ self.tableView.registerNib(UINib(nibName: "VineHeaderCell", bundle: nil), forCellReuseIdentifier: "VineHeader")
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.items.count
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+ // Configure the cell...
+ let cell = tableView.dequeueReusableCellWithIdentifier("ConversationCell", forIndexPath: indexPath) as! ConversationCellController
+ cell.profileImage.image = UIImage(named: "profileImage")
+ cell.layoutMargins = UIEdgeInsetsZero
+ currentCell = cell
+
+ return currentCell
+ }
+
+}
diff --git a/FBSDKCoreKit.framework/FBSDKCoreKit b/FBSDKCoreKit.framework/FBSDKCoreKit
new file mode 100644
index 0000000..95e4836
Binary files /dev/null and b/FBSDKCoreKit.framework/FBSDKCoreKit differ
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKAccessToken.h b/FBSDKCoreKit.framework/Headers/FBSDKAccessToken.h
new file mode 100644
index 0000000..4ed0656
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKAccessToken.h
@@ -0,0 +1,166 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+#import
+#import
+
+/*!
+ @abstract Notification indicating that the `currentAccessToken` has changed.
+ @discussion the userInfo dictionary of the notification will contain keys
+ `FBSDKAccessTokenChangeOldKey` and
+ `FBSDKAccessTokenChangeNewKey`.
+ */
+FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeNotification;
+
+/*!
+ @abstract A key in the notification's userInfo that will be set
+ if and only if the user ID changed between the old and new tokens.
+ @discussion Token refreshes can occur automatically with the SDK
+ which do not change the user. If you're only interested in user
+ changes (such as logging out), you should check for the existence
+ of this key. The value is a NSNumber with a boolValue.
+
+ On a fresh start of the app where the SDK reads in the cached value
+ of an access token, this key will also exist since the access token
+ is moving from a null state (no user) to a non-null state (user).
+ */
+FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeUserID;
+
+/*
+ @abstract key in notification's userInfo object for getting the old token.
+ @discussion If there was no old token, the key will not be present.
+ */
+FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeOldKey;
+
+/*
+ @abstract key in notification's userInfo object for getting the new token.
+ @discussion If there is no new token, the key will not be present.
+ */
+FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeNewKey;
+
+
+/*!
+ @class FBSDKAccessToken
+ @abstract Represents an immutable access token for using Facebook services.
+ */
+@interface FBSDKAccessToken : NSObject
+
+/*!
+ @abstract Returns the app ID.
+ */
+@property (readonly, copy, nonatomic) NSString *appID;
+
+/*!
+ @abstract Returns the known declined permissions.
+ */
+@property (readonly, copy, nonatomic) NSSet *declinedPermissions;
+
+/*!
+ @abstract Returns the expiration date.
+ */
+@property (readonly, copy, nonatomic) NSDate *expirationDate;
+
+/*!
+ @abstract Returns the known granted permissions.
+ */
+@property (readonly, copy, nonatomic) NSSet *permissions;
+
+/*!
+ @abstract Returns the date the token was last refreshed.
+*/
+@property (readonly, copy, nonatomic) NSDate *refreshDate;
+
+/*!
+ @abstract Returns the opaque token string.
+ */
+@property (readonly, copy, nonatomic) NSString *tokenString;
+
+/*!
+ @abstract Returns the user ID.
+ */
+@property (readonly, copy, nonatomic) NSString *userID;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+/*!
+ @abstract Initializes a new instance.
+ @param tokenString the opaque token string.
+ @param permissions the granted permissions. Note this is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ @param declinedPermissions the declined permissions. Note this is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ @param appID the app ID.
+ @param userID the user ID.
+ @param expirationDate the optional expiration date (defaults to distantFuture).
+ @param refreshDate the optional date the token was last refreshed (defaults to today).
+ @discussion This initializer should only be used for advanced apps that
+ manage tokens explicitly. Typical login flows only need to use `FBSDKLoginManager`
+ along with `+currentAccessToken`.
+ */
+- (instancetype)initWithTokenString:(NSString *)tokenString
+ permissions:(NSArray *)permissions
+ declinedPermissions:(NSArray *)declinedPermissions
+ appID:(NSString *)appID
+ userID:(NSString *)userID
+ expirationDate:(NSDate *)expirationDate
+ refreshDate:(NSDate *)refreshDate
+NS_DESIGNATED_INITIALIZER;
+
+/*!
+ @abstract Convenience getter to determine if a permission has been granted
+ @param permission The permission to check.
+ */
+- (BOOL)hasGranted:(NSString *)permission;
+
+/*!
+ @abstract Compares the receiver to another FBSDKAccessToken
+ @param token The other token
+ @return YES if the receiver's values are equal to the other token's values; otherwise NO
+ */
+- (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token;
+
+/*!
+ @abstract Returns the "global" access token that represents the currently logged in user.
+ @discussion The `currentAccessToken` is a convenient representation of the token of the
+ current user and is used by other SDK components (like `FBSDKLoginManager`).
+ */
++ (FBSDKAccessToken *)currentAccessToken;
+
+/*!
+ @abstract Sets the "global" access token that represents the currently logged in user.
+ @param token The access token to set.
+ @discussion This will broadcast a notification and save the token to the app keychain.
+ */
++ (void)setCurrentAccessToken:(FBSDKAccessToken *)token;
+
+/*!
+ @abstract Refresh the current access token's permission state and extend the token's expiration date,
+ if possible.
+ @param completionHandler an optional callback handler that can surface any errors related to permission refreshing.
+ @discussion On a successful refresh, the currentAccessToken will be updated so you typically only need to
+ observe the `FBSDKAccessTokenDidChangeNotification` notification.
+
+ If a token is already expired, it cannot be refreshed.
+ */
++ (void)refreshCurrentAccessToken:(FBSDKGraphRequestHandler)completionHandler;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKAppEvents.h b/FBSDKCoreKit.framework/Headers/FBSDKAppEvents.h
new file mode 100644
index 0000000..375d413
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKAppEvents.h
@@ -0,0 +1,462 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import "FBSDKMacros.h"
+
+@class FBSDKAccessToken;
+@class FBSDKGraphRequest;
+
+/*! @abstract NSNotificationCenter name indicating a result of a failed log flush attempt. The posted object will be an NSError instance. */
+FBSDK_EXTERN NSString *const FBSDKAppEventsLoggingResultNotification;
+
+/*! @abstract optional plist key ("FacebookLoggingOverrideAppID") for setting `loggingOverrideAppID` */
+FBSDK_EXTERN NSString *const FBSDKAppEventsOverrideAppIDBundleKey;
+
+/*!
+
+ @typedef NS_ENUM (NSUInteger, FBSDKAppEventsFlushBehavior)
+
+ @abstract Specifies when `FBSDKAppEvents` sends log events to the server.
+
+ */
+typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushBehavior)
+{
+
+ /*! Flush automatically: periodically (once a minute or every 100 logged events) and always at app reactivation. */
+ FBSDKAppEventsFlushBehaviorAuto = 0,
+
+ /*! Only flush when the `flush` method is called. When an app is moved to background/terminated, the
+ events are persisted and re-established at activation, but they will only be written with an
+ explicit call to `flush`. */
+ FBSDKAppEventsFlushBehaviorExplicitOnly,
+
+};
+
+/*!
+ @methodgroup Predefined event names for logging events common to many apps. Logging occurs through the `logEvent` family of methods on `FBSDKAppEvents`.
+ Common event parameters are provided in the `FBSDKAppEventsParameterNames*` constants.
+ */
+
+/*! Log this event when the user has achieved a level in the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameAchievedLevel;
+
+/*! Log this event when the user has entered their payment info. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedPaymentInfo;
+
+/*! Log this event when the user has added an item to their cart. The valueToSum passed to logEvent should be the item's price. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedToCart;
+
+/*! Log this event when the user has added an item to their wishlist. The valueToSum passed to logEvent should be the item's price. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedToWishlist;
+
+/*! Log this event when a user has completed registration with the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameCompletedRegistration;
+
+/*! Log this event when the user has completed a tutorial in the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameCompletedTutorial;
+
+/*! Log this event when the user has entered the checkout process. The valueToSum passed to logEvent should be the total price in the cart. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameInitiatedCheckout;
+
+/*! Log this event when the user has rated an item in the app. The valueToSum passed to logEvent should be the numeric rating. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameRated;
+
+/*! Log this event when a user has performed a search within the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameSearched;
+
+/*! Log this event when the user has spent app credits. The valueToSum passed to logEvent should be the number of credits spent. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameSpentCredits;
+
+/*! Log this event when the user has unlocked an achievement in the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameUnlockedAchievement;
+
+/*! Log this event when a user has viewed a form of content in the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventNameViewedContent;
+
+/*!
+ @methodgroup Predefined event name parameters for common additional information to accompany events logged through the `logEvent` family
+ of methods on `FBSDKAppEvents`. Common event names are provided in the `FBAppEventName*` constants.
+ */
+
+/*! Parameter key used to specify an ID for the specific piece of content being logged about. Could be an EAN, article identifier, etc., depending on the nature of the app. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameContentID;
+
+/*! Parameter key used to specify a generic content type/family for the logged event, e.g. "music", "photo", "video". Options to use will vary based upon what the app is all about. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameContentType;
+
+/*! Parameter key used to specify currency used with logged event. E.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is . */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameCurrency;
+
+/*! Parameter key used to specify a description appropriate to the event being logged. E.g., the name of the achievement unlocked in the `FBAppEventNameAchievementUnlocked` event. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameDescription;
+
+/*! Parameter key used to specify the level achieved in a `FBAppEventNameAchieved` event. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameLevel;
+
+/*! Parameter key used to specify the maximum rating available for the `FBAppEventNameRate` event. E.g., "5" or "10". */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameMaxRatingValue;
+
+/*! Parameter key used to specify how many items are being processed for an `FBAppEventNameInitiatedCheckout` or `FBAppEventNamePurchased` event. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameNumItems;
+
+/*! Parameter key used to specify whether payment info is available for the `FBAppEventNameInitiatedCheckout` event. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNamePaymentInfoAvailable;
+
+/*! Parameter key used to specify method user has used to register for the app, e.g., "Facebook", "email", "Twitter", etc */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameRegistrationMethod;
+
+/*! Parameter key used to specify the string provided by the user for a search operation. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameSearchString;
+
+/*! Parameter key used to specify whether the activity being logged about was successful or not. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameSuccess;
+
+/*
+ @methodgroup Predefined values to assign to event parameters that accompany events logged through the `logEvent` family
+ of methods on `FBSDKAppEvents`. Common event parameters are provided in the `FBSDKAppEventParameterName*` constants.
+ */
+
+/*! Yes-valued parameter value to be used with parameter keys that need a Yes/No value */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueYes;
+
+/*! No-valued parameter value to be used with parameter keys that need a Yes/No value */
+FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueNo;
+
+
+/*!
+
+ @class FBSDKAppEvents
+
+ @abstract
+ Client-side event logging for specialized application analytics available through Facebook App Insights
+ and for use with Facebook Ads conversion tracking and optimization.
+
+ @discussion
+ The `FBSDKAppEvents` static class has a few related roles:
+
+ + Logging predefined and application-defined events to Facebook App Insights with a
+ numeric value to sum across a large number of events, and an optional set of key/value
+ parameters that define "segments" for this event (e.g., 'purchaserStatus' : 'frequent', or
+ 'gamerLevel' : 'intermediate')
+
+ + Logging events to later be used for ads optimization around lifetime value.
+
+ + Methods that control the way in which events are flushed out to the Facebook servers.
+
+ Here are some important characteristics of the logging mechanism provided by `FBSDKAppEvents`:
+
+ + Events are not sent immediately when logged. They're cached and flushed out to the Facebook servers
+ in a number of situations:
+ - when an event count threshold is passed (currently 100 logged events).
+ - when a time threshold is passed (currently 15 seconds).
+ - when an app has gone to background and is then brought back to the foreground.
+
+ + Events will be accumulated when the app is in a disconnected state, and sent when the connection is
+ restored and one of the above 'flush' conditions are met.
+
+ + The `FBSDKAppEvents` class is thread-safe in that events may be logged from any of the app's threads.
+
+ + The developer can set the `flushBehavior` on `FBSDKAppEvents` to force the flushing of events to only
+ occur on an explicit call to the `flush` method.
+
+ + The developer can turn on console debug output for event logging and flushing to the server by using
+ the `FBSDKLoggingBehaviorAppEvents` value in `[FBSettings setLoggingBehavior:]`.
+
+ Some things to note when logging events:
+
+ + There is a limit on the number of unique event names an app can use, on the order of 1000.
+ + There is a limit to the number of unique parameter names in the provided parameters that can
+ be used per event, on the order of 25. This is not just for an individual call, but for all
+ invocations for that eventName.
+ + Event names and parameter names (the keys in the NSDictionary) must be between 2 and 40 characters, and
+ must consist of alphanumeric characters, _, -, or spaces.
+ + The length of each parameter value can be no more than on the order of 100 characters.
+
+ */
+@interface FBSDKAppEvents : NSObject
+
+/*
+ * Basic event logging
+ */
+
+/*!
+
+ @abstract
+ Log an event with just an eventName.
+
+ @param eventName The name of the event to record. Limitations on number of events and name length
+ are given in the `FBSDKAppEvents` documentation.
+
+ */
++ (void)logEvent:(NSString *)eventName;
+
+/*!
+
+ @abstract
+ Log an event with an eventName and a numeric value to be aggregated with other events of this name.
+
+ @param eventName The name of the event to record. Limitations on number of events and name length
+ are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants.
+
+ @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report
+ the cumulative and average value of this amount.
+ */
++ (void)logEvent:(NSString *)eventName
+ valueToSum:(double)valueToSum;
+
+
+/*!
+
+ @abstract
+ Log an event with an eventName and a set of key/value pairs in the parameters dictionary.
+ Parameter limitations are described above.
+
+ @param eventName The name of the event to record. Limitations on number of events and name construction
+ are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants.
+
+ @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must
+ be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of
+ parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
+ are provided in `FBSDKAppEventParameterName*` constants.
+ */
++ (void)logEvent:(NSString *)eventName
+ parameters:(NSDictionary *)parameters;
+
+/*!
+
+ @abstract
+ Log an event with an eventName, a numeric value to be aggregated with other events of this name,
+ and a set of key/value pairs in the parameters dictionary.
+
+ @param eventName The name of the event to record. Limitations on number of events and name construction
+ are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants.
+
+ @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report
+ the cumulative and average value of this amount.
+
+ @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must
+ be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of
+ parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
+ are provided in `FBSDKAppEventParameterName*` constants.
+
+ */
++ (void)logEvent:(NSString *)eventName
+ valueToSum:(double)valueToSum
+ parameters:(NSDictionary *)parameters;
+
+
+/*!
+
+ @abstract
+ Log an event with an eventName, a numeric value to be aggregated with other events of this name,
+ and a set of key/value pairs in the parameters dictionary. Providing session lets the developer
+ target a particular . If nil is provided, then `[FBSession activeSession]` will be used.
+
+ @param eventName The name of the event to record. Limitations on number of events and name construction
+ are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants.
+
+ @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report
+ the cumulative and average value of this amount. Note that this is an NSNumber, and a value of `nil` denotes
+ that this event doesn't have a value associated with it for summation.
+
+ @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must
+ be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of
+ parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
+ are provided in `FBSDKAppEventParameterName*` constants.
+
+ @param accessToken The optional access token to log the event as.
+ */
++ (void)logEvent:(NSString *)eventName
+ valueToSum:(NSNumber *)valueToSum
+ parameters:(NSDictionary *)parameters
+ accessToken:(FBSDKAccessToken *)accessToken;
+
+/*
+ * Purchase logging
+ */
+
+/*!
+
+ @abstract
+ Log a purchase of the specified amount, in the specified currency.
+
+ @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency. This value
+ will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346).
+
+ @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for
+ specific values. One reference for these is .
+
+ @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set
+ to `FBSDKAppEventsFlushBehaviorExplicitOnly`.
+
+ */
++ (void)logPurchase:(double)purchaseAmount
+ currency:(NSString *)currency;
+
+/*!
+
+ @abstract
+ Log a purchase of the specified amount, in the specified currency, also providing a set of
+ additional characteristics describing the purchase.
+
+ @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency.This value
+ will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346).
+
+ @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for
+ specific values. One reference for these is .
+
+ @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must
+ be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of
+ parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
+ are provided in `FBSDKAppEventParameterName*` constants.
+
+ @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set
+ to `FBSDKAppEventsFlushBehaviorExplicitOnly`.
+
+ */
++ (void)logPurchase:(double)purchaseAmount
+ currency:(NSString *)currency
+ parameters:(NSDictionary *)parameters;
+
+/*!
+
+ @abstract
+ Log a purchase of the specified amount, in the specified currency, also providing a set of
+ additional characteristics describing the purchase, as well as an to log to.
+
+ @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency.This value
+ will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346).
+
+ @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for
+ specific values. One reference for these is .
+
+ @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must
+ be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of
+ parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names
+ are provided in `FBSDKAppEventParameterName*` constants.
+
+ @param accessToken The optional access token to log the event as.
+
+ @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set
+ to `FBSDKAppEventsFlushBehaviorExplicitOnly`.
+
+ */
++ (void)logPurchase:(double)purchaseAmount
+ currency:(NSString *)currency
+ parameters:(NSDictionary *)parameters
+ accessToken:(FBSDKAccessToken *)accessToken;
+
+/*!
+
+ @abstract
+ Notifies the events system that the app has launched and, when appropriate, logs an "activated app" event. Should typically be placed in the
+ app delegates' `applicationDidBecomeActive:` method.
+
+ This method also takes care of logging the event indicating the first time this app has been launched, which, among other things, is used to
+ track user acquisition and app install ads conversions.
+
+ @discussion
+ `activateApp` will not log an event on every app launch, since launches happen every time the app is backgrounded and then foregrounded.
+ "activated app" events will be logged when the app has not been active for more than 60 seconds. This method also causes a "deactivated app"
+ event to be logged when sessions are "completed", and these events are logged with the session length, with an indication of how much
+ time has elapsed between sessions, and with the number of background/foreground interruptions that session had. This data
+ is all visible in your app's App Events Insights.
+ */
++ (void)activateApp;
+
+/*
+ * Control over event batching/flushing
+ */
+
+/*!
+
+ @abstract
+ Get the current event flushing behavior specifying when events are sent back to Facebook servers.
+ */
++ (FBSDKAppEventsFlushBehavior)flushBehavior;
+
+/*!
+
+ @abstract
+ Set the current event flushing behavior specifying when events are sent back to Facebook servers.
+
+ @param flushBehavior The desired `FBSDKAppEventsFlushBehavior` to be used.
+ */
++ (void)setFlushBehavior:(FBSDKAppEventsFlushBehavior)flushBehavior;
+
+/*!
+ @abstract
+ Set the 'override' App ID for App Event logging.
+
+ @discussion
+ In some cases, apps want to use one Facebook App ID for login and social presence and another
+ for App Event logging. (An example is if multiple apps from the same company share an app ID for login, but
+ want distinct logging.) By default, this value is `nil`, and defers to the `FBSDKAppEventsOverrideAppIDBundleKey`
+ plist value. If that's not set, it defaults to `[FBSDKSettings appID]`.
+
+ This should be set before any other calls are made to `FBSDKAppEvents`. Thus, you should set it in your application
+ delegate's `application:didFinishLaunchingWithOptions:` delegate.
+
+ @param appID The Facebook App ID to be used for App Event logging.
+ */
++ (void)setLoggingOverrideAppID:(NSString *)appID;
+
+/*!
+ @abstract
+ Get the 'override' App ID for App Event logging.
+
+ @see setLoggingOverrideAppID:
+
+ */
++ (NSString *)loggingOverrideAppID;
+
+
+/*!
+ @abstract
+ Explicitly kick off flushing of events to Facebook. This is an asynchronous method, but it does initiate an immediate
+ kick off. Server failures will be reported through the NotificationCenter with notification ID `FBSDKAppEventsLoggingResultNotification`.
+ */
++ (void)flush;
+
+/*!
+ @abstract
+ Creates a request representing the Graph API call to retrieve a Custom Audience "third party ID" for the app's Facebook user.
+ Callers will send this ID back to their own servers, collect up a set to create a Facebook Custom Audience with,
+ and then use the resultant Custom Audience to target ads.
+
+ @param accessToken The access token to use to establish the user's identity for users logged into Facebook through this app.
+ If `nil`, then the `[FBSDKAccessToken currentAccessToken]` is used.
+
+ @discussion
+ The JSON in the request's response will include an "custom_audience_third_party_id" key/value pair, with the value being the ID retrieved.
+ This ID is an encrypted encoding of the Facebook user's ID and the invoking Facebook app ID.
+ Multiple calls with the same user will return different IDs, thus these IDs cannot be used to correlate behavior
+ across devices or applications, and are only meaningful when sent back to Facebook for creating Custom Audiences.
+
+ The ID retrieved represents the Facebook user identified in the following way: if the specified access token is valid,
+ the ID will represent the user associated with that token; otherwise the ID will represent the user logged into the
+ native Facebook app on the device. If there is no native Facebook app, no one is logged into it, or the user has opted out
+ at the iOS level from ad tracking, then a `nil` ID will be returned.
+
+ This method returns `nil` if either the user has opted-out (via iOS) from Ad Tracking, the app itself has limited event usage
+ via the `[FBSDKSettings limitEventAndDataUsage]` flag, or a specific Facebook user cannot be identified.
+ */
++ (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSDKAccessToken *)accessToken;
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKAppLinkResolver.h b/FBSDKCoreKit.framework/Headers/FBSDKAppLinkResolver.h
new file mode 100644
index 0000000..8e65e5b
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKAppLinkResolver.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 BFTask;
+
+// Check if Bolts.framework is available for import
+#if __has_include()
+// Import it if it's available
+# import
+#else
+// Otherwise - redeclare BFAppLinkResolving protocol to resolve the problem of missing symbols
+// Please note: Bolts.framework is still required for AppLink resolving to work,
+// but this allows FBSDKCoreKit to weakly link Bolts.framework as well as this enables clang modulemaps to work.
+
+/*!
+ Implement this protocol to provide an alternate strategy for resolving
+ App Links that may include pre-fetching, caching, or querying for App Link
+ data from an index provided by a service provider.
+ */
+@protocol BFAppLinkResolving
+
+/*!
+ Asynchronously resolves App Link data for a given URL.
+
+ @param url The URL to resolve into an App Link.
+ @returns A BFTask that will return a BFAppLink for the given URL.
+ */
+- (BFTask *)appLinkFromURLInBackground:(NSURL *)url;
+
+@end
+
+#endif
+
+/*!
+ @class FBSDKAppLinkResolver
+
+ @abstract
+ Provides an implementation of the BFAppLinkResolving protocol that uses the Facebook App Link
+ Index API to resolve App Links given a URL. It also provides an additional helper method that can resolve
+ multiple App Links in a single call.
+
+ @discussion
+ Usage of this type requires a client token. See `[FBSDKSettings setClientToken:]` and linking
+ Bolts.framework
+ */
+@interface FBSDKAppLinkResolver : NSObject
+
+/*!
+ @abstract Asynchronously resolves App Link data for multiple URLs.
+
+ @param urls An array of NSURLs to resolve into App Links.
+ @returns A BFTask that will return dictionary mapping input NSURLs to their
+ corresponding BFAppLink.
+
+ @discussion
+ You should set the client token before making this call. See `[FBSDKSettings setClientToken:]`
+ */
+- (BFTask *)appLinksFromURLsInBackground:(NSArray *)urls;
+
+/*!
+ @abstract Allocates and initializes a new instance of FBSDKAppLinkResolver.
+ */
++ (instancetype)resolver;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKAppLinkUtility.h b/FBSDKCoreKit.framework/Headers/FBSDKAppLinkUtility.h
new file mode 100644
index 0000000..216b71d
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKAppLinkUtility.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @abstract Describes the callback for fetchDeferredAppLink.
+ @param url the url representing the deferred App Link
+ @param error the error during the request, if any
+
+ @discussion The url may also have a fb_click_time_utc query parameter that
+ represents when the click occurred that caused the deferred App Link to be created.
+ */
+typedef void (^FBSDKDeferredAppLinkHandler)(NSURL *url, NSError *error);
+
+/*!
+ @abstract Class containing App Links related utility methods.
+ */
+@interface FBSDKAppLinkUtility : NSObject
+
+/*!
+ @abstract
+ Call this method from the main thread to fetch deferred applink data if you use Mobile App
+ Engagement Ads (https://developers.facebook.com/docs/ads-for-apps/mobile-app-ads-engagement).
+ This may require a network round trip. If successful, the handler is invoked with the link
+ data (this will only return a valid URL once, and future calls will result in a nil URL
+ value in the callback).
+
+ @param handler the handler to be invoked if there is deferred App Link data
+
+ @discussion The handler may contain an NSError instance to capture any errors. In the
+ common case where there simply was no app link data, the NSError instance will be nil.
+
+ This method should only be called from a location that occurs after any launching URL has
+ been processed (e.g., you should call this method from your application delegate's
+ applicationDidBecomeActive:).
+ */
++ (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKApplicationDelegate.h b/FBSDKCoreKit.framework/Headers/FBSDKApplicationDelegate.h
new file mode 100644
index 0000000..857acd0
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKApplicationDelegate.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 FBSDKApplicationDelegate
+
+ @abstract
+ The FBSDKApplicationDelegate is designed to post process the results from Facebook Login
+ or Facebook Dialogs (or any action that requires switching over to the native Facebook
+ app or Safari).
+
+ @discussion
+ The methods in this class are designed to mirror those in UIApplicationDelegate, and you
+ should call them in the respective methods in your AppDelegate implementation.
+ */
+@interface FBSDKApplicationDelegate : NSObject
+
+/*!
+ @abstract Gets the singleton instance.
+ */
++ (instancetype)sharedInstance;
+
+/*!
+ @abstract
+ Call this method from the [UIApplicationDelegate application:openURL:sourceApplication:annotation:] method
+ of the AppDelegate for your app. It should be invoked for the proper processing of responses during interaction
+ with the native Facebook app or Safari as part of SSO authorization flow or Facebook dialogs.
+
+ @param application The application as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:].
+
+ @param url The URL as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:].
+
+ @param sourceApplication The sourceApplication as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:].
+
+ @param annotation The annotation as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:].
+
+ @return YES if the url was intended for the Facebook SDK, NO if not.
+ */
+- (BOOL)application:(UIApplication *)application
+ openURL:(NSURL *)url
+ sourceApplication:(NSString *)sourceApplication
+ annotation:(id)annotation;
+
+/*!
+ @abstract
+ Call this method from the [UIApplicationDelegate application:didFinishLaunchingWithOptions:] method
+ of the AppDelegate for your app. It should be invoked for the proper use of the Facebook SDK.
+
+ @param application The application as passed to [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
+
+ @param launchOptions The launchOptions as passed to [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
+
+ @return YES if the url was intended for the Facebook SDK, NO if not.
+ */
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKButton.h b/FBSDKCoreKit.framework/Headers/FBSDKButton.h
new file mode 100644
index 0000000..8132998
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKButton.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @abstract A base class for common SDK buttons.
+ */
+@interface FBSDKButton : UIButton
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKConstants.h b/FBSDKCoreKit.framework/Headers/FBSDKConstants.h
new file mode 100644
index 0000000..5f53161
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKConstants.h
@@ -0,0 +1,210 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+/*!
+ @abstract The error domain for all errors from FBSDKCoreKit.
+ @discussion Error codes from the SDK in the range 0-99 are reserved for this domain.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorDomain;
+
+/*!
+ @typedef NS_ENUM(NSInteger, FBSDKErrorCode)
+ @abstract Error codes for FBSDKErrorDomain.
+ */
+typedef NS_ENUM(NSInteger, FBSDKErrorCode)
+{
+ /*!
+ @abstract Reserved.
+ */
+ FBSDKReservedErrorCode = 0,
+
+ /*!
+ @abstract The error code for errors from invalid encryption on incoming encryption URLs.
+ */
+ FBSDKEncryptionErrorCode,
+
+ /*!
+ @abstract The error code for errors from invalid arguments to SDK methods.
+ */
+ FBSDKInvalidArgumentErrorCode,
+
+ /*!
+ @abstract The error code for unknown errors.
+ */
+ FBSDKUnknownErrorCode,
+
+ /*!
+ @abstract A request failed due to a network error. Use NSUnderlyingErrorKey to retrieve
+ the error object from the NSURLConnection for more information.
+ */
+ FBSDKNetworkErrorCode,
+
+ /*!
+ @abstract The error code for errors encounted during an App Events flush.
+ */
+ FBSDKAppEventsFlushErrorCode,
+
+ /*!
+ @abstract An endpoint that returns a binary response was used with FBSDKGraphRequestConnection.
+ @discussion Endpoints that return image/jpg, etc. should be accessed using NSURLRequest
+ */
+ FBSDKGraphRequestNonTextMimeTypeReturnedErrorCode,
+
+ /*!
+ @abstract The operation failed because the server returned an unexpected response.
+ @discussion You can get this error if you are not using the most recent SDK, or you are accessing a version of the
+ Graph API incompatible with the current SDK.
+ */
+ FBSDKGraphRequestProtocolMismatchErrorCode,
+
+ /*!
+ @abstract The Graph API returned an error.
+ @discussion See below for useful userInfo keys (beginning with FBSDKGraphRequestError*)
+ */
+ FBSDKGraphRequestGraphAPIErrorCode,
+
+ /*!
+ @abstract The specified dialog configuration is not available.
+ @discussion This error may signify that the configuration for the dialogs has not yet been downloaded from the server
+ or that the dialog is unavailable. Subsequent attempts to use the dialog may succeed as the configuration is loaded.
+ */
+ FBSDKDialogUnavailableErrorCode,
+
+ /*!
+ @abstract Indicates an operation failed because a required access token was not found.
+ */
+ FBSDKAccessTokenRequiredErrorCode,
+
+ /*!
+ @abstract Indicates an app switch (typically for a dialog) failed because the destination app is out of date.
+ */
+ FBSDKAppVersionUnsupportedErrorCode,
+
+ /*!
+ @abstract Indicates an app switch to the browser (typically for a dialog) failed.
+ */
+ FBSDKBrowswerUnavailableErrorCode,
+};
+
+/*!
+ @typedef NS_ENUM(NSUInteger, FBSDKGraphRequestErrorCategory)
+ @abstract Describes the category of Facebook error. See `FBSDKGraphRequestErrorCategoryKey`.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKGraphRequestErrorCategory)
+{
+ /*! The default error category that is not known to be recoverable. Check `FBSDKLocalizedErrorDescriptionKey` for a user facing message. */
+ FBSDKGraphRequestErrorCategoryOther = 0,
+ /*! Indicates the error is temporary (such as server throttling). While a recoveryAttempter will be provided with the error instance, the attempt is guaranteed to succeed so you can simply retry the operation if you do not want to present an alert. */
+ FBSDKGraphRequestErrorCategoryTransient = 1,
+ /*! Indicates the error can be recovered (such as requiring a login). A recoveryAttempter will be provided with the error instance that can take UI action. */
+ FBSDKGraphRequestErrorCategoryRecoverable = 2
+};
+
+/*
+ @methodgroup error userInfo keys
+ */
+
+/*!
+ @abstract The userInfo key for the invalid collection for errors with FBSDKInvalidArgumentErrorCode.
+ @discussion If the invalid argument is a collection, the collection can be found with this key and the individual
+ invalid item can be found with FBSDKErrorArgumentValueKey.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorArgumentCollectionKey;
+
+/*!
+ @abstract The userInfo key for the invalid argument name for errors with FBSDKInvalidArgumentErrorCode.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorArgumentNameKey;
+
+/*!
+ @abstract The userInfo key for the invalid argument value for errors with FBSDKInvalidArgumentErrorCode.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorArgumentValueKey;
+
+/*!
+ @abstract The userInfo key for the message for developers in NSErrors that originate from the SDK.
+ @discussion The developer message will not be localized and is not intended to be presented within the app.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorDeveloperMessageKey;
+
+/*!
+ @abstract The userInfo key describing a localized description that can be presented to the user.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorLocalizedDescriptionKey;
+
+/*!
+ @abstract The userInfo key describing a localized title that can be presented to the user, used with `FBSDKLocalizedErrorDescriptionKey`.
+ */
+FBSDK_EXTERN NSString *const FBSDKErrorLocalizedTitleKey;
+
+/*
+ @methodgroup FBSDKGraphRequest error userInfo keys
+ */
+
+/*!
+ @abstract The userInfo key describing the error category, for error recovery purposes.
+ @discussion See `FBSDKGraphErrorRecoveryProcessor` and `[FBSDKGraphRequest disableErrorRecovery]`.
+ */
+FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorCategoryKey;
+
+/*
+ @abstract The userInfo key for the Graph API error code.
+ */
+FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorGraphErrorCode;
+
+/*
+ @abstract The userInfo key for the Graph API error subcode.
+ */
+FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorGraphErrorSubcode;
+
+/*
+ @abstract The userInfo key for the HTTP status code.
+ */
+FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey;
+
+/*
+ @abstract The userInfo key for the raw JSON response.
+ */
+FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey;
+
+/*!
+ @abstract a formal protocol very similar to the informal protocol NSErrorRecoveryAttempting
+ */
+@protocol FBSDKErrorRecoveryAttempting
+
+/*!
+ @abstract attempt the recovery
+ @param error the error
+ @param recoveryOptionIndex the selected option index
+ @param delegate the delegate
+ @param didRecoverSelector the callback selector, see discussion.
+ @param contextInfo context info to pass back to callback selector, see discussion.
+ @discussion
+ Given that an error alert has been presented document-modally to the user, and the user has chosen one of the error's recovery options, attempt recovery from the error, and send the selected message to the specified delegate. The option index is an index into the error's array of localized recovery options. The method selected by didRecoverSelector must have the same signature as:
+
+ - (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo;
+
+ The value passed for didRecover must be YES if error recovery was completely successful, NO otherwise.
+ */
+- (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKCopying.h b/FBSDKCoreKit.framework/Headers/FBSDKCopying.h
new file mode 100644
index 0000000..f4ad767
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKCopying.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @abstract Extension protocol for NSCopying that adds the copy method, which is implemented on NSObject.
+ @discussion NSObject implicitly conforms to this protocol.
+ */
+@protocol FBSDKCopying
+
+/*!
+ @abstract Implemented by NSObject as a convenience to copyWithZone:.
+ @return A copy of the receiver.
+ */
+- (id)copy;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKCoreKit.h b/FBSDKCoreKit.framework/Headers/FBSDKCoreKit.h
new file mode 100644
index 0000000..3b78900
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKCoreKit.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+
+#define FBSDK_VERSION_STRING @"4.7.0"
+#define FBSDK_TARGET_PLATFORM_VERSION @"v2.5"
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKGraphErrorRecoveryProcessor.h b/FBSDKCoreKit.framework/Headers/FBSDKGraphErrorRecoveryProcessor.h
new file mode 100644
index 0000000..d2b0313
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKGraphErrorRecoveryProcessor.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import "FBSDKConstants.h"
+
+@class FBSDKGraphErrorRecoveryProcessor;
+@class FBSDKGraphRequest;
+
+/*!
+ @abstract Defines a delegate for `FBSDKGraphErrorRecoveryProcessor`.
+ */
+@protocol FBSDKGraphErrorRecoveryProcessorDelegate
+
+/*!
+ @abstract Indicates the error recovery has been attempted.
+ @param processor the processor instance.
+ @param didRecover YES if the recovery was successful.
+ @param error the error that that was attempted to be recovered from.
+ */
+- (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor didRecover:(BOOL)didRecover error:(NSError *)error;
+
+@optional
+/*!
+ @abstract Indicates the processor is about to process the error.
+ @param processor the processor instance.
+ @param error the error is about to be processed.
+ @discussion return NO if the processor should not process the error. For example,
+ if you want to prevent alerts of localized messages but otherwise perform retries and recoveries,
+ you could return NO for errors where userInfo[FBSDKGraphRequestErrorCategoryKey] equal to FBSDKGraphRequestErrorCategoryOther
+ */
+- (BOOL)processorWillProcessError:(FBSDKGraphErrorRecoveryProcessor *)processor error:(NSError *)error;
+
+@end
+
+/*!
+ @abstract Defines a type that can process Facebook NSErrors with best practices.
+ @discussion Facebook NSErrors can contain FBSDKErrorRecoveryAttempting instances to recover from errors, or
+ localized messages to present to the user. This class will process the instances as follows:
+
+ 1. If the error is temporary as indicated by FBSDKGraphRequestErrorCategoryKey, assume the recovery succeeded and
+ notify the delegate.
+ 2. If a FBSDKErrorRecoveryAttempting instance is available, display an alert (dispatched to main thread)
+ with the recovery options and call the instance's [ attemptRecoveryFromError:optionIndex:...].
+ 3. If a FBSDKErrorRecoveryAttempting is not available, check the userInfo for FBSDKLocalizedErrorDescriptionKey
+ and present that in an alert (dispatched to main thread).
+
+ By default, FBSDKGraphRequests use this type to process errors and retry the request upon a successful
+ recovery.
+
+ Note that Facebook recovery attempters can present UI or even cause app switches (such as to login). Any such
+ work is dispatched to the main thread (therefore your request handlers may then run on the main thread).
+
+ Login recovery requires FBSDKLoginKit. Login will use FBSDKLoginBehaviorNative and will prompt the user
+ for all permissions last granted. If any are declined on the new request, the recovery is not successful but
+ the `[FBSDKAccessToken currentAccessToken]` might still have been updated.
+ .
+ */
+@interface FBSDKGraphErrorRecoveryProcessor : NSObject
+
+/*!
+ @abstract Gets the delegate. Note this is a strong reference, and is nil'ed out after recovery is complete.
+ */
+@property (nonatomic, strong, readonly) iddelegate;
+
+/*!
+ @abstract Attempts to process the error, return YES if the error can be processed.
+ @param error the error to process.
+ @param request the relateed request that may be reissued.
+ @param delegate the delegate that will be retained until recovery is complete.
+ */
+- (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id) delegate;
+
+/*!
+ @abstract The callback for FBSDKErrorRecoveryAttempting
+ @param didRecover if the recovery succeeded
+ @param contextInfo unused
+ */
+- (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKGraphRequest.h b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequest.h
new file mode 100644
index 0000000..5ae03e2
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequest.h
@@ -0,0 +1,120 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+@class FBSDKAccessToken;
+
+/*!
+ @abstract Represents a request to the Facebook Graph API.
+
+ @discussion `FBSDKGraphRequest` encapsulates the components of a request (the
+ Graph API path, the parameters, error recovery behavior) and should be
+ used in conjunction with `FBSDKGraphRequestConnection` to issue the request.
+
+ Nearly all Graph APIs require an access token. Unless specified, the
+ `[FBSDKAccessToken currentAccessToken]` is used. Therefore, most requests
+ will require login first (see `FBSDKLoginManager` in FBSDKLoginKit.framework).
+
+ A `- start` method is provided for convenience for single requests.
+
+ By default, FBSDKGraphRequest will attempt to recover any errors returned from
+ Facebook. You can disable this via `disableErrorRecovery:`.
+ @see FBSDKGraphErrorRecoveryProcessor
+ */
+@interface FBSDKGraphRequest : NSObject
+
+/*!
+ @abstract Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
+ @param graphPath the graph path (e.g., @"me").
+ @param parameters the optional parameters dictionary.
+ */
+- (instancetype)initWithGraphPath:(NSString *)graphPath
+ parameters:(NSDictionary *)parameters;
+
+/*!
+ @abstract Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`.
+ @param graphPath the graph path (e.g., @"me").
+ @param parameters the optional parameters dictionary.
+ @param HTTPMethod the optional HTTP method. nil defaults to @"GET".
+ */
+- (instancetype)initWithGraphPath:(NSString *)graphPath
+ parameters:(NSDictionary *)parameters
+ HTTPMethod:(NSString *)HTTPMethod;
+
+/*!
+ @abstract Initializes a new instance.
+ @param graphPath the graph path (e.g., @"me").
+ @param parameters the optional parameters dictionary.
+ @param tokenString the token string to use. Specifying nil will cause no token to be used.
+ @param version the optional Graph API version (e.g., @"v2.0"). nil defaults to FBSDK_TARGET_PLATFORM_VERSION.
+ @param HTTPMethod the optional HTTP method (e.g., @"POST"). nil defaults to @"GET".
+ */
+- (instancetype)initWithGraphPath:(NSString *)graphPath
+ parameters:(NSDictionary *)parameters
+ tokenString:(NSString *)tokenString
+ version:(NSString *)version
+ HTTPMethod:(NSString *)HTTPMethod
+NS_DESIGNATED_INITIALIZER;
+
+/*!
+ @abstract The request parameters.
+ */
+@property (nonatomic, strong, readonly) NSMutableDictionary *parameters;
+
+/*!
+ @abstract The access token string used by the request.
+ */
+@property (nonatomic, copy, readonly) NSString *tokenString;
+
+/*!
+ @abstract The Graph API endpoint to use for the request, for example "me".
+ */
+@property (nonatomic, copy, readonly) NSString *graphPath;
+
+/*!
+ @abstract The HTTPMethod to use for the request, for example "GET" or "POST".
+ */
+@property (nonatomic, copy, readonly) NSString *HTTPMethod;
+
+/*!
+ @abstract The Graph API version to use (e.g., "v2.0")
+ */
+@property (nonatomic, copy, readonly) NSString *version;
+
+/*!
+ @abstract If set, disables the automatic error recovery mechanism.
+ @param disable whether to disable the automatic error recovery mechanism
+ @discussion By default, non-batched FBSDKGraphRequest instances will automatically try to recover
+ from errors by constructing a `FBSDKGraphErrorRecoveryProcessor` instance that
+ re-issues the request on successful recoveries. The re-issued request will call the same
+ handler as the receiver but may occur with a different `FBSDKGraphRequestConnection` instance.
+
+ This will override [FBSDKSettings setGraphErrorRecoveryDisabled:].
+ */
+- (void)setGraphErrorRecoveryDisabled:(BOOL)disable;
+
+/*!
+ @abstract Starts a connection to the Graph API.
+ @param handler The handler block to call when the request completes.
+ */
+- (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestHandler)handler;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestConnection.h b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestConnection.h
new file mode 100644
index 0000000..79ffb3f
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestConnection.h
@@ -0,0 +1,325 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+@class FBSDKGraphRequest;
+@class FBSDKGraphRequestConnection;
+
+/*!
+ @typedef FBSDKGraphRequestHandler
+
+ @abstract
+ A block that is passed to addRequest to register for a callback with the results of that
+ request once the connection completes.
+
+ @discussion
+ Pass a block of this type when calling addRequest. This will be called once
+ the request completes. The call occurs on the UI thread.
+
+ @param connection The `FBSDKGraphRequestConnection` that sent the request.
+
+ @param result The result of the request. This is a translation of
+ JSON data to `NSDictionary` and `NSArray` objects. This
+ is nil if there was an error.
+
+ @param error The `NSError` representing any error that occurred.
+
+ */
+typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection,
+ id result,
+ NSError *error);
+
+/*!
+ @protocol
+
+ @abstract
+ The `FBSDKGraphRequestConnectionDelegate` protocol defines the methods used to receive network
+ activity progress information from a .
+ */
+@protocol FBSDKGraphRequestConnectionDelegate
+
+@optional
+
+/*!
+ @method
+
+ @abstract
+ Tells the delegate the request connection will begin loading
+
+ @discussion
+ If the is created using one of the convenience factory methods prefixed with
+ start, the object returned from the convenience method has already begun loading and this method
+ will not be called when the delegate is set.
+
+ @param connection The request connection that is starting a network request
+ */
+- (void)requestConnectionWillBeginLoading:(FBSDKGraphRequestConnection *)connection;
+
+/*!
+ @method
+
+ @abstract
+ Tells the delegate the request connection finished loading
+
+ @discussion
+ If the request connection completes without a network error occuring then this method is called.
+ Invocation of this method does not indicate success of every made, only that the
+ request connection has no further activity. Use the error argument passed to the FBSDKGraphRequestHandler
+ block to determine success or failure of each .
+
+ This method is invoked after the completion handler for each .
+
+ @param connection The request connection that successfully completed a network request
+ */
+- (void)requestConnectionDidFinishLoading:(FBSDKGraphRequestConnection *)connection;
+
+/*!
+ @method
+
+ @abstract
+ Tells the delegate the request connection failed with an error
+
+ @discussion
+ If the request connection fails with a network error then this method is called. The `error`
+ argument specifies why the network connection failed. The `NSError` object passed to the
+ FBSDKGraphRequestHandler block may contain additional information.
+
+ @param connection The request connection that successfully completed a network request
+ @param error The `NSError` representing the network error that occurred, if any. May be nil
+ in some circumstances. Consult the `NSError` for the for reliable
+ failure information.
+ */
+- (void)requestConnection:(FBSDKGraphRequestConnection *)connection
+ didFailWithError:(NSError *)error;
+
+/*!
+ @method
+
+ @abstract
+ Tells the delegate how much data has been sent and is planned to send to the remote host
+
+ @discussion
+ The byte count arguments refer to the aggregated objects, not a particular .
+
+ Like `NSURLConnection`, the values may change in unexpected ways if data needs to be resent.
+
+ @param connection The request connection transmitting data to a remote host
+ @param bytesWritten The number of bytes sent in the last transmission
+ @param totalBytesWritten The total number of bytes sent to the remote host
+ @param totalBytesExpectedToWrite The total number of bytes expected to send to the remote host
+ */
+- (void)requestConnection:(FBSDKGraphRequestConnection *)connection
+ didSendBodyData:(NSInteger)bytesWritten
+ totalBytesWritten:(NSInteger)totalBytesWritten
+totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
+
+@end
+
+/*!
+ @class FBSDKGraphRequestConnection
+
+ @abstract
+ The `FBSDKGraphRequestConnection` represents a single connection to Facebook to service a request.
+
+ @discussion
+ The request settings are encapsulated in a reusable object. The
+ `FBSDKGraphRequestConnection` object encapsulates the concerns of a single communication
+ e.g. starting a connection, canceling a connection, or batching requests.
+
+ */
+@interface FBSDKGraphRequestConnection : NSObject
+
+/*!
+ @abstract
+ The delegate object that receives updates.
+ */
+@property (nonatomic, assign) id delegate;
+
+/*!
+ @abstract Gets or sets the timeout interval to wait for a response before giving up.
+ */
+@property (nonatomic) NSTimeInterval timeout;
+
+/*!
+ @abstract
+ The raw response that was returned from the server. (readonly)
+
+ @discussion
+ This property can be used to inspect HTTP headers that were returned from
+ the server.
+
+ The property is nil until the request completes. If there was a response
+ then this property will be non-nil during the FBSDKGraphRequestHandler callback.
+ */
+@property (nonatomic, retain, readonly) NSHTTPURLResponse *URLResponse;
+
+/*!
+ @methodgroup Class methods
+ */
+
+/*!
+ @method
+
+ @abstract
+ This method sets the default timeout on all FBSDKGraphRequestConnection instances. Defaults to 60 seconds.
+
+ @param defaultConnectionTimeout The timeout interval.
+ */
++ (void)setDefaultConnectionTimeout:(NSTimeInterval)defaultConnectionTimeout;
+
+/*!
+ @methodgroup Adding requests
+ */
+
+/*!
+ @method
+
+ @abstract
+ This method adds an object to this connection.
+
+ @param request A request to be included in the round-trip when start is called.
+ @param handler A handler to call back when the round-trip completes or times out.
+
+ @discussion
+ The completion handler is retained until the block is called upon the
+ completion or cancellation of the connection.
+ */
+- (void)addRequest:(FBSDKGraphRequest *)request
+ completionHandler:(FBSDKGraphRequestHandler)handler;
+
+/*!
+ @method
+
+ @abstract
+ This method adds an object to this connection.
+
+ @param request A request to be included in the round-trip when start is called.
+
+ @param handler A handler to call back when the round-trip completes or times out.
+ The handler will be invoked on the main thread.
+
+ @param name An optional name for this request. This can be used to feed
+ the results of one request to the input of another in the same
+ `FBSDKGraphRequestConnection` as described in
+ [Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ).
+
+ @discussion
+ The completion handler is retained until the block is called upon the
+ completion or cancellation of the connection. This request can be named
+ to allow for using the request's response in a subsequent request.
+ */
+- (void)addRequest:(FBSDKGraphRequest *)request
+ completionHandler:(FBSDKGraphRequestHandler)handler
+ batchEntryName:(NSString *)name;
+
+/*!
+ @method
+
+ @abstract
+ This method adds an object to this connection.
+
+ @param request A request to be included in the round-trip when start is called.
+
+ @param handler A handler to call back when the round-trip completes or times out.
+
+ @param batchParameters The optional dictionary of parameters to include for this request
+ as described in [Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ).
+ Examples include "depends_on", "name", or "omit_response_on_success".
+
+ @discussion
+ The completion handler is retained until the block is called upon the
+ completion or cancellation of the connection. This request can be named
+ to allow for using the request's response in a subsequent request.
+ */
+- (void)addRequest:(FBSDKGraphRequest *)request
+ completionHandler:(FBSDKGraphRequestHandler)handler
+ batchParameters:(NSDictionary *)batchParameters;
+
+/*!
+ @methodgroup Instance methods
+ */
+
+/*!
+ @method
+
+ @abstract
+ Signals that a connection should be logically terminated as the
+ application is no longer interested in a response.
+
+ @discussion
+ Synchronously calls any handlers indicating the request was cancelled. Cancel
+ does not guarantee that the request-related processing will cease. It
+ does promise that all handlers will complete before the cancel returns. A call to
+ cancel prior to a start implies a cancellation of all requests associated
+ with the connection.
+ */
+- (void)cancel;
+
+/*!
+ @method
+
+ @abstract
+ This method starts a connection with the server and is capable of handling all of the
+ requests that were added to the connection.
+
+ @discussion By default, a connection is scheduled on the current thread in the default mode when it is created.
+ See `setDelegateQueue:` for other options.
+
+ This method cannot be called twice for an `FBSDKGraphRequestConnection` instance.
+ */
+- (void)start;
+
+/*!
+ @abstract Determines the operation queue that is used to call methods on the connection's delegate.
+ @param queue The operation queue to use when calling delegate methods.
+ @discussion By default, a connection is scheduled on the current thread in the default mode when it is created.
+ You cannot reschedule a connection after it has started.
+
+ This is very similar to `[NSURLConnection setDelegateQueue:]`.
+ */
+- (void)setDelegateQueue:(NSOperationQueue *)queue;
+
+/*!
+ @method
+
+ @abstract
+ Overrides the default version for a batch request
+
+ @discussion
+ The SDK automatically prepends a version part, such as "v2.0" to API paths in order to simplify API versioning
+ for applications. If you want to override the version part while using batch requests on the connection, call
+ this method to set the version for the batch request.
+
+ @param version This is a string in the form @"v2.0" which will be used for the version part of an API path
+ */
+- (void)overrideVersionPartWith:(NSString *)version;
+
+@end
+
+/*!
+ @abstract The key in the result dictionary for requests to old versions of the Graph API
+ whose response is not a JSON object.
+
+ @discussion When a request returns a non-JSON response (such as a "true" literal), that response
+ will be wrapped into a dictionary using this const as the key. This only applies for very few Graph API
+ prior to v2.1.
+ */
+FBSDK_EXTERN NSString *const FBSDKNonJSONResponseProperty;
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestDataAttachment.h b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestDataAttachment.h
new file mode 100644
index 0000000..c179e29
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKGraphRequestDataAttachment.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @abstract A container class for data attachments so that additional metadata can be provided about the attachment.
+ */
+@interface FBSDKGraphRequestDataAttachment : NSObject
+
+/*!
+ @abstract Initializes the receiver with the attachment data and metadata.
+ @param data The attachment data (retained, not copied)
+ @param filename The filename for the attachment
+ @param contentType The content type for the attachment
+ */
+- (instancetype)initWithData:(NSData *)data
+ filename:(NSString *)filename
+ contentType:(NSString *)contentType
+NS_DESIGNATED_INITIALIZER;
+
+/*!
+ @abstract The content type for the attachment.
+ */
+@property (nonatomic, copy, readonly) NSString *contentType;
+
+/*!
+ @abstract The attachment data.
+ */
+@property (nonatomic, strong, readonly) NSData *data;
+
+/*!
+ @abstract The filename for the attachment.
+ */
+@property (nonatomic, copy, readonly) NSString *filename;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKMacros.h b/FBSDKCoreKit.framework/Headers/FBSDKMacros.h
new file mode 100644
index 0000000..fd2e2ff
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKMacros.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#ifdef __cplusplus
+#define FBSDK_EXTERN extern "C" __attribute__((visibility ("default")))
+#else
+#define FBSDK_EXTERN extern __attribute__((visibility ("default")))
+#endif
+
+#define FBSDK_STATIC_INLINE static inline
+
+#define FBSDK_NO_DESIGNATED_INITIALIZER() \
+@throw [NSException exceptionWithName:NSInvalidArgumentException \
+ reason:[NSString stringWithFormat:@"unrecognized selector sent to instance %p", self] \
+ userInfo:nil]
+
+#define FBSDK_NOT_DESIGNATED_INITIALIZER(DESIGNATED_INITIALIZER) \
+@throw [NSException exceptionWithName:NSInvalidArgumentException \
+ reason:[NSString stringWithFormat:@"Please use the designated initializer [%p %@]", \
+ self, \
+ NSStringFromSelector(@selector(DESIGNATED_INITIALIZER))] \
+ userInfo:nil]
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKMutableCopying.h b/FBSDKCoreKit.framework/Headers/FBSDKMutableCopying.h
new file mode 100644
index 0000000..621fac9
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKMutableCopying.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+/*!
+ @abstract Extension protocol for NSMutableCopying that adds the mutableCopy method, which is implemented on NSObject.
+ @discussion NSObject implicitly conforms to this protocol.
+ */
+@protocol FBSDKMutableCopying
+
+/*!
+ @abstract Implemented by NSObject as a convenience to mutableCopyWithZone:.
+ @return A mutable copy of the receiver.
+ */
+- (id)mutableCopy;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKProfile.h b/FBSDKCoreKit.framework/Headers/FBSDKProfile.h
new file mode 100644
index 0000000..11da3d9
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKProfile.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 "FBSDKMacros.h"
+#import "FBSDKProfilePictureView.h"
+
+/*!
+ @abstract Notification indicating that the `currentProfile` has changed.
+ @discussion the userInfo dictionary of the notification will contain keys
+ `FBSDKProfileChangeOldKey` and
+ `FBSDKProfileChangeNewKey`.
+ */
+FBSDK_EXTERN NSString *const FBSDKProfileDidChangeNotification;
+
+/* @abstract key in notification's userInfo object for getting the old profile.
+ @discussion If there was no old profile, the key will not be present.
+ */
+FBSDK_EXTERN NSString *const FBSDKProfileChangeOldKey;
+
+/* @abstract key in notification's userInfo object for getting the new profile.
+ @discussion If there is no new profile, the key will not be present.
+ */
+FBSDK_EXTERN NSString *const FBSDKProfileChangeNewKey;
+
+/*!
+ @abstract Represents an immutable Facebook profile
+ @discussion This class provides a global "currentProfile" instance to more easily
+ add social context to your application. When the profile changes, a notification is
+ posted so that you can update relevant parts of your UI and is persisted to NSUserDefaults.
+
+ Typically, you will want to call `enableUpdatesOnAccessTokenChange:YES` so that
+ it automatically observes changes to the `[FBSDKAccessToken currentAccessToken]`.
+
+ You can use this class to build your own `FBSDKProfilePictureView` or in place of typical requests to "/me".
+ */
+@interface FBSDKProfile : NSObject
+
+/*!
+ @abstract initializes a new instance.
+ @param userID the user ID
+ @param firstName the user's first name
+ @param middleName the user's middle name
+ @param lastName the user's last name
+ @param name the user's complete name
+ @param linkURL the link for this profile
+ @param refreshDate the optional date this profile was fetched. Defaults to [NSDate date].
+ */
+- (instancetype)initWithUserID:(NSString *)userID
+ firstName:(NSString *)firstName
+ middleName:(NSString *)middleName
+ lastName:(NSString *)lastName
+ name:(NSString *)name
+ linkURL:(NSURL *)linkURL
+ refreshDate:(NSDate *)refreshDate NS_DESIGNATED_INITIALIZER;
+/*!
+ @abstract The user id
+ */
+@property (nonatomic, readonly) NSString *userID;
+/*!
+ @abstract The user's first name
+ */
+@property (nonatomic, readonly) NSString *firstName;
+/*!
+ @abstract The user's middle name
+ */
+@property (nonatomic, readonly) NSString *middleName;
+/*!
+ @abstract The user's last name
+ */
+@property (nonatomic, readonly) NSString *lastName;
+/*!
+ @abstract The user's complete name
+ */
+@property (nonatomic, readonly) NSString *name;
+/*!
+ @abstract A URL to the user's profile.
+ @discussion Consider using Bolts and `FBSDKAppLinkResolver` to resolve this
+ to an app link to link directly to the user's profile in the Facebook app.
+ */
+@property (nonatomic, readonly) NSURL *linkURL;
+
+/*!
+ @abstract The last time the profile data was fetched.
+ */
+@property (nonatomic, readonly) NSDate *refreshDate;
+
+/*!
+ @abstract Gets the current FBSDKProfile instance.
+ */
++ (FBSDKProfile *)currentProfile;
+
+/*!
+ @abstract Sets the current instance and posts the appropriate notification if the profile parameter is different
+ than the receiver.
+ @param profile the profile to set
+ @discussion This persists the profile to NSUserDefaults.
+ */
++ (void)setCurrentProfile:(FBSDKProfile *)profile;
+
+/*!
+ @abstract Indicates if `currentProfile` will automatically observe `FBSDKAccessTokenDidChangeNotification` notifications
+ @param enable YES is observing
+ @discussion If observing, this class will issue a graph request for public profile data when the current token's userID
+ differs from the current profile. You can observe `FBSDKProfileDidChangeNotification` for when the profile is updated.
+
+ Note that if `[FBSDKAccessToken currentAccessToken]` is unset, the `currentProfile` instance remains. It's also possible
+ for `currentProfile` to return nil until the data is fetched.
+ */
++ (void)enableUpdatesOnAccessTokenChange:(BOOL)enable;
+
+/*!
+ @abstract A convenience method for returning a complete `NSURL` for retrieving the user's profile image.
+ @param mode The picture mode
+ @param size The height and width. This will be rounded to integer precision.
+ */
+- (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size;
+
+/*!
+ @abstract A convenience method for returning a Graph API path for retrieving the user's profile image.
+ @deprecated use `imageURLForPictureMode:size:` instead
+ @discussion You can pass this to a `FBSDKGraphRequest` instance to download the image.
+ @param mode The picture mode
+ @param size The height and width. This will be rounded to integer precision.
+ */
+- (NSString *)imagePathForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size
+__attribute__ ((deprecated("use imageURLForPictureMode:size: instead")));
+
+/*!
+ @abstract Returns YES if the profile is equivalent to the receiver.
+ @param profile the profile to compare to.
+ */
+- (BOOL)isEqualToProfile:(FBSDKProfile *)profile;
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKProfilePictureView.h b/FBSDKCoreKit.framework/Headers/FBSDKProfilePictureView.h
new file mode 100644
index 0000000..f1f64cb
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKProfilePictureView.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @typedef FBSDKProfilePictureMode enum
+ @abstract Defines the aspect ratio mode for the source image of the profile picture.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKProfilePictureMode)
+{
+ /*!
+ @abstract A square cropped version of the image will be included in the view.
+ */
+ FBSDKProfilePictureModeSquare,
+ /*!
+ @abstract The original picture's aspect ratio will be used for the source image in the view.
+ */
+ FBSDKProfilePictureModeNormal,
+};
+
+/*!
+ @abstract A view to display a profile picture.
+ */
+@interface FBSDKProfilePictureView : UIView
+
+/*!
+ @abstract The mode for the receiver to determine the aspect ratio of the source image.
+ */
+@property (nonatomic, assign) FBSDKProfilePictureMode pictureMode;
+
+/*!
+ @abstract The profile ID to show the picture for.
+ */
+@property (nonatomic, copy) NSString *profileID;
+
+/*!
+ @abstract Explicitly marks the receiver as needing to update the image.
+ @discussion This method is called whenever any properties that affect the source image are modified, but this can also
+ be used to trigger a manual update of the image if it needs to be re-downloaded.
+ */
+- (void)setNeedsImageUpdate;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKSettings.h b/FBSDKCoreKit.framework/Headers/FBSDKSettings.h
new file mode 100644
index 0000000..edc0040
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKSettings.h
@@ -0,0 +1,209 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+/*
+ * Constants defining logging behavior. Use with <[FBSDKSettings setLoggingBehavior]>.
+ */
+
+/*! Include access token in logging. */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorAccessTokens;
+
+/*! Log performance characteristics */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics;
+
+/*! Log FBSDKAppEvents interactions */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorAppEvents;
+
+/*! Log Informational occurrences */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorInformational;
+
+/*! Log cache errors. */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorCacheErrors;
+
+/*! Log errors from SDK UI controls */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorUIControlErrors;
+
+/*! Log debug warnings from API response, i.e. when friends fields requested, but user_friends permission isn't granted. */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorGraphAPIDebugWarning;
+
+/*! Log warnings from API response, i.e. when requested feature will be deprecated in next version of API.
+ Info is the lowest level of severity, using it will result in logging all previously mentioned levels.
+ */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo;
+
+/*! Log errors from SDK network requests */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorNetworkRequests;
+
+/*! Log errors likely to be preventable by the developer. This is in the default set of enabled logging behaviors. */
+FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorDeveloperErrors;
+
+@interface FBSDKSettings : NSObject
+
+/*!
+ @abstract Get the Facebook App ID used by the SDK.
+ @discussion If not explicitly set, the default will be read from the application's plist (FacebookAppID).
+ */
++ (NSString *)appID;
+
+/*!
+ @abstract Set the Facebook App ID to be used by the SDK.
+ @param appID The Facebook App ID to be used by the SDK.
+ */
++ (void)setAppID:(NSString *)appID;
+
+/*!
+ @abstract Get the default url scheme suffix used for sessions.
+ @discussion If not explicitly set, the default will be read from the application's plist (FacebookUrlSchemeSuffix).
+ */
++ (NSString *)appURLSchemeSuffix;
+
+/*!
+ @abstract Set the app url scheme suffix used by the SDK.
+ @param appURLSchemeSuffix The url scheme suffix to be used by the SDK.
+ */
++ (void)setAppURLSchemeSuffix:(NSString *)appURLSchemeSuffix;
+
+/*!
+ @abstract Retrieve the Client Token that has been set via [FBSDKSettings setClientToken].
+ @discussion If not explicitly set, the default will be read from the application's plist (FacebookClientToken).
+ */
++ (NSString *)clientToken;
+
+/*!
+ @abstract Sets the Client Token for the Facebook App.
+ @discussion This is needed for certain API calls when made anonymously, without a user-based access token.
+ @param clientToken The Facebook App's "client token", which, for a given appid can be found in the Security
+ section of the Advanced tab of the Facebook App settings found at
+ */
++ (void)setClientToken:(NSString *)clientToken;
+
+/*!
+ @abstract A convenient way to toggle error recovery for all FBSDKGraphRequest instances created after this is set.
+ @param disableGraphErrorRecovery YES or NO.
+ */
++ (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery;
+
+/*!
+ @abstract Get the Facebook Display Name used by the SDK.
+ @discussion If not explicitly set, the default will be read from the application's plist (FacebookDisplayName).
+ */
++ (NSString *)displayName;
+
+/*!
+ @abstract Set the default Facebook Display Name to be used by the SDK.
+ @discussion This should match the Display Name that has been set for the app with the corresponding Facebook App ID,
+ in the Facebook App Dashboard.
+ @param displayName The Facebook Display Name to be used by the SDK.
+ */
++ (void)setDisplayName:(NSString *)displayName;
+
+/*!
+ @abstract Get the Facebook domain part.
+ @discussion If not explicitly set, the default will be read from the application's plist (FacebookDomainPart).
+ */
++ (NSString *)facebookDomainPart;
+
+/*!
+ @abstract Set the subpart of the Facebook domain.
+ @discussion This can be used to change the Facebook domain (e.g. @"beta") so that requests will be sent to
+ graph.beta.facebook.com
+ @param facebookDomainPart The domain part to be inserted into facebook.com.
+ */
++ (void)setFacebookDomainPart:(NSString *)facebookDomainPart;
+
+/*!
+ @abstract The quality of JPEG images sent to Facebook from the SDK.
+ @discussion If not explicitly set, the default is 0.9.
+ @see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */
++ (CGFloat)JPEGCompressionQuality;
+
+/*!
+ @abstract Set the quality of JPEG images sent to Facebook from the SDK.
+ @param JPEGCompressionQuality The quality for JPEG images, expressed as a value from 0.0 to 1.0.
+ @see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */
++ (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality;
+
+/*!
+ @abstract
+ Gets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches.
+ */
++ (BOOL)limitEventAndDataUsage;
+
+/*!
+ @abstract
+ Sets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches.
+
+ @param limitEventAndDataUsage The desired value.
+ */
++ (void)setLimitEventAndDataUsage:(BOOL)limitEventAndDataUsage;
+
+/*!
+ @abstract Retrieve the current iOS SDK version.
+ */
++ (NSString *)sdkVersion;
+
+/*!
+ @abstract Retrieve the current Facebook SDK logging behavior.
+ */
++ (NSSet *)loggingBehavior;
+
+/*!
+ @abstract Set the current Facebook SDK logging behavior. This should consist of strings defined as
+ constants with FBSDKLoggingBehavior*.
+
+ @param loggingBehavior A set of strings indicating what information should be logged. If nil is provided, the logging
+ behavior is reset to the default set of enabled behaviors. Set to an empty set in order to disable all logging.
+
+ @discussion You can also define this via an array in your app plist with key "FacebookLoggingBehavior" or add and remove individual values via enableLoggingBehavior: or disableLogginBehavior:
+ */
++ (void)setLoggingBehavior:(NSSet *)loggingBehavior;
+
+/*!
+ @abstract Enable a particular Facebook SDK logging behavior.
+
+ @param loggingBehavior The LoggingBehavior to enable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
+ */
++ (void)enableLoggingBehavior:(NSString *)loggingBehavior;
+
+/*!
+ @abstract Disable a particular Facebook SDK logging behavior.
+
+ @param loggingBehavior The LoggingBehavior to disable. This should be a string defined as a constant with FBSDKLoggingBehavior*.
+ */
++ (void)disableLoggingBehavior:(NSString *)loggingBehavior;
+
+/*!
+ @abstract Set the user defaults key used by legacy token caches.
+
+ @param tokenInformationKeyName the key used by legacy token caches.
+
+ @discussion Use this only if you customized FBSessionTokenCachingStrategy in v3.x of
+ the Facebook SDK for iOS.
+*/
++ (void)setLegacyUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName;
+
+/*!
+ @abstract Get the user defaults key used by legacy token caches.
+*/
++ (NSString *)legacyUserDefaultTokenInformationKeyName;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKTestUsersManager.h b/FBSDKCoreKit.framework/Headers/FBSDKTestUsersManager.h
new file mode 100644
index 0000000..7d2e0ac
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKTestUsersManager.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 FBSDKAccessToken;
+
+/*!
+ @typedef
+
+ @abstract Callback block for returning an array of FBSDKAccessToken instances (and possibly `NSNull` instances); or an error.
+ */
+typedef void (^FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)(NSArray *tokens, NSError *error) ;
+
+/*!
+ @typedef
+
+ @abstract Callback block for removing a test user.
+ */
+typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ;
+
+
+/*!
+ @class FBSDKTestUsersManager
+ @abstract Provides methods for managing test accounts for testing Facebook integration.
+
+ @discussion Facebook allows developers to create test accounts for testing their applications'
+ Facebook integration (see https://developers.facebook.com/docs/test_users/). This class
+ simplifies use of these accounts for writing tests. It is not designed for use in
+ production application code.
+
+ This class will make Graph API calls on behalf of your app to manage test accounts and requires
+ an app id and app secret. You will typically use this class to write unit or integration tests.
+ Make sure you NEVER include your app secret in your production app.
+ */
+@interface FBSDKTestUsersManager : NSObject
+
+/*!
+ @abstract construct or return the shared instance
+ @param appID the Facebook app id
+ @param appSecret the Facebook app secret
+ */
++ (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret;
+
+/*!
+ @abstract retrieve FBSDKAccessToken instances for test accounts with the specific permissions.
+ @param arraysOfPermissions an array of permissions sets, such as @[ [NSSet setWithObject:@"email"], [NSSet setWithObject:@"user_birthday"]]
+ if you needed two test accounts with email and birthday permissions, respectively. You can pass in empty nested sets
+ if you need two arbitrary test accounts. For convenience, passing nil is treated as @[ [NSSet set] ]
+ for fetching a single test user.
+ @param createIfNotFound if YES, new test accounts are created if no test accounts existed that fit the permissions
+ requirement
+ @param handler the callback to invoke which will return an array of `FBAccessTokenData` instances or an `NSError`.
+ If param `createIfNotFound` is NO, the array may contain `[NSNull null]` instances.
+
+ @discussion If you are requesting test accounts with differing number of permissions, try to order
+ `arrayOfPermissionsArrays` so that the most number of permissions come first to minimize creation of new
+ test accounts.
+ */
+- (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *)arraysOfPermissions
+ createIfNotFound:(BOOL)createIfNotFound
+ completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler;
+
+/*!
+ @abstract add a test account with the specified permissions
+ @param permissions the set of permissions, e.g., [NSSet setWithObjects:@"email", @"user_friends"]
+ @param handler the callback handler
+ */
+- (void)addTestAccountWithPermissions:(NSSet *)permissions
+ completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler;
+
+/*!
+ @abstract remove a test account for the given user id
+ @param userId the user id
+ @param handler the callback handler
+ */
+- (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKTestUsersManagerRemoveTestAccountHandler)handler;
+
+/*!
+ @abstract Make two test users friends with each other.
+ @param first the token of the first user
+ @param second the token of the second user
+ @param callback the callback handler
+ */
+- (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(void (^)(NSError *))callback;
+
+@end
diff --git a/FBSDKCoreKit.framework/Headers/FBSDKUtility.h b/FBSDKCoreKit.framework/Headers/FBSDKUtility.h
new file mode 100644
index 0000000..46c490b
--- /dev/null
+++ b/FBSDKCoreKit.framework/Headers/FBSDKUtility.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @abstract Class to contain common utility methods.
+ */
+@interface FBSDKUtility : NSObject
+
+/*!
+ @abstract Parses a query string into a dictionary.
+ @param queryString The query string value.
+ @return A dictionary with the key/value pairs.
+ */
++ (NSDictionary *)dictionaryWithQueryString:(NSString *)queryString;
+
+/*!
+ @abstract Constructs a query string from a dictionary.
+ @param dictionary The dictionary with key/value pairs for the query string.
+ @param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
+ @result Query string representation of the parameters.
+ */
++ (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef;
+
+/*!
+ @abstract Decodes a value from an URL.
+ @param value The value to decode.
+ @result The decoded value.
+ */
++ (NSString *)URLDecode:(NSString *)value;
+
+/*!
+ @abstract Encodes a value for an URL.
+ @param value The value to encode.
+ @result The encoded value.
+ */
++ (NSString *)URLEncode:(NSString *)value;
+
+@end
diff --git a/FBSDKCoreKit.framework/Info.plist b/FBSDKCoreKit.framework/Info.plist
new file mode 100644
index 0000000..b6dda8e
Binary files /dev/null and b/FBSDKCoreKit.framework/Info.plist differ
diff --git a/FBSDKCoreKit.framework/Modules/module.modulemap b/FBSDKCoreKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..3c3e6e6
--- /dev/null
+++ b/FBSDKCoreKit.framework/Modules/module.modulemap
@@ -0,0 +1,31 @@
+framework module FBSDKCoreKit {
+ umbrella header "FBSDKCoreKit.h"
+
+ export *
+ module * { export * }
+
+ explicit module FBSDKButton {
+ header "FBSDKButton.h"
+ export *
+ }
+
+ explicit module FBSDKAppLinkResolver {
+ header "FBSDKAppLinkResolver.h"
+ export *
+ }
+
+ explicit module FBSDKGraphErrorRecoveryProcessor {
+ header "FBSDKGraphErrorRecoveryProcessor.h"
+ export *
+ }
+
+ explicit module FBSDKGraphRequestDataAttachment {
+ header "FBSDKGraphRequestDataAttachment.h"
+ export *
+ }
+
+ explicit module FBSDKTestUsersManager {
+ header "FBSDKTestUsersManager.h"
+ export *
+ }
+}
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKAccessTokenCacheV4.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKAccessTokenCacheV4.h
new file mode 100644
index 0000000..7fa7d7f
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKAccessTokenCacheV4.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import "FBSDKAccessToken.h"
+#import "FBSDKAccessTokenCaching.h"
+
+@interface FBSDKAccessTokenCacheV4 : NSObject
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPICrypto.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPICrypto.h
new file mode 100644
index 0000000..7d488e7
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPICrypto.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import "FBSDKBridgeAPIRequest.h"
+
+@interface FBSDKBridgeAPICrypto : NSObject
+
++ (void)addCipherKeyToQueryParameters:(NSMutableDictionary *)queryParameters;
++ (NSDictionary *)decryptResponseForRequest:(FBSDKBridgeAPIRequest *)request
+ queryParameters:(NSDictionary *)queryParameters
+ error:(NSError *__autoreleasing *)errorRef;
++ (void)reset;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocol.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocol.h
new file mode 100644
index 0000000..679577c
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocol.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+#import "FBSDKBridgeAPIProtocolType.h"
+
+@class FBSDKBridgeAPIRequest;
+
+FBSDK_EXTERN NSString *const FBSDKBridgeAPIAppIDKey;
+FBSDK_EXTERN NSString *const FBSDKBridgeAPISchemeSuffixKey;
+FBSDK_EXTERN NSString *const FBSDKBridgeAPIVersionKey;
+
+@protocol FBSDKBridgeAPIProtocol
+
+- (NSURL *)requestURLWithActionID:(NSString *)actionID
+ scheme:(NSString *)scheme
+ methodName:(NSString *)methodName
+ methodVersion:(NSString *)methodVersion
+ parameters:(NSDictionary *)parameters
+ error:(NSError *__autoreleasing *)errorRef;
+- (NSDictionary *)responseParametersForActionID:(NSString *)actionID
+ queryParameters:(NSDictionary *)queryParameters
+ cancelled:(BOOL *)cancelledRef
+ error:(NSError *__autoreleasing *)errorRef;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolNativeV1.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolNativeV1.h
new file mode 100644
index 0000000..8fd34bd
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolNativeV1.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+#import "FBSDKBridgeAPIProtocol.h"
+
+typedef struct
+{
+ __unsafe_unretained NSString *bridgeArgs;
+ __unsafe_unretained NSString *methodArgs;
+ __unsafe_unretained NSString *methodVersion;
+} FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct;
+FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct FBSDKBridgeAPIProtocolNativeV1OutputKeys;
+
+typedef struct
+{
+ __unsafe_unretained NSString *actionID;
+ __unsafe_unretained NSString *appIcon;
+ __unsafe_unretained NSString *appName;
+ __unsafe_unretained NSString *sdkVersion;
+} FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeysStruct;
+FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys;
+
+typedef struct
+{
+ __unsafe_unretained NSString *bridgeArgs;
+ __unsafe_unretained NSString *methodResults;
+} FBSDKBridgeAPIProtocolNativeV1InputKeysStruct;
+FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1InputKeysStruct FBSDKBridgeAPIProtocolNativeV1InputKeys;
+
+typedef struct
+{
+ __unsafe_unretained NSString *actionID;
+ __unsafe_unretained NSString *error;
+} FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeysStruct;
+FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys;
+
+@interface FBSDKBridgeAPIProtocolNativeV1 : NSObject
+
+- (instancetype)initWithAppScheme:(NSString *)appScheme;
+- (instancetype)initWithAppScheme:(NSString *)appScheme
+ pasteboard:(UIPasteboard *)pasteboard
+ dataLengthThreshold:(NSUInteger)dataLengthThreshold
+ includeAppIcon:(BOOL)includeAppIcon
+NS_DESIGNATED_INITIALIZER;
+
+@property (nonatomic, copy, readonly) NSString *appScheme;
+@property (nonatomic, assign, readonly) NSUInteger dataLengthThreshold;
+@property (nonatomic, assign, readonly) BOOL includeAppIcon;
+@property (nonatomic, strong, readonly) UIPasteboard *pasteboard;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolWebV1.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolWebV1.h
new file mode 100644
index 0000000..c7b28f4
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKBridgeAPIProtocolWebV1.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import "FBSDKBridgeAPIProtocol.h"
+
+@interface FBSDKBridgeAPIProtocolWebV1 : NSObject
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKError.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKError.h
new file mode 100644
index 0000000..f37bd86
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKError.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+@interface FBSDKError : NSObject
+
++ (NSString *)errorDomain;
+
++ (BOOL)errorIsNetworkError:(NSError *)error;
+
++ (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message;
++ (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message underlyingError:(NSError *)underlyingError;
++ (NSError *)errorWithCode:(NSInteger)code
+ userInfo:(NSDictionary *)userInfo
+ message:(NSString *)message
+ underlyingError:(NSError *)underlyingError;
+
++ (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message;
++ (NSError *)invalidArgumentErrorWithName:(NSString *)name
+ value:(id)value
+ message:(NSString *)message
+ underlyingError:(NSError *)underlyingError;
++ (NSError *)invalidCollectionErrorWithName:(NSString *)name
+ collection:(id)collection
+ item:(id)item
+ message:(NSString *)message;
++ (NSError *)invalidCollectionErrorWithName:(NSString *)name
+ collection:(id)collection
+ item:(id)item
+ message:(NSString *)message
+ underlyingError:(NSError *)underlyingError;
+
++ (NSError *)requiredArgumentErrorWithName:(NSString *)name message:(NSString *)message;
++ (NSError *)requiredArgumentErrorWithName:(NSString *)name
+ message:(NSString *)message
+ underlyingError:(NSError *)underlyingError;
+
++ (NSError *)unknownErrorWithMessage:(NSString *)message;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestBody.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestBody.h
new file mode 100644
index 0000000..b61c782
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestBody.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+#import
+
+@class FBSDKGraphRequestDataAttachment;
+@class FBSDKLogger;
+
+@interface FBSDKGraphRequestBody : NSObject
+
+@property (nonatomic, retain, readonly) NSData *data;
+
+- (void)appendWithKey:(NSString *)key
+ formValue:(NSString *)value
+ logger:(FBSDKLogger *)logger;
+
+- (void)appendWithKey:(NSString *)key
+ imageValue:(UIImage *)image
+ logger:(FBSDKLogger *)logger;
+
+- (void)appendWithKey:(NSString *)key
+ dataValue:(NSData *)data
+ logger:(FBSDKLogger *)logger;
+
+- (void)appendWithKey:(NSString *)key
+ dataAttachmentValue:(FBSDKGraphRequestDataAttachment *)dataAttachment
+ logger:(FBSDKLogger *)logger;
+
++ (NSString *)mimeContentType;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestMetadata.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestMetadata.h
new file mode 100644
index 0000000..cd218c4
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKGraphRequestMetadata.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+// Internal only class to facilitate FBSDKGraphRequest processing, specifically
+// associating FBSDKGraphRequest and FBSDKGraphRequestHandler instances and necessary
+// data for retry processing.
+@interface FBSDKGraphRequestMetadata : NSObject
+
+@property (nonatomic, retain) FBSDKGraphRequest *request;
+@property (nonatomic, copy) FBSDKGraphRequestHandler completionHandler;
+@property (nonatomic, copy) NSDictionary *batchParameters;
+
+- (instancetype)initWithRequest:(FBSDKGraphRequest *)request
+ completionHandler:(FBSDKGraphRequestHandler)handler
+ batchParameters:(NSDictionary *)batchParameters
+NS_DESIGNATED_INITIALIZER;
+
+- (void)invokeCompletionHandlerForConnection:(FBSDKGraphRequestConnection *)connection
+ withResults:(id)results
+ error:(NSError *)error;
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKURLConnection.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKURLConnection.h
new file mode 100644
index 0000000..cbe80a0
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKURLConnection.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 FBSDKURLConnection;
+
+typedef void (^FBSDKURLConnectionHandler)(FBSDKURLConnection *connection,
+ NSError *error,
+ NSURLResponse *response,
+ NSData *responseData);
+
+@protocol FBSDKURLConnectionDelegate
+
+@optional
+
+- (void)facebookURLConnection:(FBSDKURLConnection *)connection
+ didSendBodyData:(NSInteger)bytesWritten
+ totalBytesWritten:(NSInteger)totalBytesWritten
+ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
+
+@end
+
+@interface FBSDKURLConnection : NSObject
+
+- (FBSDKURLConnection *)initWithRequest:(NSURLRequest *)request
+ completionHandler:(FBSDKURLConnectionHandler)handler
+NS_DESIGNATED_INITIALIZER;
+
+@property (nonatomic, assign) id delegate;
+
+- (void)cancel;
+- (void)start;
+- (void)setDelegateQueue:(NSOperationQueue *)queue;
+
+@end
diff --git a/FBSDKCoreKit.framework/PrivateHeaders/FBSDKWebDialogView.h b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKWebDialogView.h
new file mode 100644
index 0000000..9ad7427
--- /dev/null
+++ b/FBSDKCoreKit.framework/PrivateHeaders/FBSDKWebDialogView.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+@protocol FBSDKWebDialogViewDelegate;
+
+@interface FBSDKWebDialogView : UIView
+
+@property (nonatomic, assign) id delegate;
+
+- (void)loadURL:(NSURL *)URL;
+- (void)stopLoading;
+
+@end
+
+@protocol FBSDKWebDialogViewDelegate
+
+- (void)webDialogView:(FBSDKWebDialogView *)webDialogView didCompleteWithResults:(NSDictionary *)results;
+- (void)webDialogView:(FBSDKWebDialogView *)webDialogView didFailWithError:(NSError *)error;
+- (void)webDialogViewDidCancel:(FBSDKWebDialogView *)webDialogView;
+- (void)webDialogViewDidFinishLoad:(FBSDKWebDialogView *)webDialogView;
+
+@end
diff --git a/FBSDKLoginKit.framework/FBSDKLoginKit b/FBSDKLoginKit.framework/FBSDKLoginKit
new file mode 100644
index 0000000..d6b45c5
Binary files /dev/null and b/FBSDKLoginKit.framework/FBSDKLoginKit differ
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginButton.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginButton.h
new file mode 100644
index 0000000..51499d4
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginButton.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+#import
+
+#import "FBSDKTooltipView.h"
+
+@protocol FBSDKLoginButtonDelegate;
+
+/*!
+ @typedef NS_ENUM(NSUInteger, FBSDKLoginButtonTooltipBehavior)
+ @abstract Indicates the desired login tooltip behavior.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKLoginButtonTooltipBehavior)
+{
+ /*! The default behavior. The tooltip will only be displayed if
+ the app is eligible (determined by possible server round trip) */
+ FBSDKLoginButtonTooltipBehaviorAutomatic = 0,
+ /*! Force display of the tooltip (typically for UI testing) */
+ FBSDKLoginButtonTooltipBehaviorForceDisplay = 1,
+ /*! Force disable. In this case you can still exert more refined
+ control by manually constructing a `FBSDKLoginTooltipView` instance. */
+ FBSDKLoginButtonTooltipBehaviorDisable = 2
+};
+
+/*!
+ @abstract A button that initiates a log in or log out flow upon tapping.
+ @discussion `FBSDKLoginButton` works with `[FBSDKAccessToken currentAccessToken]` to
+ determine what to display, and automatically starts authentication when tapped (i.e.,
+ you do not need to manually subscribe action targets).
+
+ Like `FBSDKLoginManager`, you should make sure your app delegate is connected to
+ `FBSDKApplicationDelegate` in order for the button's delegate to receive messages.
+
+ `FBSDKLoginButton` has a fixed height, but you may change the width. `initWithFrame:CGRectZero`
+ will size the button to its minimum frame.
+*/
+@interface FBSDKLoginButton : FBSDKButton
+
+/*!
+ @abstract The default audience to use, if publish permissions are requested at login time.
+ */
+@property (assign, nonatomic) FBSDKDefaultAudience defaultAudience;
+/*!
+ @abstract Gets or sets the delegate.
+ */
+@property (weak, nonatomic) IBOutlet id delegate;
+/*!
+ @abstract Gets or sets the login behavior to use
+ */
+@property (assign, nonatomic) FBSDKLoginBehavior loginBehavior;
+/*!
+ @abstract The publish permissions to request.
+
+ @discussion Use `defaultAudience` to specify the default audience to publish to.
+ Note this is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ */
+@property (copy, nonatomic) NSArray *publishPermissions;
+/*!
+ @abstract The read permissions to request.
+
+ @discussion Note, that if read permissions are specified, then publish permissions should not be specified. This is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ */
+@property (copy, nonatomic) NSArray *readPermissions;
+/*!
+ @abstract Gets or sets the desired tooltip behavior.
+ */
+@property (assign, nonatomic) FBSDKLoginButtonTooltipBehavior tooltipBehavior;
+/*!
+ @abstract Gets or sets the desired tooltip color style.
+ */
+@property (assign, nonatomic) FBSDKTooltipColorStyle tooltipColorStyle;
+
+@end
+
+/*!
+ @protocol
+ @abstract A delegate for `FBSDKLoginButton`
+ */
+@protocol FBSDKLoginButtonDelegate
+
+@required
+/*!
+ @abstract Sent to the delegate when the button was used to login.
+ @param loginButton the sender
+ @param result The results of the login
+ @param error The error (if any) from the login
+ */
+- (void) loginButton:(FBSDKLoginButton *)loginButton
+didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
+ error:(NSError *)error;
+
+/*!
+ @abstract Sent to the delegate when the button was used to logout.
+ @param loginButton The button that was clicked.
+*/
+- (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton;
+
+@optional
+/*!
+ @abstract Sent to the delegate when the button is about to login.
+ @param loginButton the sender
+ @return YES if the login should be allowed to proceed, NO otherwise
+ */
+- (BOOL) loginButtonWillLogin:(FBSDKLoginButton *)loginButton;
+
+@end
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginConstants.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginConstants.h
new file mode 100644
index 0000000..100c09a
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginConstants.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+/*!
+ @abstract The error domain for all errors from FBSDKLoginKit
+ @discussion Error codes from the SDK in the range 300-399 are reserved for this domain.
+ */
+FBSDK_EXTERN NSString *const FBSDKLoginErrorDomain;
+
+/*!
+ @typedef NS_ENUM(NSInteger, FBSDKLoginErrorCode)
+ @abstract Error codes for FBSDKLoginErrorDomain.
+ */
+typedef NS_ENUM(NSInteger, FBSDKLoginErrorCode)
+{
+ /*!
+ @abstract Reserved.
+ */
+ FBSDKLoginReservedErrorCode = 300,
+ /*!
+ @abstract The error code for unknown errors.
+ */
+ FBSDKLoginUnknownErrorCode,
+
+ /*!
+ @abstract The user's password has changed and must log in again
+ */
+ FBSDKLoginPasswordChangedErrorCode,
+ /*!
+ @abstract The user must log in to their account on www.facebook.com to restore access
+ */
+ FBSDKLoginUserCheckpointedErrorCode,
+ /*!
+ @abstract Indicates a failure to request new permissions because the user has changed.
+ */
+ FBSDKLoginUserMismatchErrorCode,
+ /*!
+ @abstract The user must confirm their account with Facebook before logging in
+ */
+ FBSDKLoginUnconfirmedUserErrorCode,
+
+ /*!
+ @abstract The Accounts framework failed without returning an error, indicating the
+ app's slider in the iOS Facebook Settings (device Settings -> Facebook -> App Name) has
+ been disabled.
+ */
+ FBSDKLoginSystemAccountAppDisabledErrorCode,
+ /*!
+ @abstract An error occurred related to Facebook system Account store
+ */
+ FBSDKLoginSystemAccountUnavailableErrorCode,
+ /*!
+ @abstract The login response was missing a valid challenge string.
+ */
+ FBSDKLoginBadChallengeString,
+};
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginKit.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginKit.h
new file mode 100644
index 0000000..4723940
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginKit.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+#import
+#import
+#import
+#import
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginManager.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginManager.h
new file mode 100644
index 0000000..ee35bd8
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginManager.h
@@ -0,0 +1,202 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+#import
+#import
+
+@class FBSDKLoginManagerLoginResult;
+
+/*!
+ @abstract Describes the call back to the FBSDKLoginManager
+ @param result the result of the authorization
+ @param error the authorization error, if any.
+ */
+typedef void (^FBSDKLoginManagerRequestTokenHandler)(FBSDKLoginManagerLoginResult *result, NSError *error);
+
+
+/*!
+ @typedef FBSDKDefaultAudience enum
+
+ @abstract
+ Passed to open to indicate which default audience to use for sessions that post data to Facebook.
+
+ @discussion
+ Certain operations such as publishing a status or publishing a photo require an audience. When the user
+ grants an application permission to perform a publish operation, a default audience is selected as the
+ publication ceiling for the application. This enumerated value allows the application to select which
+ audience to ask the user to grant publish permission for.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKDefaultAudience)
+{
+ /*! Indicates that the user's friends are able to see posts made by the application */
+ FBSDKDefaultAudienceFriends = 0,
+ /*! Indicates that only the user is able to see posts made by the application */
+ FBSDKDefaultAudienceOnlyMe,
+ /*! Indicates that all Facebook users are able to see posts made by the application */
+ FBSDKDefaultAudienceEveryone,
+};
+
+/*!
+ @typedef FBSDKLoginBehavior enum
+
+ @abstract
+ Passed to the \c FBSDKLoginManager to indicate how Facebook Login should be attempted.
+
+ @discussion
+ Facebook Login authorizes the application to act on behalf of the user, using the user's
+ Facebook account. Usually a Facebook Login will rely on an account maintained outside of
+ the application, by the native Facebook application, the browser, or perhaps the device
+ itself. This avoids the need for a user to enter their username and password directly, and
+ provides the most secure and lowest friction way for a user to authorize the application to
+ interact with Facebook.
+
+ The \c FBSDKLoginBehavior enum specifies which log-in methods may be used. The SDK
+ will determine the best behavior based on the current device (such as iOS version).
+ */
+typedef NS_ENUM(NSUInteger, FBSDKLoginBehavior)
+{
+ /*!
+ @abstract This is the default behavior, and indicates logging in through the native
+ Facebook app may be used. The SDK may still use Safari instead.
+ */
+ FBSDKLoginBehaviorNative = 0,
+ /*!
+ @abstract Attempts log in through the Safari or SFSafariViewController, if available.
+ */
+ FBSDKLoginBehaviorBrowser,
+ /*!
+ @abstract Attempts log in through the Facebook account currently signed in through
+ the device Settings.
+ @note If the account is not available to the app (either not configured by user or
+ as determined by the SDK) this behavior falls back to \c FBSDKLoginBehaviorNative.
+ */
+ FBSDKLoginBehaviorSystemAccount,
+ /*!
+ @abstract Attemps log in through a modal \c UIWebView pop up
+
+ @note This behavior is only available to certain types of apps. Please check the Facebook
+ Platform Policy to verify your app meets the restrictions.
+ */
+ FBSDKLoginBehaviorWeb,
+};
+
+/*!
+ @abstract `FBSDKLoginManager` provides methods for logging the user in and out.
+ @discussion `FBSDKLoginManager` works directly with `[FBSDKAccessToken currentAccessToken]` and
+ sets the "currentAccessToken" upon successful authorizations (or sets `nil` in case of `logOut`).
+
+ You should check `[FBSDKAccessToken currentAccessToken]` before calling logIn* to see if there is
+ a cached token available (typically in your viewDidLoad).
+
+ If you are managing your own token instances outside of "currentAccessToken", you will need to set
+ "currentAccessToken" before calling logIn* to authorize futher permissions on your tokens.
+ */
+@interface FBSDKLoginManager : NSObject
+
+/*!
+ @abstract the default audience.
+ @discussion you should set this if you intend to ask for publish permissions.
+ */
+@property (assign, nonatomic) FBSDKDefaultAudience defaultAudience;
+
+/*!
+ @abstract the login behavior
+ */
+@property (assign, nonatomic) FBSDKLoginBehavior loginBehavior;
+
+/*!
+ @deprecated use logInWithReadPermissions:fromViewController:handler: instead
+ */
+- (void)logInWithReadPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler
+__attribute__ ((deprecated("use logInWithReadPermissions:fromViewController:handler: instead")));
+
+/*!
+ @deprecated use logInWithPublishPermissions:fromViewController:handler: instead
+ */
+- (void)logInWithPublishPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler
+__attribute__ ((deprecated("use logInWithPublishPermissions:fromViewController:handler: instead")));
+
+/*!
+ @abstract Logs the user in or authorizes additional permissions.
+ @param permissions the optional array of permissions. Note this is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ @param fromViewController the view controller to present from. If nil, the topmost view controller will be
+ automatically determined as best as possible.
+ @param handler the callback.
+ @discussion Use this method when asking for read permissions. You should only ask for permissions when they
+ are needed and explain the value to the user. You can inspect the result.declinedPermissions to also
+ provide more information to the user if they decline permissions.
+
+ If `[FBSDKAccessToken currentAccessToken]` is not nil, it will be treated as a reauthorization for that user
+ and will pass the "rerequest" flag to the login dialog.
+
+ This method will present UI the user. You typically should check if `[FBSDKAccessToken currentAccessToken]`
+ already contains the permissions you need before asking to reduce unnecessary app switching. For example,
+ you could make that check at viewDidLoad.
+ */
+- (void)logInWithReadPermissions:(NSArray *)permissions
+ fromViewController:(UIViewController *)fromViewController
+ handler:(FBSDKLoginManagerRequestTokenHandler)handler;
+
+/*!
+ @abstract Logs the user in or authorizes additional permissions.
+ @param permissions the optional array of permissions. Note this is converted to NSSet and is only
+ an NSArray for the convenience of literal syntax.
+ @param fromViewController the view controller to present from. If nil, the topmost view controller will be
+ automatically determined as best as possible.
+ @param handler the callback.
+ @discussion Use this method when asking for publish permissions. You should only ask for permissions when they
+ are needed and explain the value to the user. You can inspect the result.declinedPermissions to also
+ provide more information to the user if they decline permissions.
+
+ If `[FBSDKAccessToken currentAccessToken]` is not nil, it will be treated as a reauthorization for that user
+ and will pass the "rerequest" flag to the login dialog.
+
+ This method will present UI the user. You typically should check if `[FBSDKAccessToken currentAccessToken]`
+ already contains the permissions you need before asking to reduce unnecessary app switching. For example,
+ you could make that check at viewDidLoad.
+ */
+- (void)logInWithPublishPermissions:(NSArray *)permissions
+ fromViewController:(UIViewController *)fromViewController
+ handler:(FBSDKLoginManagerRequestTokenHandler)handler;
+
+/*!
+ @abstract Logs the user out
+ @discussion This calls [FBSDKAccessToken setCurrentAccessToken:nil] and [FBSDKProfile setCurrentProfile:nil].
+ */
+- (void)logOut;
+
+/*!
+ @method
+
+ @abstract Issues an asychronous renewCredentialsForAccount call to the device's Facebook account store.
+
+ @param handler The completion handler to call when the renewal is completed. This can be invoked on an arbitrary thread.
+
+ @discussion This can be used to explicitly renew account credentials and is provided as a convenience wrapper around
+ `[ACAccountStore renewCredentialsForAccount:completion]`. Note the method will not issue the renewal call if the the
+ Facebook account has not been set on the device, or if access had not been granted to the account (though the handler
+ wil receive an error).
+
+ If the `[FBSDKAccessToken currentAccessToken]` was from the account store, a succesful renewal will also set
+ a new "currentAccessToken".
+ */
++ (void)renewSystemCredentials:(void (^)(ACAccountCredentialRenewResult result, NSError *error))handler;
+
+@end
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginManagerLoginResult.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginManagerLoginResult.h
new file mode 100644
index 0000000..36a1af6
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginManagerLoginResult.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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 FBSDKAccessToken;
+
+/*!
+ @abstract Describes the result of a login attempt.
+ */
+@interface FBSDKLoginManagerLoginResult : NSObject
+
+/*!
+ @abstract the access token.
+ */
+@property (copy, nonatomic) FBSDKAccessToken *token;
+
+/*!
+ @abstract whether the login was cancelled by the user.
+ */
+@property (readonly, nonatomic) BOOL isCancelled;
+
+/*!
+ @abstract the set of permissions granted by the user in the associated request.
+ @discussion inspect the token's permissions set for a complete list.
+ */
+@property (copy, nonatomic) NSSet *grantedPermissions;
+
+/*!
+ @abstract the set of permissions declined by the user in the associated request.
+ @discussion inspect the token's permissions set for a complete list.
+ */
+@property (copy, nonatomic) NSSet *declinedPermissions;
+
+/*!
+ @abstract Initializes a new instance.
+ @param token the access token
+ @param isCancelled whether the login was cancelled by the user
+ @param grantedPermissions the set of granted permissions
+ @param declinedPermissions the set of declined permissions
+ */
+- (instancetype)initWithToken:(FBSDKAccessToken *)token
+ isCancelled:(BOOL)isCancelled
+ grantedPermissions:(NSSet *)grantedPermissions
+ declinedPermissions:(NSSet *)declinedPermissions
+NS_DESIGNATED_INITIALIZER;
+@end
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKLoginTooltipView.h b/FBSDKLoginKit.framework/Headers/FBSDKLoginTooltipView.h
new file mode 100644
index 0000000..e6a9411
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKLoginTooltipView.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+#import
+
+@protocol FBSDKLoginTooltipViewDelegate;
+
+/*!
+ @class FBSDKLoginTooltipView
+
+ @abstract Represents a tooltip to be displayed next to a Facebook login button
+ to highlight features for new users.
+
+ @discussion The `FBSDKLoginButton` may display this view automatically. If you do
+ not use the `FBSDKLoginButton`, you can manually call one of the `present*` methods
+ as appropriate and customize behavior via `FBSDKLoginTooltipViewDelegate` delegate.
+
+ By default, the `FBSDKLoginTooltipView` is not added to the superview until it is
+ determined the app has migrated to the new login experience. You can override this
+ (e.g., to test the UI layout) by implementing the delegate or setting `forceDisplay` to YES.
+
+ */
+@interface FBSDKLoginTooltipView : FBSDKTooltipView
+
+/*! @abstract the delegate */
+@property (nonatomic, assign) id delegate;
+
+/*! @abstract if set to YES, the view will always be displayed and the delegate's
+ `loginTooltipView:shouldAppear:` will NOT be called. */
+@property (nonatomic, assign) BOOL forceDisplay;
+
+@end
+
+/*!
+ @protocol
+
+ @abstract
+ The `FBSDKLoginTooltipViewDelegate` protocol defines the methods used to receive event
+ notifications from `FBSDKLoginTooltipView` objects.
+ */
+@protocol FBSDKLoginTooltipViewDelegate
+
+@optional
+
+/*!
+ @abstract
+ Asks the delegate if the tooltip view should appear
+
+ @param view The tooltip view.
+ @param appIsEligible The value fetched from the server identifying if the app
+ is eligible for the new login experience.
+
+ @discussion Use this method to customize display behavior.
+ */
+- (BOOL)loginTooltipView:(FBSDKLoginTooltipView *)view shouldAppear:(BOOL)appIsEligible;
+
+/*!
+ @abstract
+ Tells the delegate the tooltip view will appear, specifically after it's been
+ added to the super view but before the fade in animation.
+
+ @param view The tooltip view.
+ */
+- (void)loginTooltipViewWillAppear:(FBSDKLoginTooltipView *)view;
+
+/*!
+ @abstract
+ Tells the delegate the tooltip view will not appear (i.e., was not
+ added to the super view).
+
+ @param view The tooltip view.
+ */
+- (void)loginTooltipViewWillNotAppear:(FBSDKLoginTooltipView *)view;
+
+
+@end
diff --git a/FBSDKLoginKit.framework/Headers/FBSDKTooltipView.h b/FBSDKLoginKit.framework/Headers/FBSDKTooltipView.h
new file mode 100644
index 0000000..aff1067
--- /dev/null
+++ b/FBSDKLoginKit.framework/Headers/FBSDKTooltipView.h
@@ -0,0 +1,141 @@
+// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
+//
+// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
+// copy, modify, and distribute this software in source code or binary form for use
+// in connection with the web services and APIs provided by Facebook.
+//
+// As with any software that integrates with the Facebook platform, your use of
+// this software is subject to the Facebook Developer Principles and Policies
+// [http://developers.facebook.com/policy/]. This copyright 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
+
+/*!
+ @typedef FBSDKTooltipViewArrowDirection enum
+
+ @abstract
+ Passed on construction to determine arrow orientation.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKTooltipViewArrowDirection)
+{
+ /*! View is located above given point, arrow is pointing down. */
+ FBSDKTooltipViewArrowDirectionDown = 0,
+ /*! View is located below given point, arrow is pointing up. */
+ FBSDKTooltipViewArrowDirectionUp = 1,
+};
+
+/*!
+ @typedef FBSDKTooltipColorStyle enum
+
+ @abstract
+ Passed on construction to determine color styling.
+ */
+typedef NS_ENUM(NSUInteger, FBSDKTooltipColorStyle)
+{
+ /*! Light blue background, white text, faded blue close button. */
+ FBSDKTooltipColorStyleFriendlyBlue = 0,
+ /*! Dark gray background, white text, light gray close button. */
+ FBSDKTooltipColorStyleNeutralGray = 1,
+};
+
+/*!
+ @class FBSDKTooltipView
+
+ @abstract
+ Tooltip bubble with text in it used to display tips for UI elements,
+ with a pointed arrow (to refer to the UI element).
+
+ @discussion
+ The tooltip fades in and will automatically fade out. See `displayDuration`.
+ */
+@interface FBSDKTooltipView : UIView
+
+/*!
+ @abstract Gets or sets the amount of time in seconds the tooltip should be displayed.
+
+ @discussion Set this to zero to make the display permanent until explicitly dismissed.
+ Defaults to six seconds.
+ */
+@property (nonatomic, assign) CFTimeInterval displayDuration;
+
+/*!
+ @abstract Gets or sets the color style after initialization.
+
+ @discussion Defaults to value passed to -initWithTagline:message:colorStyle:.
+ */
+@property (nonatomic, assign) FBSDKTooltipColorStyle colorStyle;
+
+/*!
+ @abstract Gets or sets the message.
+ */
+@property (nonatomic, copy) NSString *message;
+
+/*!
+ @abstract Gets or sets the optional phrase that comprises the first part of the label (and is highlighted differently).
+ */
+@property (nonatomic, copy) NSString *tagline;
+
+/*!
+ @abstract
+ Designated initializer.
+
+ @param tagline First part of the label, that will be highlighted with different color. Can be nil.
+
+ @param message Main message to display.
+
+ @param colorStyle Color style to use for tooltip.
+
+ @discussion
+ If you need to show a tooltip for login, consider using the `FBSDKLoginTooltipView` view.
+
+ @see FBSDKLoginTooltipView
+ */
+- (instancetype)initWithTagline:(NSString *)tagline message:(NSString *)message colorStyle:(FBSDKTooltipColorStyle)colorStyle;
+
+/*!
+ @abstract
+ Show tooltip at the top or at the bottom of given view.
+ Tooltip will be added to anchorView.window.rootViewController.view
+
+ @param anchorView view to show at, must be already added to window view hierarchy, in order to decide
+ where tooltip will be shown. (If there's not enough space at the top of the anchorView in window bounds -
+ tooltip will be shown at the bottom of it)
+
+ @discussion
+ Use this method to present the tooltip with automatic positioning or
+ use -presentInView:withArrowPosition:direction: for manual positioning
+ If anchorView is nil or has no window - this method does nothing.
+ */
+- (void)presentFromView:(UIView *)anchorView;
+
+/*!
+ @abstract
+ Adds tooltip to given view, with given position and arrow direction.
+
+ @param view View to be used as superview.
+
+ @param arrowPosition Point in view's cordinates, where arrow will be pointing
+
+ @param arrowDirection whenever arrow should be pointing up (message bubble is below the arrow) or
+ down (message bubble is above the arrow).
+ */
+- (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition direction:(FBSDKTooltipViewArrowDirection)arrowDirection;
+
+/*!
+ @abstract
+ Remove tooltip manually.
+
+ @discussion
+ Calling this method isn't necessary - tooltip will dismiss itself automatically after the `displayDuration`.
+ */
+- (void)dismiss;
+
+@end
diff --git a/FBSDKLoginKit.framework/Info.plist b/FBSDKLoginKit.framework/Info.plist
new file mode 100644
index 0000000..ad88b51
Binary files /dev/null and b/FBSDKLoginKit.framework/Info.plist differ
diff --git a/FBSDKLoginKit.framework/Modules/module.modulemap b/FBSDKLoginKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..4b1d57b
--- /dev/null
+++ b/FBSDKLoginKit.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module FBSDKLoginKit {
+ umbrella header "FBSDKLoginKit.h"
+
+ export *
+ module * { export * }
+}
diff --git a/Fabric.framework/Fabric b/Fabric.framework/Fabric
new file mode 100755
index 0000000..da5acd2
Binary files /dev/null and b/Fabric.framework/Fabric differ
diff --git a/Fabric.framework/Headers/FABAttributes.h b/Fabric.framework/Headers/FABAttributes.h
new file mode 100644
index 0000000..f4e0639
--- /dev/null
+++ b/Fabric.framework/Headers/FABAttributes.h
@@ -0,0 +1,48 @@
+//
+// FABAttributes.h
+// Fabric
+//
+// Copyright (c) 2015 Twitter. All rights reserved.
+//
+
+#pragma once
+
+#define FAB_UNAVAILABLE(x) __attribute__((unavailable(x)))
+
+#if __has_feature(nullability)
+ #define fab_nullable nullable
+ #define fab_nonnull nonnull
+ #define fab_null_unspecified null_unspecified
+ #define fab_null_resettable null_resettable
+ #define __fab_nullable __nullable
+ #define __fab_nonnull __nonnull
+ #define __fab_null_unspecified __null_unspecified
+#else
+ #define fab_nullable
+ #define fab_nonnull
+ #define fab_null_unspecified
+ #define fab_null_resettable
+ #define __fab_nullable
+ #define __fab_nonnull
+ #define __fab_null_unspecified
+#endif
+
+#ifndef NS_ASSUME_NONNULL_BEGIN
+ #define NS_ASSUME_NONNULL_BEGIN
+#endif
+
+#ifndef NS_ASSUME_NONNULL_END
+ #define NS_ASSUME_NONNULL_END
+#endif
+
+
+/**
+ * The following macros are defined here to provide
+ * backwards compatability. If you are still using
+ * them you should migrate to the new versions that
+ * are defined above.
+ */
+#define FAB_NONNULL __fab_nonnull
+#define FAB_NULLABLE __fab_nullable
+#define FAB_START_NONNULL NS_ASSUME_NONNULL_BEGIN
+#define FAB_END_NONNULL NS_ASSUME_NONNULL_END
diff --git a/Fabric.framework/Headers/Fabric.h b/Fabric.framework/Headers/Fabric.h
new file mode 100644
index 0000000..47a3d05
--- /dev/null
+++ b/Fabric.framework/Headers/Fabric.h
@@ -0,0 +1,64 @@
+//
+// Fabric.h
+//
+// Copyright (c) 2015 Twitter. All rights reserved.
+//
+
+#import
+#import "FABAttributes.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+#if TARGET_OS_IPHONE
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ #error "Fabric's minimum iOS version is 6.0"
+#endif
+#else
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+ #error "Fabric's minimum OS X version is 10.7"
+#endif
+#endif
+
+/**
+ * Fabric Base. Coordinates configuration and starts all provided kits.
+ */
+@interface Fabric : NSObject
+
+/**
+ * Initialize Fabric and all provided kits. Call this method within your App Delegate's `application:didFinishLaunchingWithOptions:` and provide the kits you wish to use.
+ *
+ * For example, in Objective-C:
+ *
+ * `[Fabric with:@[[Crashlytics class], [Twitter class], [Digits class], [MoPub class]]];`
+ *
+ * Swift:
+ *
+ * `Fabric.with([Crashlytics.self(), Twitter.self(), Digits.self(), MoPub.self()])`
+ *
+ * Only the first call to this method is honored. Subsequent calls are no-ops.
+ *
+ * @param kitClasses An array of kit Class objects
+ *
+ * @return Returns the shared Fabric instance. In most cases this can be ignored.
+ */
++ (instancetype)with:(NSArray *)kitClasses;
+
+/**
+ * Returns the Fabric singleton object.
+ */
++ (instancetype)sharedSDK;
+
+/**
+ * This BOOL enables or disables debug logging, such as kit version information. The default value is NO.
+ */
+@property (nonatomic, assign) BOOL debug;
+
+/**
+ * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
+ */
+- (id)init FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
+
+@end
+
+NS_ASSUME_NONNULL_END
+
diff --git a/Fabric.framework/Info.plist b/Fabric.framework/Info.plist
new file mode 100644
index 0000000..4b07ac2
--- /dev/null
+++ b/Fabric.framework/Info.plist
@@ -0,0 +1,55 @@
+
+
+
+
+ BuildMachineOSBuild
+ 14E46
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ Fabric
+ CFBundleIdentifier
+ io.fabric.sdk.ios
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ Fabric
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.5.5
+ CFBundleSignature
+ ????
+ CFBundleSupportedPlatforms
+
+ iPhoneOS
+
+ CFBundleVersion
+ 30
+ DTCompiler
+ com.apple.compilers.llvm.clang.1_0
+ DTPlatformBuild
+ 13A340
+ DTPlatformName
+ iphoneos
+ DTPlatformVersion
+ 9.0
+ DTSDKBuild
+ 13A340
+ DTSDKName
+ iphoneos9.0
+ DTXcode
+ 0700
+ DTXcodeBuild
+ 7A220
+ MinimumOSVersion
+ 6.0
+ NSHumanReadableCopyright
+ Copyright © 2015 Twitter. All rights reserved.
+ UIDeviceFamily
+
+ 1
+ 2
+
+
+
diff --git a/Fabric.framework/Modules/module.modulemap b/Fabric.framework/Modules/module.modulemap
new file mode 100644
index 0000000..2a31223
--- /dev/null
+++ b/Fabric.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module Fabric {
+ umbrella header "Fabric.h"
+
+ export *
+ module * { export * }
+}
\ No newline at end of file
diff --git a/Fabric.framework/run b/Fabric.framework/run
new file mode 100755
index 0000000..f4c5732
--- /dev/null
+++ b/Fabric.framework/run
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# run
+#
+# Copyright (c) 2015 Crashlytics. All rights reserved.
+
+# Figure out where we're being called from
+DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# Quote path in case of spaces or special chars
+DIR="\"${DIR}"
+
+PATH_SEP="/"
+VALIDATE_COMMAND="uploadDSYM\" $@ validate"
+UPLOAD_COMMAND="uploadDSYM\" $@"
+
+# Ensure params are as expected, run in sync mode to validate
+eval $DIR$PATH_SEP$VALIDATE_COMMAND
+return_code=$?
+
+if [[ $return_code != 0 ]]; then
+ exit $return_code
+fi
+
+# Verification passed, upload dSYM in background to prevent Xcode from waiting
+# Note: Validation is performed again before upload.
+# Output can still be found in Console.app
+eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
diff --git a/Fabric.framework/uploadDSYM b/Fabric.framework/uploadDSYM
new file mode 100755
index 0000000..55d78a1
Binary files /dev/null and b/Fabric.framework/uploadDSYM differ
diff --git a/FacebookFeedDatasource.swift b/FacebookFeedDatasource.swift
new file mode 100644
index 0000000..2bc99d1
--- /dev/null
+++ b/FacebookFeedDatasource.swift
@@ -0,0 +1,50 @@
+//
+// FacebookFeedDatasource.swift
+// comblie
+//
+// Created by Cal on 11/16/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FacebookFeedDatasource: NSObject, UITableViewDataSource {
+
+ var tableView : UITableView
+ var items : NSMutableArray
+ var isProfile : Bool
+ var parent : UITableViewController!
+
+ init(parent: UITableViewController, tableView : UITableView, isProfile: Bool) {
+ self.parent = parent
+ self.isProfile = isProfile
+ self.items = ["a","a", "a"]
+ self.tableView = tableView
+ self.tableView.registerNib(UINib(nibName: "FacebookHeaderCell", bundle: nil), forCellReuseIdentifier: "FacebookHeader")
+ self.tableView.registerNib(UINib(nibName: "FacebookStatusCell", bundle: nil), forCellReuseIdentifier: "FacebookStatus")
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.items.count
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+
+ // Configure the cell...
+ if (isProfile && indexPath.row == 0) {
+ currentCell = tableView.dequeueReusableCellWithIdentifier("FacebookHeader", forIndexPath: indexPath)
+ } else {
+ let cell = tableView.dequeueReusableCellWithIdentifier("FacebookStatus", forIndexPath: indexPath) as! FacebookStatusCellController
+ cell.parent = self.parent
+ currentCell = cell
+ }
+
+ return currentCell
+ }
+}
diff --git a/FacebookFeedTableViewController.swift b/FacebookFeedTableViewController.swift
new file mode 100644
index 0000000..ed8a460
--- /dev/null
+++ b/FacebookFeedTableViewController.swift
@@ -0,0 +1,82 @@
+//
+// FacebookFeedTableViewController.swift
+// comblie
+//
+// Created by Cal on 10/24/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FacebookFeedTableViewController: UITableViewController {
+
+ var dataSource : FacebookFeedDatasource!
+ var isProfile : Bool!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ if (self.restorationIdentifier?.rangeOfString("Feed") != nil) {
+ self.isProfile = false
+ } else {
+ self.isProfile = true
+ }
+
+ self.dataSource = FacebookFeedDatasource(parent: self, tableView: self.tableView, isProfile: self.isProfile)
+ self.tableView.dataSource = dataSource
+
+ self.edgesForExtendedLayout = UIRectEdge.None
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
+ self.tableView.rowHeight = UITableViewAutomaticDimension;
+ self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average"
+ self.tableView.allowsSelection = false;
+
+ }
+
+
+ /*
+ // Override to support conditional editing of the table view.
+ override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the specified item to be editable.
+ return true
+ }
+ */
+
+ /*
+ // Override to support editing the table view.
+ override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
+ if editingStyle == .Delete {
+ // Delete the row from the data source
+ tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
+ } else if editingStyle == .Insert {
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
+ }
+ }
+ */
+
+ /*
+ // Override to support rearranging the table view.
+ override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
+
+ }
+ */
+
+ /*
+ // Override to support conditional rearranging of the table view.
+ override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the item to be re-orderable.
+ return true
+ }
+ */
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/FacebookHeaderCell.xib b/FacebookHeaderCell.xib
new file mode 100644
index 0000000..90d53f7
--- /dev/null
+++ b/FacebookHeaderCell.xib
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FacebookHeaderTableViewCell.swift b/FacebookHeaderTableViewCell.swift
new file mode 100644
index 0000000..d30ad53
--- /dev/null
+++ b/FacebookHeaderTableViewCell.swift
@@ -0,0 +1,27 @@
+//
+// FacebookHeaderTableViewCell.swift
+// comblie
+//
+// Created by Cal on 10/22/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FacebookHeaderTableViewCell: UITableViewCell {
+
+ @IBOutlet weak var profileImageBackground: UIView!
+ @IBOutlet weak var profileImage: UIImageView!
+
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+
+ self.profileImageBackground.layer.cornerRadius = CGFloat(self.profileImageBackground.frame.height/2)
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage.frame.height/2)
+
+ }
+
+
+}
diff --git a/FacebookProfileTableViewController.swift b/FacebookProfileTableViewController.swift
new file mode 100644
index 0000000..dcba4f1
--- /dev/null
+++ b/FacebookProfileTableViewController.swift
@@ -0,0 +1,109 @@
+//
+// FacebookProfileTableViewController.swift
+// comblie
+//
+// Created by Cal on 10/22/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FacebookProfileTableViewController: UITableViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ self.edgesForExtendedLayout = UIRectEdge.None
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
+ self.tableView.rowHeight = UITableViewAutomaticDimension;
+ self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average"
+ // Uncomment the following line to preserve selection between presentations
+ // self.clearsSelectionOnViewWillAppear = false
+
+ // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+ // self.navigationItem.rightBarButtonItem = self.editButtonItem()
+ }
+
+ override func didReceiveMemoryWarning() {
+ super.didReceiveMemoryWarning()
+ // Dispose of any resources that can be recreated.
+ }
+
+ // MARK: - Table view data source
+
+ override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ // #warning Incomplete implementation, return the number of rows
+ return 2
+ }
+
+
+ override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+ if (indexPath.row == 0) {
+ let cell = tableView.dequeueReusableCellWithIdentifier("FacebookHeader", forIndexPath: indexPath)
+ currentCell = cell
+ } else {
+ let cell = tableView.dequeueReusableCellWithIdentifier("FacebookBasicPost", forIndexPath: indexPath)
+ currentCell = cell
+ }
+
+ // Configure the cell...
+
+ return currentCell
+ }
+
+ override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
+ return 44
+ }
+
+ /*
+ // Override to support conditional editing of the table view.
+ override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the specified item to be editable.
+ return true
+ }
+ */
+
+ /*
+ // Override to support editing the table view.
+ override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
+ if editingStyle == .Delete {
+ // Delete the row from the data source
+ tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
+ } else if editingStyle == .Insert {
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
+ }
+ }
+ */
+
+ /*
+ // Override to support rearranging the table view.
+ override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
+
+ }
+ */
+
+ /*
+ // Override to support conditional rearranging of the table view.
+ override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the item to be re-orderable.
+ return true
+ }
+ */
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/FacebookStatusCell.xib b/FacebookStatusCell.xib
new file mode 100644
index 0000000..26b3bff
--- /dev/null
+++ b/FacebookStatusCell.xib
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+ HelveticaNeue-Roman
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FacebookStatusCellController.swift b/FacebookStatusCellController.swift
new file mode 100644
index 0000000..fc8c8ec
--- /dev/null
+++ b/FacebookStatusCellController.swift
@@ -0,0 +1,56 @@
+//
+// FacebookStatusCellController.swift
+// comblie
+//
+// Created by Cal on 10/30/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FacebookStatusCellController: UITableViewCell {
+
+ @IBOutlet weak var postAuthor: UILabel!
+ @IBOutlet weak var profileImage: UIView!
+ @IBOutlet weak var lineSeparator: UIView!
+ @IBOutlet weak var lineHeight: NSLayoutConstraint!
+
+ var parent : UITableViewController!
+ var VC : CommentsController!
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage
+ .frame.height/2)
+ self.lineHeight.constant = CGFloat(0.5)
+ }
+
+ override func setSelected(selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+
+ // Configure the view for the selected state
+ self.lineSeparator.backgroundColor = UIColor(red: 236/255, green: 236/255, blue: 236/255, alpha: 1)
+ }
+
+ override func setHighlighted(highlighted: Bool, animated: Bool) {
+ self.lineSeparator.backgroundColor = UIColor(red: 236/255, green: 236/255, blue: 236/255, alpha: 1)
+
+ self.postAuthor.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "openProfile"))
+ }
+
+ // MARK: Actions
+
+ func openProfile() {
+ let profileView = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("PublicProfile")
+ self.parent.parentViewController!.navigationController?.pushViewController(profileView!, animated: true)
+ }
+
+ @IBAction func enlarge(sender: UIButton) {
+ VC = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("Comments") as! CommentsController
+ VC.postHeight = self.contentView.frame.height
+ self.window?.rootViewController?.presentViewController(VC, animated: true, completion: nil)
+ UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
+
+ }
+}
diff --git a/FeedHeader.xib b/FeedHeader.xib
new file mode 100644
index 0000000..3656a3f
--- /dev/null
+++ b/FeedHeader.xib
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FeedPageController.swift b/FeedPageController.swift
new file mode 100644
index 0000000..2318ae7
--- /dev/null
+++ b/FeedPageController.swift
@@ -0,0 +1,216 @@
+//
+// SocialFeedsViewController.swift
+// comblie
+//
+// Created by Cal on 10/13/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FeedPageController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
+
+ //MARK: Properties
+
+
+ @IBOutlet weak var feedViewContainer: UIView!
+ @IBOutlet weak var networkName: UILabel!
+ @IBOutlet weak var customPageControls: UIStackView!
+ @IBOutlet weak var headerBackground: UIView!
+ @IBOutlet weak var grayBarHeight: NSLayoutConstraint!
+ @IBOutlet weak var navBarContent: UIView!
+
+ var pageViewController : UIPageViewController!
+ var pages : NSArray!
+ var pageQuery : String!
+ var viewControllers : NSArray!
+ var dotCollection : [UIView]!
+ var headerColor : UIColor!
+ var clickedColor : UIColor!
+ var notClickedColor : UIColor!
+ var navBar : UINavigationBar!
+
+ // Set up for parameters that can be passed in
+ init(page : String)
+ {
+ self.pageQuery = page
+
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ self.pageQuery = ""
+ super.init(coder: aDecoder)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.navBar = self.navigationController?.navigationBar
+ self.navBar.frame.origin.y = -50
+ // Do any additional setup after loading the view, typically from a nib.
+
+ // Instantiate the view page controller and add it to the Main View as a child view
+ // Prepares the login-type views
+ //self.navigationController?.navigationBarHidden = false
+
+ self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("SocialPageViewController") as! UIPageViewController
+ self.pageViewController.delegate = self
+ self.pageViewController.dataSource = self
+ let newsfeedVC = createViewController("AllNewsfeed")
+ let facebookVC = createViewController("FacebookFeed")
+ let twitterVC = createViewController("TwitterFeed")
+ let instagramVC = createViewController("InstagramFeed")
+ let tumblrVC = createViewController("TumblrFeed")
+ let vineVC = createViewController("VineFeed")
+ pages = NSArray(objects: newsfeedVC, facebookVC, twitterVC, instagramVC, tumblrVC, vineVC)
+ viewControllers = NSArray(object: newsfeedVC)
+ self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
+ self.addChildViewController(self.pageViewController)
+ self.pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.feedViewContainer.frame.width, height: self.feedViewContainer.frame.height)
+ self.feedViewContainer.addSubview(self.pageViewController.view)
+ //self.view.addSubview(self.pageViewController.view)
+ self.pageViewController.didMoveToParentViewController(self)
+ dotCollection = customPageControls.subviews
+
+ // Position Page Control
+ initializeConstraints()
+ stylePageControls()
+ changeHeaderColors("Newsfeed", networkIndex: 0)
+ }
+
+ //MARK: Actions
+
+ @IBAction func compose(sender: UIBarButtonItem) {
+ let composeVC = self.storyboard?.instantiateViewControllerWithIdentifier("ComposePage")
+ self.navigationController?.presentViewController(composeVC!, animated: true, completion: nil)
+ }
+
+ // Creates and returns view controllers by storyboard ID
+
+ func createViewController(identifierID : String) -> UIViewController {
+ let vc = self.storyboard!.instantiateViewControllerWithIdentifier(identifierID) as UIViewController
+ return vc
+ }
+
+ // MARK: Page View Controller Data Source
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == 0 || index == NSNotFound) {
+ return nil
+ }
+ index--
+ return pages[index] as! UIViewController
+ }
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == pages.count-1 || index == NSNotFound) {
+ return nil
+ }
+ index++
+ return pages[index] as! UIViewController
+ }
+
+ // Triggers after it has landed on a new page after swipe
+
+ func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
+
+ // Set the current page
+ let fullIdentifier = pageViewController.viewControllers?.last?.restorationIdentifier
+ let cleanIdentifier = fullIdentifier?.stringByReplacingOccurrencesOfString("Feed", withString: "")
+ networkName.text = cleanIdentifier
+ let currentPage = pageViewController.viewControllers?.last
+ let currentIndex = pages.indexOfObject(currentPage!)
+ changeHeaderColors((currentPage?.restorationIdentifier)!, networkIndex: currentIndex)
+
+ }
+
+ // MARK : Other
+
+ func initializeConstraints() {
+ let screenHeight = UIScreen.mainScreen().bounds.height
+ if (screenHeight <= 480) {
+ print("iPhone4")
+
+ } else if screenHeight == 568 {
+ print("iPhone5")
+
+ } else {
+ print("iPhone6")
+
+ }
+ }
+
+ func changeHeaderColors(networkID: String, networkIndex: Int) {
+
+ switch networkID {
+ case "FacebookFeed":
+ self.navBar.barTintColor = UIColor(red: 63/255, green: 88/255, blue: 151/255, alpha: 1)
+ clickedColor = UIColor(red: 99/255, green: 122/255, blue: 181/255, alpha: 1)
+ notClickedColor = UIColor(red: 218/255, green: 239/255, blue: 250/255, alpha: 1)
+ break
+ case "TwitterFeed":
+ self.navBar.barTintColor = UIColor(red: 82/255, green: 176/255, blue: 236/255, alpha: 1)
+ clickedColor = UIColor(red: 118/255, green: 195/255, blue: 247/255, alpha: 1)
+ notClickedColor = UIColor(red: 238/255, green: 243/255, blue: 249/255, alpha: 1)
+ break
+ case "InstagramFeed":
+ self.navBar.barTintColor = UIColor(red: 49/255, green: 96/255, blue: 132/255, alpha: 1)
+ clickedColor = UIColor(red: 88/255, green: 129/255, blue: 165/255, alpha: 1)
+ notClickedColor = UIColor(red: 155/255, green: 179/255, blue: 201/255, alpha: 1)
+ break
+ case "TumblrFeed":
+ self.navBar.barTintColor = UIColor(red: 54/255, green: 70/255, blue: 93/255, alpha: 1)
+ clickedColor = UIColor(red: 94/255, green: 106/255, blue: 125/255, alpha: 1)
+ notClickedColor = UIColor(red: 140/255, green: 149/255, blue: 161/255, alpha: 1)
+ break
+ case "VineFeed":
+ self.navBar.barTintColor = UIColor(red: 105/255, green: 214/255, blue: 187/255, alpha: 1)
+ clickedColor = UIColor(red: 150/255, green: 238/255, blue: 217/255, alpha: 1)
+ notClickedColor = UIColor(red: 193/255, green: 245/255, blue: 233/255, alpha: 1)
+ break
+ default:
+ self.navBar.barTintColor = UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1.0)
+ clickedColor = UIColor(red: 49/255, green: 49/255, blue: 49/255, alpha: 1.0)
+ notClickedColor = UIColor(red: 196/255, green: 196/255, blue: 196/255, alpha: 1.0)
+ break
+ }
+ if (networkID == "Newsfeed") {
+ self.navigationItem.rightBarButtonItem?.tintColor = UIColor(red: 132/255, green: 45/255, blue: 114/255, alpha: 1)
+ networkName.textColor = UIColor.blackColor()
+ UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
+ } else {
+ self.navigationItem.rightBarButtonItem?.tintColor = UIColor.whiteColor()
+ networkName.textColor = UIColor.whiteColor()
+ UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
+ }
+
+ // Change the colors
+
+ self.headerBackground.backgroundColor = headerColor
+
+ for (index, element) in dotCollection.enumerate() {
+ if index == networkIndex {
+ element.backgroundColor = clickedColor
+ } else {
+ element.backgroundColor = notClickedColor
+ }
+ }
+
+ }
+
+
+ func stylePageControls() {
+ //Sets the height of the gray line below the header
+ self.grayBarHeight.constant = CGFloat(0.5)
+
+ for dots in dotCollection {
+ dots.layer.cornerRadius = dots.frame.height/2
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/FeedbackController.swift b/FeedbackController.swift
new file mode 100644
index 0000000..c8fb186
--- /dev/null
+++ b/FeedbackController.swift
@@ -0,0 +1,70 @@
+//
+// FeedbackController.swift
+// comblie
+//
+// Created by Cal on 11/4/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class FeedbackController: UIViewController,UITextViewDelegate {
+
+ @IBOutlet weak var reportText: UITextView!
+ @IBOutlet weak var grayBarHeight: NSLayoutConstraint!
+ @IBOutlet weak var bottomBarHeight: NSLayoutConstraint!
+ var placeholderColor : UIColor!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ let me = NSUserDefaults.standardUserDefaults()
+ print(me.boolForKey("facebook"))
+ // Do any additional setup after loading the view.
+ self.grayBarHeight.constant = CGFloat(0.5)
+ self.bottomBarHeight.constant = CGFloat(0.5)
+ self.placeholderColor = UIColor(red: 187/255, green: 187/255, blue: 190/255, alpha: 1)
+ self.reportText.textColor = placeholderColor
+ self.reportText.delegate = self
+ }
+
+
+ //MARK: Action
+
+ @IBAction func cancel(sender: UIButton) {
+ self.dismissViewControllerAnimated(true, completion: nil)
+ }
+
+ func textViewDidBeginEditing(textView: UITextView) {
+ if textView.textColor == self.placeholderColor {
+ textView.text = ""
+ textView.textColor = UIColor.blackColor()
+ }
+ }
+
+ func textViewDidEndEditing(textView: UITextView) {
+ if textView.text == "" {
+ textView.text = "What would you like for us to improve?"
+ textView.textColor = self.placeholderColor
+ }
+ }
+
+ func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
+ if(text == "\n") {
+ textView.resignFirstResponder()
+ return false
+ }
+ return true
+ }
+
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/IncomingMessageCell.xib b/IncomingMessageCell.xib
new file mode 100644
index 0000000..8c49619
--- /dev/null
+++ b/IncomingMessageCell.xib
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/IncomingMessageCellController.swift b/IncomingMessageCellController.swift
new file mode 100644
index 0000000..6486260
--- /dev/null
+++ b/IncomingMessageCellController.swift
@@ -0,0 +1,30 @@
+//
+// IncomingMessageCellController.swift
+// comblie
+//
+// Created by Cal on 10/25/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class IncomingMessageCellController: UITableViewCell {
+
+ @IBOutlet weak var profileImage: UIImageView!
+ @IBOutlet weak var messageBackground: UIView!
+ @IBOutlet weak var message: UILabel!
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage.frame.height/2)
+ self.messageBackground.layer.cornerRadius = CGFloat(13)
+ }
+
+ override func setSelected(selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+
+ // Configure the view for the selected state
+ }
+
+}
diff --git a/IncomingMessageTwoCell.xib b/IncomingMessageTwoCell.xib
new file mode 100644
index 0000000..8f15b46
--- /dev/null
+++ b/IncomingMessageTwoCell.xib
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/InstagramFeedCell.xib b/InstagramFeedCell.xib
new file mode 100644
index 0000000..7545ebb
--- /dev/null
+++ b/InstagramFeedCell.xib
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/InstagramFeedCellController.swift b/InstagramFeedCellController.swift
new file mode 100644
index 0000000..ac05c34
--- /dev/null
+++ b/InstagramFeedCellController.swift
@@ -0,0 +1,110 @@
+//
+// InstagramFeedCellController.swift
+// comblie
+//
+// Created by Cal on 10/24/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class InstagramFeedCellController: UITableViewCell {
+
+ @IBOutlet weak var postBackgroundImage: UIImageView!
+ @IBOutlet weak var profileImage: UIImageView!
+ @IBOutlet weak var postText: UILabel!
+ @IBOutlet weak var statusText: UILabel!
+ @IBOutlet weak var lineSeparator: UIView!
+ @IBOutlet weak var lineHeight: NSLayoutConstraint!
+ @IBOutlet weak var playButton: UIButton!
+ @IBOutlet weak var likeCommentBox: UIStackView!
+ @IBOutlet weak var postTime: UILabel!
+
+ var VC : InstagramModalController!
+
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ self.postBackgroundImage.image = UIImage(named: "sunset")
+
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage.frame.height/2)
+ configureText()
+ lineHeight.constant = CGFloat(0.5)
+ self.selectionStyle = UITableViewCellSelectionStyle.None
+ }
+
+ override func setSelected(selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+ lineSeparator.backgroundColor = UIColor.whiteColor()
+ // Configure the view for the selected state
+ }
+
+ override func setHighlighted(highlighted: Bool, animated: Bool) {
+ lineSeparator.backgroundColor = UIColor.whiteColor()
+ }
+
+ // MARK: Action
+
+ @IBAction func enlarge(sender: UIButton) {
+ VC = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("InstagramModal") as! InstagramModalController
+ //For keeping the opacity
+ VC.providesPresentationContextTransitionStyle = true
+ VC.definesPresentationContext = true
+ VC.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
+ self.window?.rootViewController?.presentViewController(VC, animated: true, completion: setModal)
+ }
+
+ @IBAction func playVideo(sender: UIButton) {
+ print("Playing Video")
+ }
+
+ func setModal() {
+ VC.thumbnailImage.image = self.postBackgroundImage.image
+ VC.profileImage.image = self.profileImage.image
+ VC.postText.text = self.postText.text
+ VC.statusText.attributedText = self.statusText.attributedText
+ VC.postHeight = self.contentView.frame.height
+ //VC.playButton.setBackgroundImage(UIImage(named: "playArrow"), forState: .Normal)
+ }
+
+ func configureText() {
+ var user = "@davidbeckham "
+ var userMutableString = NSMutableAttributedString()
+ userMutableString = NSMutableAttributedString(string: user, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeueLTStd-Roman",
+ size: 10.0)!])
+
+ var sectionOne = "posted a photo on "
+ var sectionOneMutableString = NSMutableAttributedString()
+ sectionOneMutableString = NSMutableAttributedString(string: sectionOne, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeueLTStd-Lt",
+ size: 10.0)!])
+
+ var author = "David"
+ var authorMutableString = NSMutableAttributedString()
+ authorMutableString = NSMutableAttributedString(string: author, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeueLTStd-Roman",
+ size: 10.0)!])
+
+ var sectionTwo = "'s post on "
+ var sectionTwoMutableString = NSMutableAttributedString()
+ sectionTwoMutableString = NSMutableAttributedString(string: sectionTwo, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeueLTStd-Lt",
+ size: 10.0)!])
+
+ var network = "Instagram"
+ var networkMutableString = NSMutableAttributedString()
+ networkMutableString = NSMutableAttributedString(string: network, attributes: [NSFontAttributeName:UIFont(
+ name: "HelveticaNeueLTStd-Roman",
+ size: 10.0)!])
+
+
+ userMutableString.appendAttributedString(sectionOneMutableString)
+ //userMutableString.appendAttributedString(authorMutableString)
+ //userMutableString.appendAttributedString(sectionTwoMutableString)
+ userMutableString.appendAttributedString(networkMutableString)
+ statusText.attributedText = userMutableString
+ }
+
+}
diff --git a/InstagramFeedDatasource.swift b/InstagramFeedDatasource.swift
new file mode 100644
index 0000000..f62ad93
--- /dev/null
+++ b/InstagramFeedDatasource.swift
@@ -0,0 +1,45 @@
+//
+// InstagramFeedDatasource.swift
+// comblie
+//
+// Created by Cal on 11/16/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class InstagramFeedDatasource: NSObject, UITableViewDataSource {
+
+ var tableView : UITableView
+ var items : NSMutableArray
+
+ init(tableView : UITableView) {
+ self.items = ["a"]
+ self.tableView = tableView
+ self.tableView.registerNib(UINib(nibName: "InstagramFeedCell", bundle: nil), forCellReuseIdentifier: "InstagramFeed")
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.items.count
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+ if (indexPath.row == 1) {
+ let cell = tableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath) as! InstagramFeedCellController
+ cell.playButton.alpha = CGFloat(0)
+ currentCell = cell
+ } else {
+ let cell = tableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath) as! InstagramFeedCellController
+ currentCell = cell
+ }
+ // Configure the cell...
+
+ return currentCell
+ }
+}
diff --git a/InstagramFeedTableViewController.swift b/InstagramFeedTableViewController.swift
new file mode 100644
index 0000000..a4932ac
--- /dev/null
+++ b/InstagramFeedTableViewController.swift
@@ -0,0 +1,107 @@
+//
+// InstagramFeedTableViewController.swift
+// comblie
+//
+// Created by Cal on 10/24/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class InstagramFeedTableViewController: UITableViewController {
+
+ var dataSource : InstagramFeedDatasource!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // READS DATASOURCE HERE
+ dataSource = InstagramFeedDatasource(tableView: self.tableView)
+ self.tableView.dataSource = dataSource
+
+
+ print(self.tableView.dataSource)
+ self.edgesForExtendedLayout = UIRectEdge.None
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
+ self.tableView.rowHeight = UITableViewAutomaticDimension;
+ self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average"
+ self.tableView.registerNib(UINib(nibName: "InstagramFeedCell", bundle: nil), forCellReuseIdentifier: "InstagramFeed")
+
+ }
+
+ // MARK: - Table view data source
+
+ /*override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ // #warning Incomplete implementation, return the number of rows
+ return 2
+ }*/
+
+
+
+ /*override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+ if (indexPath.row == 1) {
+ let cell = tableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath) as! InstagramFeedCellController
+ cell.playButton.alpha = CGFloat(0)
+ currentCell = cell
+ } else {
+ let cell = tableView.dequeueReusableCellWithIdentifier("InstagramFeed", forIndexPath: indexPath) as! InstagramFeedCellController
+ currentCell = cell
+ }
+ // Configure the cell...
+
+ return currentCell
+ }*/
+
+
+ /*
+ // Override to support conditional editing of the table view.
+ override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the specified item to be editable.
+ return true
+ }
+ */
+
+ /*
+ // Override to support editing the table view.
+ override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
+ if editingStyle == .Delete {
+ // Delete the row from the data source
+ tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
+ } else if editingStyle == .Insert {
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
+ }
+ }
+ */
+
+ /*
+ // Override to support rearranging the table view.
+ override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
+
+ }
+ */
+
+ /*
+ // Override to support conditional rearranging of the table view.
+ override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
+ // Return false if you do not want the item to be re-orderable.
+ return true
+ }
+ */
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/InstagramModalController.swift b/InstagramModalController.swift
new file mode 100644
index 0000000..936df67
--- /dev/null
+++ b/InstagramModalController.swift
@@ -0,0 +1,55 @@
+//
+// InstagramModalController.swift
+// comblie
+//
+// Created by Cal on 11/5/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class InstagramModalController: UIViewController {
+
+ //MARK: Properties
+ @IBOutlet weak var thumbnailImage: UIImageView!
+ @IBOutlet weak var profileImage: UIImageView!
+ @IBOutlet weak var postText: UILabel!
+ @IBOutlet weak var statusText: UILabel!
+ @IBOutlet weak var playButton: UIButton!
+ @IBOutlet weak var lineHeight: NSLayoutConstraint!
+
+ var postHeight : CGFloat!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view.
+ self.profileImage.layer.cornerRadius = CGFloat(self.profileImage.frame.height/2)
+ self.lineHeight.constant = CGFloat(0.5)
+ }
+
+ //MARK: Actions
+
+ @IBAction func cancel(sender: UIButton) {
+ self.dismissViewControllerAnimated(true, completion: nil)
+ }
+
+ @IBAction func openComments(sender: UIButton) {
+ let VC = self.storyboard?.instantiateViewControllerWithIdentifier("Comments") as! CommentsController
+ //This gives it an error of presenting an active controller
+ //self.addChildViewController(VC)
+ VC.postHeight = self.postHeight
+ self.presentViewController(VC, animated: true, completion: nil)
+ UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
+ }
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/InstagramPhotoCell.swift b/InstagramPhotoCell.swift
new file mode 100644
index 0000000..147ba41
--- /dev/null
+++ b/InstagramPhotoCell.swift
@@ -0,0 +1,16 @@
+//
+// InstagramPhotoCell.swift
+// comblie
+//
+// Created by Cal on 10/27/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class InstagramPhotoCell: UICollectionViewCell {
+
+ @IBOutlet weak var photoImage: UIImageView!
+
+
+}
diff --git a/MessagePageController.swift b/MessagePageController.swift
new file mode 100644
index 0000000..37b7df2
--- /dev/null
+++ b/MessagePageController.swift
@@ -0,0 +1,147 @@
+//
+// SocialFeedsViewController.swift
+// comblie
+//
+// Created by Cal on 10/13/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class MessagePageController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
+
+ //MARK: Properties
+
+
+ @IBOutlet weak var feedViewContainer: UIView!
+
+ @IBOutlet weak var customPageControls: UIStackView!
+ @IBOutlet weak var networkName: UILabel!
+
+ var pageViewController : UIPageViewController!
+ var pages : NSArray!
+ var pageQuery : String!
+ var viewControllers : NSArray!
+ var dotCollection : [UIView]!
+
+ // Set up for parameters that can be passed in
+ init(page : String)
+ {
+ self.pageQuery = page
+
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ self.pageQuery = ""
+ super.init(coder: aDecoder)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view, typically from a nib.
+
+ // Instantiate the view page controller and add it to the Main View as a child view
+ // Prepares the login-type views
+ self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MessagePageViewController") as! UIPageViewController
+ self.pageViewController.delegate = self
+ self.pageViewController.dataSource = self
+ let allVC = createViewController("ConversationTableView")
+ let facebookVC = createViewController("ConversationTableView")
+ let twitterVC = createViewController("ConversationTableView")
+ let instagramVC = createViewController("ConversationTableView")
+ let tumblrVC = createViewController("ConversationTableView")
+ let vineVC = createViewController("ConversationTableView")
+ pages = NSArray(objects: allVC, facebookVC, twitterVC, instagramVC, tumblrVC, vineVC)
+ viewControllers = NSArray(object: allVC)
+ self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
+ self.addChildViewController(self.pageViewController)
+ self.pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.feedViewContainer.frame.width, height: self.feedViewContainer.frame.height)
+ self.feedViewContainer.addSubview(self.pageViewController.view)
+ //self.view.addSubview(self.pageViewController.view)
+ self.pageViewController.didMoveToParentViewController(self)
+ dotCollection = customPageControls.subviews
+ // Position Page Control
+ initializeConstraints()
+ stylePageControls()
+ }
+
+ //MARK: Actions
+
+
+ // Creates and returns view controllers by storyboard ID
+
+ func createViewController(identifierID : String) -> UIViewController {
+ let vc = self.storyboard!.instantiateViewControllerWithIdentifier(identifierID) as UIViewController
+ return vc
+ }
+
+ // MARK: Page View Controller Data Source
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == 0 || index == NSNotFound) {
+ return nil
+ }
+ index--
+ return pages[index] as! UIViewController
+ }
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == pages.count-1 || index == NSNotFound) {
+ return nil
+ }
+ index++
+ return pages[index] as! UIViewController
+
+ }
+
+ // Triggers after it has landed on a new page after swipe
+
+ func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
+
+ // Set the current page
+ networkName.text = pageViewController.viewControllers?.last?.restorationIdentifier
+
+ let currentIndex = pages.indexOfObject((pageViewController.viewControllers?.last)!)
+ for (index, element) in dotCollection.enumerate() {
+ if index == currentIndex {
+ element.alpha = CGFloat(1.0)
+ } else {
+ element.alpha = CGFloat(0.25)
+ }
+ }
+
+ }
+
+ // MARK : Other
+
+ func initializeConstraints() {
+ let screenHeight = UIScreen.mainScreen().bounds.height
+ if (screenHeight <= 480) {
+ print("iPhone4")
+
+ } else if screenHeight == 568 {
+ print("iPhone5")
+
+ } else {
+ print("iPhone6")
+
+ }
+ }
+
+ func stylePageControls() {
+ for dots in dotCollection {
+ dots.layer.cornerRadius = dots.frame.height/2
+ dots.alpha = CGFloat(0.25)
+ }
+
+ var currentIndex = pages.indexOfObject(viewControllers[0])
+ dotCollection[currentIndex].alpha = CGFloat(1.0)
+ }
+
+}
\ No newline at end of file
diff --git a/MessageRoomDatasource.swift b/MessageRoomDatasource.swift
new file mode 100644
index 0000000..915e8a5
--- /dev/null
+++ b/MessageRoomDatasource.swift
@@ -0,0 +1,72 @@
+//
+// MessageRoomDatasource.swift
+// comblie
+//
+// Created by Cal on 11/16/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class MessageRoomDatasource: NSObject, UITableViewDataSource {
+
+ var tableView : UITableView
+ var items : NSMutableArray
+
+ init(tableView : UITableView) {
+ self.items = ["a","a","a","a","a","a","a","a"]
+ self.tableView = tableView
+ self.tableView.registerNib(UINib(nibName: "IncomingMessageCell", bundle: nil), forCellReuseIdentifier: "IncomingMessage")
+ self.tableView.registerNib(UINib(nibName: "IncomingMessageTwoCell", bundle: nil), forCellReuseIdentifier: "IncomingMessageTwo")
+ self.tableView.registerNib(UINib(nibName: "OutgoingMessageCell", bundle: nil), forCellReuseIdentifier: "OutgoingMessage")
+ self.tableView.registerNib(UINib(nibName: "TimeMessageCell", bundle: nil), forCellReuseIdentifier: "TimeMessage")
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.items.count
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ // #warning Incomplete implementation, return the number of sections
+ return 1
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ var currentCell : UITableViewCell!
+ // Configure the cell...
+ if(indexPath.row==0){
+ // Create first cell
+ let cell = tableView.dequeueReusableCellWithIdentifier("TimeMessage", forIndexPath: indexPath) as! TimeMessageCellController
+ cell.timeLabel.text = "YESTERDAY 5:02 PM"
+ currentCell = cell
+ } else if(indexPath.row==1){
+ // Create second cell
+ let cell = tableView.dequeueReusableCellWithIdentifier("IncomingMessage", forIndexPath: indexPath) as! IncomingMessageCellController
+ cell.message.text = "Hey, how's it going?"
+ currentCell = cell
+
+ } else if(indexPath.row==2){
+ // Create second cell
+ let cell = tableView.dequeueReusableCellWithIdentifier("TimeMessage", forIndexPath: indexPath) as! TimeMessageCellController
+ cell.timeLabel.text = "TODAY 12:38 PM"
+ currentCell = cell
+ }else if(indexPath.row==6){
+ // Create second cell
+ let cell = tableView.dequeueReusableCellWithIdentifier("TimeMessage", forIndexPath: indexPath) as! TimeMessageCellController
+ cell.timeLabel.text = "3:30 PM"
+ currentCell = cell
+ }else if(indexPath.row==7){
+ // Create second cell
+ let cell = tableView.dequeueReusableCellWithIdentifier("IncomingMessage", forIndexPath: indexPath) as! IncomingMessageCellController
+ cell.message.text = "Sounds good, I'll see you later then."
+ currentCell = cell
+ } else{
+ // Create all others
+ let cell = tableView.dequeueReusableCellWithIdentifier("OutgoingMessage", forIndexPath: indexPath) as! OutgoingMessageCellController
+ cell.message.text = "This is just sample text used as a filler to show what the message box looks like."
+ currentCell = cell
+ }
+ // Configure the cell...
+ return currentCell
+ }
+}
diff --git a/NetworkSettingsController.swift b/NetworkSettingsController.swift
new file mode 100644
index 0000000..3e7cbf1
--- /dev/null
+++ b/NetworkSettingsController.swift
@@ -0,0 +1,152 @@
+//
+// NetworkSettingsController.swift
+// comblie
+//
+// Created by Cal on 11/10/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class NetworkSettingsController: UIViewController {
+
+ @IBOutlet weak var stackView: UIStackView!
+ @IBOutlet weak var grayBarHeight: NSLayoutConstraint!
+
+ var facebook : Bool!
+ var twitter : Bool!
+ var instagram : Bool!
+ var tumblr : Bool!
+ var vine : Bool!
+
+ var userPrefs : NSUserDefaults!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view.
+ self.facebook = true
+ self.twitter = false
+ self.instagram = false
+ self.tumblr = true
+ self.vine = true
+
+ self.userPrefs = NSUserDefaults.standardUserDefaults()
+
+ self.grayBarHeight.constant = CGFloat(0.5)
+
+ checkAuthentication()
+ initializeSwitches()
+ }
+
+ //MARK: Actions
+
+ @IBAction func cancel(sender: UIButton) {
+ self.dismissViewControllerAnimated(true, completion: nil)
+ }
+
+ //MARK: Other
+
+ func checkAuthentication() {
+ for item in self.stackView.subviews {
+ var connectButton : UIButton!
+ var connectionLabel : UILabel!
+ var connectSwitch : UISwitch!
+
+ if item.tag != 1 {
+ let networkName = item.restorationIdentifier
+ //Network names : facebook, twitter, etc...
+ print(networkName)
+ for innerItem in item.subviews {
+ if innerItem.tag == 5 {
+ connectionLabel = innerItem as! UILabel
+
+ if networkName == nil {
+ connectionLabel.alpha = CGFloat(0)
+ } else {
+ connectionLabel.alpha = CGFloat(1)
+ }
+ } else if innerItem.tag == 3 {
+ connectButton = innerItem as! UIButton
+
+ if networkName == nil {
+ connectButton.alpha = CGFloat(1)
+ } else {
+ connectButton.alpha = CGFloat(0)
+ }
+ } else if innerItem.tag == 0 {
+ connectSwitch = innerItem as! UISwitch
+ connectSwitch.addTarget(self, action: "TriggerNetworks:", forControlEvents: .ValueChanged)
+ // Sets the UserPrefs on UISwitch
+ connectSwitch.on = userPrefs.boolForKey(connectSwitch.restorationIdentifier!)
+
+ if networkName == nil {
+ connectSwitch.alpha = CGFloat(0)
+ } else {
+ connectSwitch.alpha = CGFloat(1)
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ func initializeSwitches() {
+ //Sets separator thickness and scales switches
+ for item in self.stackView.subviews {
+ if item.tag == 1 {
+ item.constraints.first?.constant = CGFloat(0.5)
+ } else {
+ for innerItem in item.subviews {
+ var switchButton : UISwitch!
+
+ //Iterates through the elements
+ if innerItem.isKindOfClass(UISwitch) {
+ switchButton = innerItem as! UISwitch
+ switchButton.transform = CGAffineTransformMakeScale(0.75, 0.75)
+ switchButton.addTarget(self, action: "stateChanged:", forControlEvents: UIControlEvents.ValueChanged)
+ stateChanged(switchButton)
+ }
+
+ }
+ }
+ }
+ }
+
+ func stateChanged(switchButton : UISwitch) {
+ var connectionLabel : UILabel!
+ var connectionNetwork : UILabel!
+
+ for item in (switchButton.superview?.subviews)! {
+ if item.tag == 5 {
+ connectionLabel = item as! UILabel
+ } else if item.tag == 2 {
+ connectionNetwork = item as! UILabel
+ }
+ }
+
+ if switchButton.on {
+ connectionLabel.text = "Connected"
+ connectionNetwork.textColor = UIColor.blackColor()
+ } else {
+ connectionLabel.text = "Disconnected"
+ connectionNetwork.textColor = UIColor.lightGrayColor()
+ }
+ }
+
+ func TriggerNetworks(switchButton : UISwitch) {
+ userPrefs.setBool(switchButton.on, forKey: switchButton.restorationIdentifier!)
+ }
+
+ /*
+ // MARK: - Navigation
+
+ // In a storyboard-based application, you will often want to do a little preparation before navigation
+ override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+ // Get the new view controller using segue.destinationViewController.
+ // Pass the selected object to the new view controller.
+ }
+ */
+
+}
diff --git a/NotificationPageController.swift b/NotificationPageController.swift
new file mode 100644
index 0000000..78e94b4
--- /dev/null
+++ b/NotificationPageController.swift
@@ -0,0 +1,146 @@
+//
+// SocialFeedsViewController.swift
+// comblie
+//
+// Created by Cal on 10/13/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class NotificationPageController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
+
+ //MARK: Properties
+
+ @IBOutlet weak var feedViewContainer: UIView!
+ @IBOutlet weak var networkName: UILabel!
+ @IBOutlet weak var customPageControls: UIStackView!
+
+
+ var pageViewController : UIPageViewController!
+ var pages : NSArray!
+ var pageQuery : String!
+ var viewControllers : NSArray!
+ var dotCollection : [UIView]!
+
+ // Set up for parameters that can be passed in
+ init(page : String)
+ {
+ self.pageQuery = page
+
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ self.pageQuery = ""
+ super.init(coder: aDecoder)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view, typically from a nib.
+
+ // Instantiate the view page controller and add it to the Main View as a child view
+ // Prepares the login-type views
+ self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("NotificationPageViewController") as! UIPageViewController
+ self.pageViewController.delegate = self
+ self.pageViewController.dataSource = self
+ let facebookVC = createViewController("NotificationTableView")
+ let twitterVC = createViewController("NotificationTableView")
+ let instagramVC = createViewController("NotificationTableView")
+ let tumblrVC = createViewController("NotificationTableView")
+ let vineVC = createViewController("NotificationTableView")
+ pages = NSArray(objects: facebookVC, twitterVC, instagramVC, tumblrVC, vineVC)
+ viewControllers = NSArray(object: facebookVC)
+ self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
+ self.addChildViewController(self.pageViewController)
+ self.pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.feedViewContainer.frame.width, height: self.feedViewContainer.frame.height)
+ self.feedViewContainer.addSubview(self.pageViewController.view)
+ //self.view.addSubview(self.pageViewController.view)
+ self.pageViewController.didMoveToParentViewController(self)
+ dotCollection = customPageControls.subviews
+
+ // Position Page Control
+ initializeConstraints()
+ stylePageControls()
+ }
+
+ //MARK: Actions
+
+
+ // Creates and returns view controllers by storyboard ID
+
+ func createViewController(identifierID : String) -> UIViewController {
+ let vc = self.storyboard!.instantiateViewControllerWithIdentifier(identifierID) as UIViewController
+ return vc
+ }
+
+ // MARK: Page View Controller Data Source
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == 0 || index == NSNotFound) {
+ return nil
+ }
+ index--
+ return pages[index] as! UIViewController
+ }
+
+ func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
+ let vc = viewController as UIViewController
+ var index = pages.indexOfObject(vc)
+ if (index == pages.count-1 || index == NSNotFound) {
+ return nil
+ }
+ index++
+ return pages[index] as! UIViewController
+
+ }
+
+ // Triggers after it has landed on a new page after swipe
+
+ func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
+
+ // Set the current page
+ networkName.text = pageViewController.viewControllers?.last?.restorationIdentifier
+
+ let currentIndex = pages.indexOfObject((pageViewController.viewControllers?.last)!)
+ for (index, element) in dotCollection.enumerate() {
+ if index == currentIndex {
+ element.alpha = CGFloat(1.0)
+ } else {
+ element.alpha = CGFloat(0.25)
+ }
+ }
+
+ }
+
+ // MARK : Other
+
+ func initializeConstraints() {
+ let screenHeight = UIScreen.mainScreen().bounds.height
+ if (screenHeight <= 480) {
+ print("iPhone4")
+
+ } else if screenHeight == 568 {
+ print("iPhone5")
+
+ } else {
+ print("iPhone6")
+
+ }
+ }
+
+ func stylePageControls() {
+ for dots in dotCollection {
+ dots.layer.cornerRadius = dots.frame.height/2
+ dots.alpha = CGFloat(0.25)
+ }
+
+ var currentIndex = pages.indexOfObject(viewControllers[0])
+ dotCollection[currentIndex].alpha = CGFloat(1.0)
+ }
+
+}
\ No newline at end of file
diff --git a/OutgoingMessageCell.xib b/OutgoingMessageCell.xib
new file mode 100644
index 0000000..5309961
--- /dev/null
+++ b/OutgoingMessageCell.xib
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OutgoingMessageCellController.swift b/OutgoingMessageCellController.swift
new file mode 100644
index 0000000..52d06d9
--- /dev/null
+++ b/OutgoingMessageCellController.swift
@@ -0,0 +1,28 @@
+//
+// OutgoingMessageCellController.swift
+// comblie
+//
+// Created by Cal on 10/25/15.
+// Copyright © 2015 Comblie. All rights reserved.
+//
+
+import UIKit
+
+class OutgoingMessageCellController: UITableViewCell {
+
+ @IBOutlet weak var messageBackground: UIView!
+ @IBOutlet weak var message: UILabel!
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ self.messageBackground.layer.cornerRadius = CGFloat(13)
+ }
+
+ override func setSelected(selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+
+ // Configure the view for the selected state
+ }
+
+}
diff --git a/Podfile b/Podfile
new file mode 100644
index 0000000..872efe8
--- /dev/null
+++ b/Podfile
@@ -0,0 +1,19 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '9.0'
+use_frameworks!
+
+target 'comblie' do
+pod 'Alamofire', '2.0.2'
+pod 'SwiftyJSON', :git => 'https://github.com/SwiftyJSON/SwiftyJSON.git'
+pod 'Firebase', '>= 2.4.1'
+pod "OAuthSwift", "~> 0.4.6"
+end
+
+target 'comblieTests' do
+
+end
+
+target 'comblieUITests' do
+
+end
+
diff --git a/Podfile.lock b/Podfile.lock
new file mode 100644
index 0000000..e6f3572
--- /dev/null
+++ b/Podfile.lock
@@ -0,0 +1,28 @@
+PODS:
+ - Alamofire (2.0.2)
+ - Firebase (2.4.2)
+ - OAuthSwift (0.4.6)
+ - SwiftyJSON (2.3.0)
+
+DEPENDENCIES:
+ - Alamofire (= 2.0.2)
+ - Firebase (>= 2.4.1)
+ - OAuthSwift (~> 0.4.6)
+ - SwiftyJSON (from `https://github.com/SwiftyJSON/SwiftyJSON.git`)
+
+EXTERNAL SOURCES:
+ SwiftyJSON:
+ :git: https://github.com/SwiftyJSON/SwiftyJSON.git
+
+CHECKOUT OPTIONS:
+ SwiftyJSON:
+ :commit: 3b5d0d4e0c19173b1bf0dc823bde25ad870f70c0
+ :git: https://github.com/SwiftyJSON/SwiftyJSON.git
+
+SPEC CHECKSUMS:
+ Alamofire: 8edbab00802a752bb5240cc2abe70e7e881488ad
+ Firebase: 5e898ed5012c81d28ca5fae1113c6b61a172bc6d
+ OAuthSwift: 8c738cc56c942a541f5c6d0362a892cb149d10b1
+ SwiftyJSON: 8d6b61a70277ef2a5d710d372e06e7e2d87fb9e4
+
+COCOAPODS: 0.38.2
diff --git a/Pods/Alamofire/LICENSE b/Pods/Alamofire/LICENSE
new file mode 100644
index 0000000..5b7934d
--- /dev/null
+++ b/Pods/Alamofire/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+
+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/Pods/Alamofire/README.md b/Pods/Alamofire/README.md
new file mode 100644
index 0000000..0f8612d
--- /dev/null
+++ b/Pods/Alamofire/README.md
@@ -0,0 +1,1078 @@
+
+
+[](https://travis-ci.org/Alamofire/Alamofire)
+[](https://img.shields.io/cocoapods/v/Alamofire.svg)
+[](https://github.com/Carthage/Carthage)
+[](http://cocoadocs.org/docsets/Alamofire)
+[](http://twitter.com/AlamofireSF)
+
+Alamofire is an HTTP networking library written in Swift.
+
+## Features
+
+- [x] Chainable Request / Response methods
+- [x] URL / JSON / plist Parameter Encoding
+- [x] Upload File / Data / Stream / MultipartFormData
+- [x] Download using Request or Resume data
+- [x] Authentication with NSURLCredential
+- [x] HTTP Response Validation
+- [x] TLS Certificate and Public Key Pinning
+- [x] Progress Closure & NSProgress
+- [x] cURL Debug Output
+- [x] Comprehensive Unit Test Coverage
+- [x] [Complete Documentation](http://cocoadocs.org/docsets/Alamofire)
+
+## Requirements
+
+- iOS 8.0+ / Mac OS X 10.9+ / watchOS 2
+- Xcode 7.0+
+
+## Migration Guides
+
+- [Alamofire 2.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%202.0%20Migration%20Guide.md)
+
+## Communication
+
+- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/alamofire). (Tag 'alamofire')
+- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/alamofire).
+- If you **found a bug**, open an issue.
+- If you **have a feature request**, open an issue.
+- If you **want to contribute**, submit a pull request.
+
+## Installation
+
+> **Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks (10.9).**
+>
+> Alamofire is no longer supported on iOS 7 due to the lack of support for frameworks. Without frameworks, running Travis-CI against iOS 7 would require a second duplicated test target. The separate test suite would need to import all the Swift files and the tests would need to be duplicated and re-written. This split would be too difficult to maintain to ensure the highest possible quality of the Alamofire ecosystem.
+
+### CocoaPods
+
+[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects.
+
+CocoaPods 0.38.2 is required to build Alamofire on the `swift-2.0` branch. It adds support for Xcode 7, Swift 2.0 and embedded frameworks. You can install it with the following command:
+
+```bash
+$ gem install cocoapods
+```
+
+To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`:
+
+```ruby
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+use_frameworks!
+
+pod 'Alamofire', '~> 2.0'
+```
+
+Then, run the following command:
+
+```bash
+$ pod install
+```
+
+### Carthage
+
+[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
+
+You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
+
+```bash
+$ brew update
+$ brew install carthage
+```
+
+To integrate Alamofire into your Xcode project using Carthage, specify it in your `Cartfile`:
+
+```ogdl
+github "Alamofire/Alamofire" ~> 2.0
+```
+
+### Manually
+
+If you prefer not to use either of the aforementioned dependency managers, you can integrate Alamofire into your project manually.
+
+#### Embedded Framework
+
+- Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
+
+```bash
+$ git init
+```
+
+- Add Alamofire as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following command:
+
+```bash
+$ git submodule add https://github.com/Alamofire/Alamofire.git
+```
+
+- Open the new `Alamofire` folder, and drag the `Alamofire.xcodeproj` into the Project Navigator of your application's Xcode project.
+
+ > It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.
+
+- Select the `Alamofire.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target.
+- Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.
+- In the tab bar at the top of that window, open the "General" panel.
+- Click on the `+` button under the "Embedded Binaries" section.
+- You will see two different `Alamofire.xcodeproj` folders each with two different versions of the `Alamofire.framework` nested inside a `Products` folder.
+
+ > It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `Alamofire.framework`.
+
+- Select the top `Alamofire.framework` for iOS and the bottom one for OS X.
+
+ > You can verify which one you selected by inspecting the build log for your project. The build target for `Alamofire` will be listed as either `Alamofire iOS` or `Alamofire OSX`.
+
+- And that's it!
+
+> The `Alamofire.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.
+
+---
+
+## Usage
+
+### Making a Request
+
+```swift
+import Alamofire
+
+Alamofire.request(.GET, "http://httpbin.org/get")
+```
+
+### Response Handling
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
+ .response { request, response, data, error in
+ print(request)
+ print(response)
+ print(error)
+ }
+```
+
+> Networking in Alamofire is done _asynchronously_. Asynchronous programming may be a source of frustration to programmers unfamiliar with the concept, but there are [very good reasons](https://developer.apple.com/library/ios/qa/qa1693/_index.html) for doing it this way.
+
+> Rather than blocking execution to wait for a response from the server, a [callback](http://en.wikipedia.org/wiki/Callback_%28computer_programming%29) is specified to handle the response once it's received. The result of a request is only available inside the scope of a response handler. Any execution contingent on the response or data received from the server must be done within a handler.
+
+### Response Serialization
+
+**Built-in Response Methods**
+
+- `response()`
+- `responseString(encoding: NSStringEncoding)`
+- `responseJSON(options: NSJSONReadingOptions)`
+- `responsePropertyList(options: NSPropertyListReadOptions)`
+
+#### Response String Handler
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get")
+ .responseString { _, _, result in
+ print("Success: \(result.isSuccess)")
+ print("Response String: \(result.value)")
+ }
+```
+
+#### Response JSON Handler
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get")
+ .responseJSON { _, _, result in
+ print(result)
+ debugPrint(result)
+ }
+```
+
+#### Chained Response Handlers
+
+Response handlers can even be chained:
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get")
+ .responseString { _, _, result in
+ print("Response String: \(result.value)")
+ }
+ .responseJSON { _, _, result in
+ print("Response JSON: \(result.value)")
+ }
+```
+
+### HTTP Methods
+
+`Alamofire.Method` lists the HTTP methods defined in [RFC 7231 §4.3](http://tools.ietf.org/html/rfc7231#section-4.3):
+
+```swift
+public enum Method: String {
+ case OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT
+}
+```
+
+These values can be passed as the first argument of the `Alamofire.request` method:
+
+```swift
+Alamofire.request(.POST, "http://httpbin.org/post")
+
+Alamofire.request(.PUT, "http://httpbin.org/put")
+
+Alamofire.request(.DELETE, "http://httpbin.org/delete")
+```
+
+### Parameters
+
+#### GET Request With URL-Encoded Parameters
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
+// http://httpbin.org/get?foo=bar
+```
+
+#### POST Request With URL-Encoded Parameters
+
+```swift
+let parameters = [
+ "foo": "bar",
+ "baz": ["a", 1],
+ "qux": [
+ "x": 1,
+ "y": 2,
+ "z": 3
+ ]
+]
+
+Alamofire.request(.POST, "http://httpbin.org/post", parameters: parameters)
+// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3
+```
+
+### Parameter Encoding
+
+Parameters can also be encoded as JSON, Property List, or any custom format, using the `ParameterEncoding` enum:
+
+```swift
+enum ParameterEncoding {
+ case URL
+ case URLEncodedInURL
+ case JSON
+ case PropertyList(format: NSPropertyListFormat, options: NSPropertyListWriteOptions)
+ case Custom((URLRequestConvertible, [String: AnyObject]?) -> (NSMutableURLRequest, NSError?))
+
+ func encode(request: NSURLRequest, parameters: [String: AnyObject]?) -> (NSURLRequest, NSError?)
+ { ... }
+}
+```
+
+- `URL`: A query string to be set as or appended to any existing URL query for `GET`, `HEAD`, and `DELETE` requests, or set as the body for requests with any other HTTP method. The `Content-Type` HTTP header field of an encoded request with HTTP body is set to `application/x-www-form-urlencoded`. _Since there is no published specification for how to encode collection types, Alamofire follows the convention of appending `[]` to the key for array values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for nested dictionary values (`foo[bar]=baz`)._
+- `URLEncodedInURL`: Creates query string to be set as or appended to any existing URL query. Uses the same implementation as the `.URL` case, but always applies the encoded result to the URL.
+- `JSON`: Uses `NSJSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the request. The `Content-Type` HTTP header field of an encoded request is set to `application/json`.
+- `PropertyList`: Uses `NSPropertyListSerialization` to create a plist representation of the parameters object, according to the associated format and write options values, which is set as the body of the request. The `Content-Type` HTTP header field of an encoded request is set to `application/x-plist`.
+- `Custom`: Uses the associated closure value to construct a new request given an existing request and parameters.
+
+#### Manual Parameter Encoding of an NSURLRequest
+
+```swift
+let URL = NSURL(string: "http://httpbin.org/get")!
+var request = NSURLRequest(URL: URL)
+
+let parameters = ["foo": "bar"]
+let encoding = Alamofire.ParameterEncoding.URL
+(request, _) = encoding.encode(request, parameters: parameters)
+```
+
+#### POST Request with JSON-encoded Parameters
+
+```swift
+let parameters = [
+ "foo": [1,2,3],
+ "bar": [
+ "baz": "qux"
+ ]
+]
+
+Alamofire.request(.POST, "http://httpbin.org/post", parameters: parameters, encoding: .JSON)
+// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}
+```
+
+### HTTP Headers
+
+Adding a custom HTTP header to a `Request` is supported directly in the global `request` method. This makes it easy to attach HTTP headers to a `Request` that can be constantly changing.
+
+> For HTTP headers that do not change, it is recommended to set them on the `NSURLSessionConfiguration` so they are automatically applied to any `NSURLSessionTask` created by the underlying `NSURLSession`.
+
+```swift
+let headers = [
+ "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
+ "Content-Type": "application/x-www-form-urlencoded"
+]
+
+Alamofire.request(.GET, "http://httpbin.org/get", headers: headers)
+ .responseJSON { _, _, result in
+ debugPrint(result)
+ }
+```
+
+### Caching
+
+Caching is handled on the system framework level by [`NSURLCache`](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/occ/cl/NSURLCache).
+
+### Uploading
+
+**Supported Upload Types**
+
+- File
+- Data
+- Stream
+- MultipartFormData
+
+#### Uploading a File
+
+```swift
+let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
+Alamofire.upload(.POST, "http://httpbin.org/post", file: fileURL)
+```
+
+#### Uploading with Progress
+
+```swift
+Alamofire.upload(.POST, "http://httpbin.org/post", file: fileURL)
+ .progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
+ print(totalBytesWritten)
+
+ // This closure is NOT called on the main queue for performance
+ // reasons. To update your ui, dispatch to the main queue.
+ dispatch_async(dispatch_get_main_queue) {
+ print("Total bytes written on main queue: \(totalBytesWritten)")
+ }
+ }
+ .responseJSON { request, response, result in
+ debugPrint(result)
+ }
+```
+
+#### Uploading MultipartFormData
+
+```swift
+Alamofire.upload(
+ .POST,
+ URLString: "http://httpbin.org/post",
+ multipartFormData: { multipartFormData in
+ multipartFormData.appendBodyPart(fileURL: unicornImageURL, name: "unicorn")
+ multipartFormData.appendBodyPart(fileURL: rainbowImageURL, name: "rainbow")
+ },
+ encodingCompletion: { encodingResult in
+ switch encodingResult {
+ case .Success(let upload, _, _):
+ upload.responseJSON { request, response, result in
+ debugPrint(result)
+ }
+ case .Failure(let encodingError):
+ print(encodingError)
+ }
+ }
+)
+```
+
+### Downloading
+
+**Supported Download Types**
+
+- Request
+- Resume Data
+
+#### Downloading a File
+
+```swift
+Alamofire.download(.GET, "http://httpbin.org/stream/100") { temporaryURL, response in
+ let fileManager = NSFileManager.defaultManager()
+ if let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
+ let pathComponent = response.suggestedFilename
+ return directoryURL.URLByAppendingPathComponent(pathComponent!)
+ }
+
+ return temporaryURL
+}
+```
+
+#### Using the Default Download Destination
+
+```swift
+let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
+Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
+```
+
+#### Downloading a File w/Progress
+
+```swift
+Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
+ .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
+ print(totalBytesRead)
+
+ // This closure is NOT called on the main queue for performance
+ // reasons. To update your ui, dispatch to the main queue.
+ dispatch_async(dispatch_get_main_queue) {
+ print("Total bytes read on main queue: \(totalBytesRead)")
+ }
+ }
+ .response { request, response, _, error in
+ print(response)
+ }
+```
+
+#### Accessing Resume Data for Failed Downloads
+
+```swift
+Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
+ .response { request, response, data, error in
+ if let
+ data = data,
+ resumeDataString = NSString(data: data, encoding: NSUTF8StringEncoding)
+ {
+ print("Resume Data: \(resumeDataString)")
+ } else {
+ print("Resume Data was empty")
+ }
+ }
+```
+
+> The `data` parameter is automatically populated with the `resumeData` if available.
+
+```swift
+let download = Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
+download.response { request, response, data, error in
+ if let
+ resumeData = download.resumeData,
+ resumeDataString = NSString(data: data, encoding: NSUTF8StringEncoding)
+ {
+ print("Resume Data: \(resumeDataString)")
+ } else {
+ print("Resume Data was empty")
+ }
+}
+```
+
+### Authentication
+
+Authentication is handled on the system framework level by [`NSURLCredential` and `NSURLAuthenticationChallenge`](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLAuthenticationChallenge_Class/Reference/Reference.html).
+
+**Supported Authentication Schemes**
+
+- [HTTP Basic](http://en.wikipedia.org/wiki/Basic_access_authentication)
+- [HTTP Digest](http://en.wikipedia.org/wiki/Digest_access_authentication)
+- [Kerberos](http://en.wikipedia.org/wiki/Kerberos_%28protocol%29)
+- [NTLM](http://en.wikipedia.org/wiki/NT_LAN_Manager)
+
+#### HTTP Basic Authentication
+
+The `authenticate` method on a `Request` will automatically provide an `NSURLCredential` to an `NSURLAuthenticationChallenge` when appropriate:
+
+```swift
+let user = "user"
+let password = "password"
+
+Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
+ .authenticate(user: user, password: password)
+ .response { request, response, _, error in
+ print(response)
+ }
+```
+
+Depending upon your server implementation, an `Authorization` header may also be appropriate:
+
+```swift
+let user = "user"
+let password = "password"
+
+let credentialData = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
+let base64Credentials = credentialData.base64EncodedStringWithOptions(nil)
+
+let headers = ["Authorization": "Basic \(base64Credentials)"]
+
+Alamofire.request(.GET, "http://httpbin.org/basic-auth/user/password", headers: headers)
+ .responseJSON { _, _, result in
+ print(result)
+ }
+```
+
+#### Authentication with NSURLCredential
+
+```swift
+let user = "user"
+let password = "password"
+
+let credential = NSURLCredential(user: user, password: password, persistence: .ForSession)
+
+Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
+ .authenticate(usingCredential: credential)
+ .response { request, response, _, error in
+ print(response)
+ }
+```
+
+### Validation
+
+By default, Alamofire treats any completed request to be successful, regardless of the content of the response. Calling `validate` before a response handler causes an error to be generated if the response had an unacceptable status code or MIME type.
+
+#### Manual Validation
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
+ .validate(statusCode: 200..<300)
+ .validate(contentType: ["application/json"])
+ .response { _, _, _, error in
+ print(error)
+ }
+```
+
+#### Automatic Validation
+
+Automatically validates status code within `200...299` range, and that the `Content-Type` header of the response matches the `Accept` header of the request, if one is provided.
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
+ .validate()
+ .responseJSON { _, _, result in
+ switch result {
+ case .Success:
+ print("Validation Successful")
+ case .Failure(_, let error):
+ print(error)
+ }
+ }
+```
+
+### Printable
+
+```swift
+let request = Alamofire.request(.GET, "http://httpbin.org/ip")
+
+print(request)
+// GET http://httpbin.org/ip (200)
+```
+
+### DebugPrintable
+
+```swift
+let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
+
+debugPrint(request)
+```
+
+#### Output (cURL)
+
+```bash
+$ curl -i \
+ -H "User-Agent: Alamofire" \
+ -H "Accept-Encoding: Accept-Encoding: gzip;q=1.0,compress;q=0.5" \
+ -H "Accept-Language: en;q=1.0,fr;q=0.9,de;q=0.8,zh-Hans;q=0.7,zh-Hant;q=0.6,ja;q=0.5" \
+ "http://httpbin.org/get?foo=bar"
+```
+
+---
+
+## Advanced Usage
+
+> Alamofire is built on `NSURLSession` and the Foundation URL Loading System. To make the most of
+this framework, it is recommended that you be familiar with the concepts and capabilities of the underlying networking stack.
+
+**Recommended Reading**
+
+- [URL Loading System Programming Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html)
+- [NSURLSession Class Reference](https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/Introduction/Introduction.html#//apple_ref/occ/cl/NSURLSession)
+- [NSURLCache Class Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/occ/cl/NSURLCache)
+- [NSURLAuthenticationChallenge Class Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLAuthenticationChallenge_Class/Reference/Reference.html)
+
+### Manager
+
+Top-level convenience methods like `Alamofire.request` use a shared instance of `Alamofire.Manager`, which is configured with the default `NSURLSessionConfiguration`.
+
+As such, the following two statements are equivalent:
+
+```swift
+Alamofire.request(.GET, "http://httpbin.org/get")
+```
+
+```swift
+let manager = Alamofire.Manager.sharedInstance
+manager.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/get")))
+```
+
+Applications can create managers for background and ephemeral sessions, as well as new managers that customize the default session configuration, such as for default headers (`HTTPAdditionalHeaders`) or timeout interval (`timeoutIntervalForRequest`).
+
+#### Creating a Manager with Default Configuration
+
+```swift
+let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
+let manager = Alamofire.Manager(configuration: configuration)
+```
+
+#### Creating a Manager with Background Configuration
+
+```swift
+let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.example.app.background")
+let manager = Alamofire.Manager(configuration: configuration)
+```
+
+#### Creating a Manager with Ephemeral Configuration
+
+```swift
+let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
+let manager = Alamofire.Manager(configuration: configuration)
+```
+
+#### Modifying Session Configuration
+
+```swift
+var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders ?? [:]
+defaultHeaders["DNT"] = "1 (Do Not Track Enabled)"
+
+let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
+configuration.HTTPAdditionalHeaders = defaultHeaders
+
+let manager = Alamofire.Manager(configuration: configuration)
+```
+
+> This is **not** recommended for `Authorization` or `Content-Type` headers. Instead, use `URLRequestConvertible` and `ParameterEncoding`, respectively.
+
+### Request
+
+The result of a `request`, `upload`, or `download` method is an instance of `Alamofire.Request`. A request is always created using a constructor method from an owning manager, and never initialized directly.
+
+Methods like `authenticate`, `validate`, and `response` return the caller in order to facilitate chaining.
+
+Requests can be suspended, resumed, and cancelled:
+
+- `suspend()`: Suspends the underlying task and dispatch queue
+- `resume()`: Resumes the underlying task and dispatch queue. If the owning manager does not have `startRequestsImmediately` set to `true`, the request must call `resume()` in order to start.
+- `cancel()`: Cancels the underlying task, producing an error that is passed to any registered response handlers.
+
+### Response Serialization
+
+#### Creating a Custom Response Serializer
+
+Alamofire provides built-in response serialization for strings, JSON, and property lists, but others can be added in extensions on `Alamofire.Request`.
+
+For example, here's how a response handler using [Ono](https://github.com/mattt/Ono) might be implemented:
+
+```swift
+extension Request {
+ public static func XMLResponseSerializer() -> GenericResponseSerializer {
+ return GenericResponseSerializer { request, response, data in
+ guard let validData = data else {
+ let failureReason = "Data could not be serialized. Input data was nil."
+ let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+
+ do {
+ let XML = try ONOXMLDocument(data: validData)
+ return .Success(XML)
+ } catch {
+ return .Failure(data, error as NSError)
+ }
+ }
+ }
+
+ public func responseXMLDocument(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void) -> Self {
+ return response(responseSerializer: Request.XMLResponseSerializer(), completionHandler: completionHandler)
+ }
+}
+```
+
+#### Generic Response Object Serialization
+
+Generics can be used to provide automatic, type-safe response object serialization.
+
+```swift
+public protocol ResponseObjectSerializable {
+ init?(response: NSHTTPURLResponse, representation: AnyObject)
+}
+
+extension Request {
+ public func responseObject(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void) -> Self {
+ let responseSerializer = GenericResponseSerializer { request, response, data in
+ let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
+ let result = JSONResponseSerializer.serializeResponse(request, response, data)
+
+ switch result {
+ case .Success(let value):
+ if let
+ response = response,
+ responseObject = T(response: response, representation: value)
+ {
+ return .Success(responseObject)
+ } else {
+ let failureReason = "JSON could not be serialized into response object: \(value)"
+ let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+ case .Failure(let data, let error):
+ return .Failure(data, error)
+ }
+ }
+
+ return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
+ }
+}
+```
+
+```swift
+final class User: ResponseObjectSerializable {
+ let username: String
+ let name: String
+
+ init?(response: NSHTTPURLResponse, representation: AnyObject) {
+ self.username = response.URL!.lastPathComponent!
+ self.name = representation.valueForKeyPath("name") as! String
+ }
+}
+```
+
+```swift
+Alamofire.request(.GET, "http://example.com/users/mattt")
+ .responseObject { (_, _, result: Result) in
+ debugPrint(result)
+ }
+```
+
+The same approach can also be used to handle endpoints that return a representation of a collection of objects:
+
+```swift
+public protocol ResponseCollectionSerializable {
+ static func collection(response response: NSHTTPURLResponse, representation: AnyObject) -> [Self]
+}
+
+extension Alamofire.Request {
+ public func responseCollection(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<[T]>) -> Void) -> Self {
+ let responseSerializer = GenericResponseSerializer<[T]> { request, response, data in
+ let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
+ let result = JSONSerializer.serializeResponse(request, response, data)
+
+ switch result {
+ case .Success(let value):
+ if let response = response {
+ return .Success(T.collection(response: response, representation: value))
+ } else {
+ let failureReason = "Response collection could not be serialized due to nil response"
+ let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+ case .Failure(let data, let error):
+ return .Failure(data, error)
+ }
+ }
+
+ return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
+ }
+}
+```
+
+```swift
+final class User: ResponseObjectSerializable, ResponseCollectionSerializable {
+ let username: String
+ let name: String
+
+ init?(response: NSHTTPURLResponse, representation: AnyObject) {
+ self.username = response.URL!.lastPathComponent!
+ self.name = representation.valueForKeyPath("name") as! String
+ }
+
+ static func collection(response response: NSHTTPURLResponse, representation: AnyObject) -> [User] {
+ var users: [User] = []
+
+ if let representation = representation as? [[String: AnyObject]] {
+ for userRepresentation in representation {
+ if let user = User(response: response, representation: userRepresentation) {
+ users.append(user)
+ }
+ }
+ }
+
+ return users
+ }
+}
+```
+
+```swift
+Alamofire.request(.GET, "http://example.com/users")
+ .responseCollection { (_, _, result: Result<[User]>) in
+ debugPrint(result)
+ }
+```
+
+### URLStringConvertible
+
+Types adopting the `URLStringConvertible` protocol can be used to construct URL strings, which are then used to construct URL requests. `NSString`, `NSURL`, `NSURLComponents`, and `NSURLRequest` conform to `URLStringConvertible` by default, allowing any of them to be passed as `URLString` parameters to the `request`, `upload`, and `download` methods:
+
+```swift
+let string = NSString(string: "http://httpbin.org/post")
+Alamofire.request(.POST, string)
+
+let URL = NSURL(string: string)!
+Alamofire.request(.POST, URL)
+
+let URLRequest = NSURLRequest(URL: URL)
+Alamofire.request(.POST, URLRequest) // overrides `HTTPMethod` of `URLRequest`
+
+let URLComponents = NSURLComponents(URL: URL, resolvingAgainstBaseURL: true)
+Alamofire.request(.POST, URLComponents)
+```
+
+Applications interacting with web applications in a significant manner are encouraged to have custom types conform to `URLStringConvertible` as a convenient way to map domain-specific models to server resources.
+
+#### Type-Safe Routing
+
+```swift
+extension User: URLStringConvertible {
+ static let baseURLString = "http://example.com"
+
+ var URLString: String {
+ return User.baseURLString + "/users/\(username)/"
+ }
+}
+```
+
+```swift
+let user = User(username: "mattt")
+Alamofire.request(.GET, user) // http://example.com/users/mattt
+```
+
+### URLRequestConvertible
+
+Types adopting the `URLRequestConvertible` protocol can be used to construct URL requests. `NSURLRequest` conforms to `URLRequestConvertible` by default, allowing it to be passed into `request`, `upload`, and `download` methods directly (this is the recommended way to specify custom HTTP body for individual requests):
+
+```swift
+let URL = NSURL(string: "http://httpbin.org/post")!
+let mutableURLRequest = NSMutableURLRequest(URL: URL)
+mutableURLRequest.HTTPMethod = "POST"
+
+let parameters = ["foo": "bar"]
+
+do {
+ mutableURLRequest.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions())
+} catch {
+ // No-op
+}
+
+mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
+
+Alamofire.request(mutableURLRequest)
+```
+
+Applications interacting with web applications in a significant manner are encouraged to have custom types conform to `URLRequestConvertible` as a way to ensure consistency of requested endpoints. Such an approach can be used to abstract away server-side inconsistencies and provide type-safe routing, as well as manage authentication credentials and other state.
+
+#### API Parameter Abstraction
+
+```swift
+enum Router: URLRequestConvertible {
+ static let baseURLString = "http://example.com"
+ static let perPage = 50
+
+ case Search(query: String, page: Int)
+
+ // MARK: URLRequestConvertible
+
+ var URLRequest: NSMutableURLRequest {
+ let result: (path: String, parameters: [String: AnyObject]) = {
+ switch self {
+ case .Search(let query, let page) where page > 1:
+ return ("/search", ["q": query, "offset": Router.perPage * page])
+ case .Search(let query, _):
+ return ("/search", ["q": query])
+ }
+ }()
+
+ let URL = NSURL(string: Router.baseURLString)!
+ let URLRequest = NSURLRequest(URL: URL.URLByAppendingPathComponent(result.path))
+ let encoding = Alamofire.ParameterEncoding.URL
+
+ return encoding.encode(URLRequest, parameters: result.parameters).0
+ }
+}
+```
+
+```swift
+Alamofire.request(Router.Search(query: "foo bar", page: 1)) // ?q=foo%20bar&offset=50
+```
+
+#### CRUD & Authorization
+
+```swift
+enum Router: URLRequestConvertible {
+ static let baseURLString = "http://example.com"
+ static var OAuthToken: String?
+
+ case CreateUser([String: AnyObject])
+ case ReadUser(String)
+ case UpdateUser(String, [String: AnyObject])
+ case DestroyUser(String)
+
+ var method: Alamofire.Method {
+ switch self {
+ case .CreateUser:
+ return .POST
+ case .ReadUser:
+ return .GET
+ case .UpdateUser:
+ return .PUT
+ case .DestroyUser:
+ return .DELETE
+ }
+ }
+
+ var path: String {
+ switch self {
+ case .CreateUser:
+ return "/users"
+ case .ReadUser(let username):
+ return "/users/\(username)"
+ case .UpdateUser(let username, _):
+ return "/users/\(username)"
+ case .DestroyUser(let username):
+ return "/users/\(username)"
+ }
+ }
+
+ // MARK: URLRequestConvertible
+
+ var URLRequest: NSMutableURLRequest {
+ let URL = NSURL(string: Router.baseURLString)!
+ let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path))
+ mutableURLRequest.HTTPMethod = method.rawValue
+
+ if let token = Router.OAuthToken {
+ mutableURLRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+ }
+
+ switch self {
+ case .CreateUser(let parameters):
+ return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0
+ case .UpdateUser(_, let parameters):
+ return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0
+ default:
+ return mutableURLRequest
+ }
+ }
+}
+```
+
+```swift
+Alamofire.request(Router.ReadUser("mattt")) // GET /users/mattt
+```
+
+### Security
+
+Using a secure HTTPS connection when communicating with servers and web services is an important step in securing sensitive data. By default, Alamofire will evaluate the certificate chain provided by the server using Apple's built in validation provided by the Security framework. While this guarantees the certificate chain is valid, it does not prevent man-in-the-middle (MITM) attacks or other potential vulnerabilities. In order to mitigate MITM attacks, applications dealing with sensitive customer data or financial information should use certificate or public key pinning provided by the `ServerTrustPolicy`.
+
+#### ServerTrustPolicy
+
+The `ServerTrustPolicy` enumeration evaluates the server trust generally provided by an `NSURLAuthenticationChallenge` when connecting to a server over a secure HTTPS connection.
+
+```swift
+let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
+ certificates: ServerTrustPolicy.certificatesInBundle(),
+ validateCertificateChain: true,
+ validateHost: true
+)
+```
+
+There are many different cases of server trust evaluation giving you complete control over the validation process:
+
+* `PerformDefaultEvaluation`: Uses the default server trust evaluation while allowing you to control whether to validate the host provided by the challenge.
+* `PinCertificates`: Uses the pinned certificates to validate the server trust. The server trust is considered valid if one of the pinned certificates match one of the server certificates.
+* `PinPublicKeys`: Uses the pinned public keys to validate the server trust. The server trust is considered valid if one of the pinned public keys match one of the server certificate public keys.
+* `DisableEvaluation`: Disables all evaluation which in turn will always consider any server trust as valid.
+* `CustomEvaluation`: Uses the associated closure to evaluate the validity of the server trust thus giving you complete control over the validation process. Use with caution.
+
+#### Server Trust Policy Manager
+
+The `ServerTrustPolicyManager` is responsible for storing an internal mapping of server trust policies to a particular host. This allows Alamofire to evaluate each host against a different server trust policy.
+
+```swift
+let serverTrustPolicies: [String: ServerTrustPolicy] = [
+ "test.example.com": .PinCertificates(
+ certificates: ServerTrustPolicy.certificatesInBundle(),
+ validateCertificateChain: true,
+ validateHost: true
+ ),
+ "insecure.expired-apis.com": .DisableEvaluation
+]
+
+let manager = Manager(
+ configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
+ serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
+)
+```
+
+> Make sure to keep a reference to the new `Manager` instance, otherwise your requests will all get cancelled when your `manager` is deallocated.
+
+These server trust policies will result in the following behavior:
+
+* `test.example.com` will always use certificate pinning with certificate chain and host validation enabled thus requiring the following criteria to be met to allow the TLS handshake to succeed:
+ * Certificate chain MUST be valid.
+ * Certificate chain MUST include one of the pinned certificates.
+ * Challenge host MUST match the host in the certificate chain's leaf certificate.
+* `insecure.expired-apis.com` will never evaluate the certificate chain and will always allow the TLS handshake to succeed.
+* All other hosts will use the default evaluation provided by Apple.
+
+##### Subclassing Server Trust Policy Manager
+
+If you find yourself needing more flexible server trust policy matching behavior (i.e. wildcarded domains), then subclass the `ServerTrustPolicyManager` and override the `serverTrustPolicyForHost` method with your own custom implementation.
+
+```swift
+class CustomServerTrustPolicyManager: ServerTrustPolicyManager {
+ override func serverTrustPolicyForHost(host: String) -> ServerTrustPolicy? {
+ var policy: ServerTrustPolicy?
+
+ // Implement your custom domain matching behavior...
+
+ return policy
+ }
+}
+```
+
+#### Validating the Host
+
+The `.PerformDefaultEvaluation`, `.PinCertificates` and `.PinPublicKeys` server trust policies all take a `validateHost` parameter. Setting the value to `true` will cause the server trust evaluation to verify that hostname in the certificate matches the hostname of the challenge. If they do not match, evaluation will fail. A `validateHost` value of `false` will still evaluate the full certificate chain, but will not validate the hostname of the leaf certificate.
+
+> It is recommended that `validateHost` always be set to `true` in production environments.
+
+#### Validating the Certificate Chain
+
+Pinning certificates and public keys both have the option of validating the certificate chain using the `validateCertificateChain` parameter. By setting this value to `true`, the full certificate chain will be evaluated in addition to performing a byte equality check against the pinned certficates or public keys. A value of `false` will skip the certificate chain validation, but will still perform the byte equality check.
+
+There are several cases where it may make sense to disable certificate chain validation. The most common use cases for disabling validation are self-signed and expired certificates. The evaluation would always fail in both of these cases, but the byte equality check will still ensure you are receiving the certificate you expect from the server.
+
+> It is recommended that `validateCertificateChain` always be set to `true` in production environments.
+
+---
+
+## Component Libraries
+
+In order to keep Alamofire focused specifically on core networking implementations, additional component libraries have been created by the [Alamofire Software Foundation](https://github.com/Alamofire/Foundation) to bring additional functionality to the Alamofire ecosystem.
+
+* [AlamofireImage](https://github.com/Alamofire/AlamofireImage) - An image library including image response serializers, `UIImage` and `UIImageView` extensions, custom image filters, an auto-purging in-memory cache and a priority-based image downloading system.
+
+## Open Rdars
+
+The following rdars have some affect on the current implementation of Alamofire.
+
+* [rdar://22024442](http://www.openradar.me/radar?id=6082025006039040) - Array of [SecCertificate] crashing Swift 2.0 compiler in optimized builds
+* [rdar://21349340](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in test case
+* [rdar://22307360](http://www.openradar.me/radar?id=4895563208196096) - Swift #available check not working properly with min deployment target
+
+## FAQ
+
+### What's the origin of the name Alamofire?
+
+Alamofire is named after the [Alamo Fire flower](https://aggie-horticulture.tamu.edu/wildseed/alamofire.html), a hybrid variant of the Bluebonnet, the official state flower of Texas.
+
+---
+
+## Credits
+
+Alamofire is owned and maintained by the [Alamofire Software Foundation](http://alamofire.org). You can follow them on Twitter at [@AlamofireSF](https://twitter.com/AlamofireSF) for project updates and releases.
+
+### Security Disclosure
+
+If you believe you have identified a security vulnerability with Alamofire, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker.
+
+## License
+
+Alamofire is released under the MIT license. See LICENSE for details.
diff --git a/Pods/Alamofire/Source/Alamofire.swift b/Pods/Alamofire/Source/Alamofire.swift
new file mode 100644
index 0000000..3b52d0f
--- /dev/null
+++ b/Pods/Alamofire/Source/Alamofire.swift
@@ -0,0 +1,368 @@
+// Alamofire.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+// MARK: - URLStringConvertible
+
+/**
+ Types adopting the `URLStringConvertible` protocol can be used to construct URL strings, which are then used to
+ construct URL requests.
+*/
+public protocol URLStringConvertible {
+ /**
+ A URL that conforms to RFC 2396.
+
+ Methods accepting a `URLStringConvertible` type parameter parse it according to RFCs 1738 and 1808.
+
+ See https://tools.ietf.org/html/rfc2396
+ See https://tools.ietf.org/html/rfc1738
+ See https://tools.ietf.org/html/rfc1808
+ */
+ var URLString: String { get }
+}
+
+extension String: URLStringConvertible {
+ public var URLString: String {
+ return self
+ }
+}
+
+extension NSURL: URLStringConvertible {
+ public var URLString: String {
+ return absoluteString
+ }
+}
+
+extension NSURLComponents: URLStringConvertible {
+ public var URLString: String {
+ return URL!.URLString
+ }
+}
+
+extension NSURLRequest: URLStringConvertible {
+ public var URLString: String {
+ return URL!.URLString
+ }
+}
+
+// MARK: - URLRequestConvertible
+
+/**
+ Types adopting the `URLRequestConvertible` protocol can be used to construct URL requests.
+*/
+public protocol URLRequestConvertible {
+ /// The URL request.
+ var URLRequest: NSMutableURLRequest { get }
+}
+
+extension NSURLRequest: URLRequestConvertible {
+ public var URLRequest: NSMutableURLRequest {
+ return self.mutableCopy() as! NSMutableURLRequest
+ }
+}
+
+// MARK: - Convenience
+
+func URLRequest(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil)
+ -> NSMutableURLRequest
+{
+ let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: URLString.URLString)!)
+ mutableURLRequest.HTTPMethod = method.rawValue
+
+ if let headers = headers {
+ for (headerField, headerValue) in headers {
+ mutableURLRequest.setValue(headerValue, forHTTPHeaderField: headerField)
+ }
+ }
+
+ return mutableURLRequest
+}
+
+// MARK: - Request Methods
+
+/**
+ Creates a request using the shared manager instance for the specified method, URL string, parameters, and
+ parameter encoding.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter parameters: The parameters. `nil` by default.
+ - parameter encoding: The parameter encoding. `.URL` by default.
+ - parameter headers: The HTTP headers. `nil` by default.
+
+ - returns: The created request.
+*/
+public func request(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ parameters: [String: AnyObject]? = nil,
+ encoding: ParameterEncoding = .URL,
+ headers: [String: String]? = nil)
+ -> Request
+{
+ return Manager.sharedInstance.request(
+ method,
+ URLString,
+ parameters: parameters,
+ encoding: encoding,
+ headers: headers
+ )
+}
+
+/**
+ Creates a request using the shared manager instance for the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request
+
+ - returns: The created request.
+*/
+public func request(URLRequest: URLRequestConvertible) -> Request {
+ return Manager.sharedInstance.request(URLRequest.URLRequest)
+}
+
+// MARK: - Upload Methods
+
+// MARK: File
+
+/**
+ Creates an upload request using the shared manager instance for the specified method, URL string, and file.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter file: The file to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ file: NSURL)
+ -> Request
+{
+ return Manager.sharedInstance.upload(method, URLString, headers: headers, file: file)
+}
+
+/**
+ Creates an upload request using the shared manager instance for the specified URL request and file.
+
+ - parameter URLRequest: The URL request.
+ - parameter file: The file to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(URLRequest: URLRequestConvertible, file: NSURL) -> Request {
+ return Manager.sharedInstance.upload(URLRequest, file: file)
+}
+
+// MARK: Data
+
+/**
+ Creates an upload request using the shared manager instance for the specified method, URL string, and data.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter data: The data to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ data: NSData)
+ -> Request
+{
+ return Manager.sharedInstance.upload(method, URLString, headers: headers, data: data)
+}
+
+/**
+ Creates an upload request using the shared manager instance for the specified URL request and data.
+
+ - parameter URLRequest: The URL request.
+ - parameter data: The data to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(URLRequest: URLRequestConvertible, data: NSData) -> Request {
+ return Manager.sharedInstance.upload(URLRequest, data: data)
+}
+
+// MARK: Stream
+
+/**
+ Creates an upload request using the shared manager instance for the specified method, URL string, and stream.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter stream: The stream to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ stream: NSInputStream)
+ -> Request
+{
+ return Manager.sharedInstance.upload(method, URLString, headers: headers, stream: stream)
+}
+
+/**
+ Creates an upload request using the shared manager instance for the specified URL request and stream.
+
+ - parameter URLRequest: The URL request.
+ - parameter stream: The stream to upload.
+
+ - returns: The created upload request.
+*/
+public func upload(URLRequest: URLRequestConvertible, stream: NSInputStream) -> Request {
+ return Manager.sharedInstance.upload(URLRequest, stream: stream)
+}
+
+// MARK: MultipartFormData
+
+/**
+ Creates an upload request using the shared manager instance for the specified method and URL string.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
+ - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
+ `MultipartFormDataEncodingMemoryThreshold` by default.
+ - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
+*/
+public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ multipartFormData: MultipartFormData -> Void,
+ encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold,
+ encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?)
+{
+ return Manager.sharedInstance.upload(
+ method,
+ URLString,
+ headers: headers,
+ multipartFormData: multipartFormData,
+ encodingMemoryThreshold: encodingMemoryThreshold,
+ encodingCompletion: encodingCompletion
+ )
+}
+
+/**
+ Creates an upload request using the shared manager instance for the specified method and URL string.
+
+ - parameter URLRequest: The URL request.
+ - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
+ - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
+ `MultipartFormDataEncodingMemoryThreshold` by default.
+ - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
+*/
+public func upload(
+ URLRequest: URLRequestConvertible,
+ multipartFormData: MultipartFormData -> Void,
+ encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold,
+ encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?)
+{
+ return Manager.sharedInstance.upload(
+ URLRequest,
+ multipartFormData: multipartFormData,
+ encodingMemoryThreshold: encodingMemoryThreshold,
+ encodingCompletion: encodingCompletion
+ )
+}
+
+// MARK: - Download Methods
+
+// MARK: URL Request
+
+/**
+ Creates a download request using the shared manager instance for the specified method and URL string.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter parameters: The parameters. `nil` by default.
+ - parameter encoding: The parameter encoding. `.URL` by default.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+*/
+public func download(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ parameters: [String: AnyObject]? = nil,
+ encoding: ParameterEncoding = .URL,
+ headers: [String: String]? = nil,
+ destination: Request.DownloadFileDestination)
+ -> Request
+{
+ return Manager.sharedInstance.download(
+ method,
+ URLString,
+ parameters: parameters,
+ encoding: encoding,
+ headers: headers,
+ destination: destination
+ )
+}
+
+/**
+ Creates a download request using the shared manager instance for the specified URL request.
+
+ - parameter URLRequest: The URL request.
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+*/
+public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request {
+ return Manager.sharedInstance.download(URLRequest, destination: destination)
+}
+
+// MARK: Resume Data
+
+/**
+ Creates a request using the shared manager instance for downloading from the resume data produced from a
+ previous request cancellation.
+
+ - parameter resumeData: The resume data. This is an opaque data blob produced by `NSURLSessionDownloadTask`
+ when a task is cancelled. See `NSURLSession -downloadTaskWithResumeData:` for additional
+ information.
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+*/
+public func download(resumeData data: NSData, destination: Request.DownloadFileDestination) -> Request {
+ return Manager.sharedInstance.download(data, destination: destination)
+}
diff --git a/Pods/Alamofire/Source/Download.swift b/Pods/Alamofire/Source/Download.swift
new file mode 100644
index 0000000..1df90cc
--- /dev/null
+++ b/Pods/Alamofire/Source/Download.swift
@@ -0,0 +1,244 @@
+// Download.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+extension Manager {
+ private enum Downloadable {
+ case Request(NSURLRequest)
+ case ResumeData(NSData)
+ }
+
+ private func download(downloadable: Downloadable, destination: Request.DownloadFileDestination) -> Request {
+ var downloadTask: NSURLSessionDownloadTask!
+
+ switch downloadable {
+ case .Request(let request):
+ dispatch_sync(queue) {
+ downloadTask = self.session.downloadTaskWithRequest(request)
+ }
+ case .ResumeData(let resumeData):
+ dispatch_sync(queue) {
+ downloadTask = self.session.downloadTaskWithResumeData(resumeData)
+ }
+ }
+
+ let request = Request(session: session, task: downloadTask)
+
+ if let downloadDelegate = request.delegate as? Request.DownloadTaskDelegate {
+ downloadDelegate.downloadTaskDidFinishDownloadingToURL = { session, downloadTask, URL in
+ return destination(URL, downloadTask.response as! NSHTTPURLResponse)
+ }
+ }
+
+ delegate[request.delegate.task] = request.delegate
+
+ if startRequestsImmediately {
+ request.resume()
+ }
+
+ return request
+ }
+
+ // MARK: Request
+
+ /**
+ Creates a download request for the specified method, URL string, parameters, parameter encoding, headers
+ and destination.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter parameters: The parameters. `nil` by default.
+ - parameter encoding: The parameter encoding. `.URL` by default.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+ */
+ public func download(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ parameters: [String: AnyObject]? = nil,
+ encoding: ParameterEncoding = .URL,
+ headers: [String: String]? = nil,
+ destination: Request.DownloadFileDestination)
+ -> Request
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+ let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
+
+ return download(encodedURLRequest, destination: destination)
+ }
+
+ /**
+ Creates a request for downloading from the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+ */
+ public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request {
+ return download(.Request(URLRequest.URLRequest), destination: destination)
+ }
+
+ // MARK: Resume Data
+
+ /**
+ Creates a request for downloading from the resume data produced from a previous request cancellation.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter resumeData: The resume data. This is an opaque data blob produced by `NSURLSessionDownloadTask`
+ when a task is cancelled. See `NSURLSession -downloadTaskWithResumeData:` for
+ additional information.
+ - parameter destination: The closure used to determine the destination of the downloaded file.
+
+ - returns: The created download request.
+ */
+ public func download(resumeData: NSData, destination: Request.DownloadFileDestination) -> Request {
+ return download(.ResumeData(resumeData), destination: destination)
+ }
+}
+
+// MARK: -
+
+extension Request {
+ /**
+ A closure executed once a request has successfully completed in order to determine where to move the temporary
+ file written to during the download process. The closure takes two arguments: the temporary file URL and the URL
+ response, and returns a single argument: the file URL where the temporary file should be moved.
+ */
+ public typealias DownloadFileDestination = (NSURL, NSHTTPURLResponse) -> NSURL
+
+ /**
+ Creates a download file destination closure which uses the default file manager to move the temporary file to a
+ file URL in the first available directory with the specified search path directory and search path domain mask.
+
+ - parameter directory: The search path directory. `.DocumentDirectory` by default.
+ - parameter domain: The search path domain mask. `.UserDomainMask` by default.
+
+ - returns: A download file destination closure.
+ */
+ public class func suggestedDownloadDestination(
+ directory directory: NSSearchPathDirectory = .DocumentDirectory,
+ domain: NSSearchPathDomainMask = .UserDomainMask)
+ -> DownloadFileDestination
+ {
+ return { temporaryURL, response -> NSURL in
+ let directoryURLs = NSFileManager.defaultManager().URLsForDirectory(directory, inDomains: domain)
+
+ if !directoryURLs.isEmpty {
+ return directoryURLs[0].URLByAppendingPathComponent(response.suggestedFilename!)
+ }
+
+ return temporaryURL
+ }
+ }
+
+ /// The resume data of the underlying download task if available after a failure.
+ public var resumeData: NSData? {
+ var data: NSData?
+
+ if let delegate = delegate as? DownloadTaskDelegate {
+ data = delegate.resumeData
+ }
+
+ return data
+ }
+
+ // MARK: - DownloadTaskDelegate
+
+ class DownloadTaskDelegate: TaskDelegate, NSURLSessionDownloadDelegate {
+ var downloadTask: NSURLSessionDownloadTask? { return task as? NSURLSessionDownloadTask }
+ var downloadProgress: ((Int64, Int64, Int64) -> Void)?
+
+ var resumeData: NSData?
+ override var data: NSData? { return resumeData }
+
+ // MARK: - NSURLSessionDownloadDelegate
+
+ // MARK: Override Closures
+
+ var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> NSURL)?
+ var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)?
+ var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)?
+
+ // MARK: Delegate Methods
+
+ func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didFinishDownloadingToURL location: NSURL)
+ {
+ if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
+ do {
+ let destination = downloadTaskDidFinishDownloadingToURL(session, downloadTask, location)
+ try NSFileManager.defaultManager().moveItemAtURL(location, toURL: destination)
+ } catch {
+ self.error = error as NSError
+ }
+ }
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didWriteData bytesWritten: Int64,
+ totalBytesWritten: Int64,
+ totalBytesExpectedToWrite: Int64)
+ {
+ if let downloadTaskDidWriteData = downloadTaskDidWriteData {
+ downloadTaskDidWriteData(
+ session,
+ downloadTask,
+ bytesWritten,
+ totalBytesWritten,
+ totalBytesExpectedToWrite
+ )
+ } else {
+ progress.totalUnitCount = totalBytesExpectedToWrite
+ progress.completedUnitCount = totalBytesWritten
+
+ downloadProgress?(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
+ }
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didResumeAtOffset fileOffset: Int64,
+ expectedTotalBytes: Int64)
+ {
+ if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
+ downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
+ } else {
+ progress.totalUnitCount = expectedTotalBytes
+ progress.completedUnitCount = fileOffset
+ }
+ }
+ }
+}
diff --git a/Pods/Alamofire/Source/Error.swift b/Pods/Alamofire/Source/Error.swift
new file mode 100644
index 0000000..b776a3e
--- /dev/null
+++ b/Pods/Alamofire/Source/Error.swift
@@ -0,0 +1,66 @@
+// Error.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/// The `Error` struct provides a convenience for creating custom Alamofire NSErrors.
+public struct Error {
+ /// The domain used for creating all Alamofire errors.
+ public static let Domain = "com.alamofire.error"
+
+ /// The custom error codes generated by Alamofire.
+ public enum Code: Int {
+ case InputStreamReadFailed = -6000
+ case OutputStreamWriteFailed = -6001
+ case ContentTypeValidationFailed = -6002
+ case StatusCodeValidationFailed = -6003
+ case DataSerializationFailed = -6004
+ case StringSerializationFailed = -6005
+ case JSONSerializationFailed = -6006
+ case PropertyListSerializationFailed = -6007
+ }
+
+ /**
+ Creates an `NSError` with the given error code and failure reason.
+
+ - parameter code: The error code.
+ - parameter failureReason: The failure reason.
+
+ - returns: An `NSError` with the given error code and failure reason.
+ */
+ public static func errorWithCode(code: Code, failureReason: String) -> NSError {
+ return errorWithCode(code.rawValue, failureReason: failureReason)
+ }
+
+ /**
+ Creates an `NSError` with the given error code and failure reason.
+
+ - parameter code: The error code.
+ - parameter failureReason: The failure reason.
+
+ - returns: An `NSError` with the given error code and failure reason.
+ */
+ public static func errorWithCode(code: Int, failureReason: String) -> NSError {
+ let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]
+ return NSError(domain: Domain, code: code, userInfo: userInfo)
+ }
+}
diff --git a/Pods/Alamofire/Source/Manager.swift b/Pods/Alamofire/Source/Manager.swift
new file mode 100644
index 0000000..01f77da
--- /dev/null
+++ b/Pods/Alamofire/Source/Manager.swift
@@ -0,0 +1,668 @@
+// Manager.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/**
+ Responsible for creating and managing `Request` objects, as well as their underlying `NSURLSession`.
+*/
+public class Manager {
+
+ // MARK: - Properties
+
+ /**
+ A shared instance of `Manager`, used by top-level Alamofire request methods, and suitable for use directly
+ for any ad hoc requests.
+ */
+ public static let sharedInstance: Manager = {
+ let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
+ configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
+
+ return Manager(configuration: configuration)
+ }()
+
+ /**
+ Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
+ */
+ public static let defaultHTTPHeaders: [String: String] = {
+ // Accept-Encoding HTTP Header; see https://tools.ietf.org/html/rfc7230#section-4.2.3
+ let acceptEncoding: String = "gzip;q=1.0,compress;q=0.5"
+
+ // Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
+ let acceptLanguage: String = {
+ var components: [String] = []
+ for (index, languageCode) in (NSLocale.preferredLanguages() as [String]).enumerate() {
+ let q = 1.0 - (Double(index) * 0.1)
+ components.append("\(languageCode);q=\(q)")
+ if q <= 0.5 {
+ break
+ }
+ }
+
+ return components.joinWithSeparator(",")
+ }()
+
+ // User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
+ let userAgent: String = {
+ if let info = NSBundle.mainBundle().infoDictionary {
+ let executable: AnyObject = info[kCFBundleExecutableKey as String] ?? "Unknown"
+ let bundle: AnyObject = info[kCFBundleIdentifierKey as String] ?? "Unknown"
+ let version: AnyObject = info[kCFBundleVersionKey as String] ?? "Unknown"
+ let os: AnyObject = NSProcessInfo.processInfo().operatingSystemVersionString ?? "Unknown"
+
+ var mutableUserAgent = NSMutableString(string: "\(executable)/\(bundle) (\(version); OS \(os))") as CFMutableString
+ let transform = NSString(string: "Any-Latin; Latin-ASCII; [:^ASCII:] Remove") as CFString
+
+ if CFStringTransform(mutableUserAgent, UnsafeMutablePointer(nil), transform, false) {
+ return mutableUserAgent as String
+ }
+ }
+
+ return "Alamofire"
+ }()
+
+ return [
+ "Accept-Encoding": acceptEncoding,
+ "Accept-Language": acceptLanguage,
+ "User-Agent": userAgent
+ ]
+ }()
+
+ let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)
+
+ /// The underlying session.
+ public let session: NSURLSession
+
+ /// The session delegate handling all the task and session delegate callbacks.
+ public let delegate: SessionDelegate
+
+ /// Whether to start requests immediately after being constructed. `true` by default.
+ public var startRequestsImmediately: Bool = true
+
+ /**
+ The background completion handler closure provided by the UIApplicationDelegate
+ `application:handleEventsForBackgroundURLSession:completionHandler:` method. By setting the background
+ completion handler, the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` closure implementation
+ will automatically call the handler.
+
+ If you need to handle your own events before the handler is called, then you need to override the
+ SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` and manually call the handler when finished.
+
+ `nil` by default.
+ */
+ public var backgroundCompletionHandler: (() -> Void)?
+
+ // MARK: - Lifecycle
+
+ /**
+ Initializes the `Manager` instance with the given configuration and server trust policy.
+
+ - parameter configuration: The configuration used to construct the managed session.
+ `NSURLSessionConfiguration.defaultSessionConfiguration()` by default.
+ - parameter serverTrustPolicyManager: The server trust policy manager to use for evaluating all server trust
+ challenges. `nil` by default.
+
+ - returns: The new `Manager` instance.
+ */
+ public init(
+ configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration(),
+ serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
+ {
+ self.delegate = SessionDelegate()
+ self.session = NSURLSession(configuration: configuration, delegate: self.delegate, delegateQueue: nil)
+ self.session.serverTrustPolicyManager = serverTrustPolicyManager
+
+ self.delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
+ guard let strongSelf = self else { return }
+ dispatch_async(dispatch_get_main_queue()) { strongSelf.backgroundCompletionHandler?() }
+ }
+ }
+
+ deinit {
+ session.invalidateAndCancel()
+ }
+
+ // MARK: - Request
+
+ /**
+ Creates a request for the specified method, URL string, parameters, parameter encoding and headers.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter parameters: The parameters. `nil` by default.
+ - parameter encoding: The parameter encoding. `.URL` by default.
+ - parameter headers: The HTTP headers. `nil` by default.
+
+ - returns: The created request.
+ */
+ public func request(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ parameters: [String: AnyObject]? = nil,
+ encoding: ParameterEncoding = .URL,
+ headers: [String: String]? = nil)
+ -> Request
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+ let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
+ return request(encodedURLRequest)
+ }
+
+ /**
+ Creates a request for the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request
+
+ - returns: The created request.
+ */
+ public func request(URLRequest: URLRequestConvertible) -> Request {
+ var dataTask: NSURLSessionDataTask!
+
+ dispatch_sync(queue) {
+ dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
+ }
+
+ let request = Request(session: session, task: dataTask)
+ delegate[request.delegate.task] = request.delegate
+
+ if startRequestsImmediately {
+ request.resume()
+ }
+
+ return request
+ }
+
+ // MARK: - SessionDelegate
+
+ /**
+ Responsible for handling all delegate callbacks for the underlying session.
+ */
+ public final class SessionDelegate: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate {
+ private var subdelegates: [Int: Request.TaskDelegate] = [:]
+ private let subdelegateQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT)
+
+ subscript(task: NSURLSessionTask) -> Request.TaskDelegate? {
+ get {
+ var subdelegate: Request.TaskDelegate?
+ dispatch_sync(subdelegateQueue) {
+ subdelegate = self.subdelegates[task.taskIdentifier]
+ }
+
+ return subdelegate
+ }
+
+ set {
+ dispatch_barrier_async(subdelegateQueue) {
+ self.subdelegates[task.taskIdentifier] = newValue
+ }
+ }
+ }
+
+ // MARK: - NSURLSessionDelegate
+
+ // MARK: Override Closures
+
+ /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didBecomeInvalidWithError:`.
+ public var sessionDidBecomeInvalidWithError: ((NSURLSession, NSError?) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didReceiveChallenge:completionHandler:`.
+ public var sessionDidReceiveChallenge: ((NSURLSession, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?
+
+ /// Overrides default behavior for NSURLSessionDelegate method `URLSessionDidFinishEventsForBackgroundURLSession:`.
+ public var sessionDidFinishEventsForBackgroundURLSession: ((NSURLSession) -> Void)?
+
+ // MARK: Delegate Methods
+
+ /**
+ Tells the delegate that the session has been invalidated.
+
+ - parameter session: The session object that was invalidated.
+ - parameter error: The error that caused invalidation, or nil if the invalidation was explicit.
+ */
+ public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
+ sessionDidBecomeInvalidWithError?(session, error)
+ }
+
+ /**
+ Requests credentials from the delegate in response to a session-level authentication request from the remote server.
+
+ - parameter session: The session containing the task that requested authentication.
+ - parameter challenge: An object that contains the request for authentication.
+ - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ didReceiveChallenge challenge: NSURLAuthenticationChallenge,
+ completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
+ {
+ var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
+ var credential: NSURLCredential?
+
+ if let sessionDidReceiveChallenge = sessionDidReceiveChallenge {
+ (disposition, credential) = sessionDidReceiveChallenge(session, challenge)
+ } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
+ let host = challenge.protectionSpace.host
+
+ if let
+ serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host),
+ serverTrust = challenge.protectionSpace.serverTrust
+ {
+ if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
+ disposition = .UseCredential
+ credential = NSURLCredential(forTrust: serverTrust)
+ } else {
+ disposition = .CancelAuthenticationChallenge
+ }
+ }
+ }
+
+ completionHandler(disposition, credential)
+ }
+
+ /**
+ Tells the delegate that all messages enqueued for a session have been delivered.
+
+ - parameter session: The session that no longer has any outstanding requests.
+ */
+ public func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
+ sessionDidFinishEventsForBackgroundURLSession?(session)
+ }
+
+ // MARK: - NSURLSessionTaskDelegate
+
+ // MARK: Override Closures
+
+ /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:`.
+ public var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> NSURLRequest?)?
+
+ /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didReceiveChallenge:completionHandler:`.
+ public var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?
+
+ /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:session:task:needNewBodyStream:`.
+ public var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> NSInputStream!)?
+
+ /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`.
+ public var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didCompleteWithError:`.
+ public var taskDidComplete: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)?
+
+ // MARK: Delegate Methods
+
+ /**
+ Tells the delegate that the remote server requested an HTTP redirect.
+
+ - parameter session: The session containing the task whose request resulted in a redirect.
+ - parameter task: The task whose request resulted in a redirect.
+ - parameter response: An object containing the server’s response to the original request.
+ - parameter request: A URL request object filled out with the new location.
+ - parameter completionHandler: A closure that your handler should call with either the value of the request
+ parameter, a modified URL request object, or NULL to refuse the redirect and
+ return the body of the redirect response.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ willPerformHTTPRedirection response: NSHTTPURLResponse,
+ newRequest request: NSURLRequest,
+ completionHandler: ((NSURLRequest?) -> Void))
+ {
+ var redirectRequest: NSURLRequest? = request
+
+ if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection {
+ redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request)
+ }
+
+ completionHandler(redirectRequest)
+ }
+
+ /**
+ Requests credentials from the delegate in response to an authentication request from the remote server.
+
+ - parameter session: The session containing the task whose request requires authentication.
+ - parameter task: The task whose request requires authentication.
+ - parameter challenge: An object that contains the request for authentication.
+ - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ didReceiveChallenge challenge: NSURLAuthenticationChallenge,
+ completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
+ {
+ if let taskDidReceiveChallenge = taskDidReceiveChallenge {
+ completionHandler(taskDidReceiveChallenge(session, task, challenge))
+ } else if let delegate = self[task] {
+ delegate.URLSession(
+ session,
+ task: task,
+ didReceiveChallenge: challenge,
+ completionHandler: completionHandler
+ )
+ } else {
+ URLSession(session, didReceiveChallenge: challenge, completionHandler: completionHandler)
+ }
+ }
+
+ /**
+ Tells the delegate when a task requires a new request body stream to send to the remote server.
+
+ - parameter session: The session containing the task that needs a new body stream.
+ - parameter task: The task that needs a new body stream.
+ - parameter completionHandler: A completion handler that your delegate method should call with the new body stream.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ needNewBodyStream completionHandler: ((NSInputStream?) -> Void))
+ {
+ if let taskNeedNewBodyStream = taskNeedNewBodyStream {
+ completionHandler(taskNeedNewBodyStream(session, task))
+ } else if let delegate = self[task] {
+ delegate.URLSession(session, task: task, needNewBodyStream: completionHandler)
+ }
+ }
+
+ /**
+ Periodically informs the delegate of the progress of sending body content to the server.
+
+ - parameter session: The session containing the data task.
+ - parameter task: The data task.
+ - parameter bytesSent: The number of bytes sent since the last time this delegate method was called.
+ - parameter totalBytesSent: The total number of bytes sent so far.
+ - parameter totalBytesExpectedToSend: The expected length of the body data.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ didSendBodyData bytesSent: Int64,
+ totalBytesSent: Int64,
+ totalBytesExpectedToSend: Int64)
+ {
+ if let taskDidSendBodyData = taskDidSendBodyData {
+ taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
+ } else if let delegate = self[task] as? Request.UploadTaskDelegate {
+ delegate.URLSession(
+ session,
+ task: task,
+ didSendBodyData: bytesSent,
+ totalBytesSent: totalBytesSent,
+ totalBytesExpectedToSend: totalBytesExpectedToSend
+ )
+ }
+ }
+
+ /**
+ Tells the delegate that the task finished transferring data.
+
+ - parameter session: The session containing the task whose request finished transferring data.
+ - parameter task: The task whose request finished transferring data.
+ - parameter error: If an error occurred, an error object indicating how the transfer failed, otherwise nil.
+ */
+ public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
+ if let taskDidComplete = taskDidComplete {
+ taskDidComplete(session, task, error)
+ } else if let delegate = self[task] {
+ delegate.URLSession(session, task: task, didCompleteWithError: error)
+ }
+
+ self[task] = nil
+ }
+
+ // MARK: - NSURLSessionDataDelegate
+
+ // MARK: Override Closures
+
+ /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveResponse:completionHandler:`.
+ public var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> NSURLSessionResponseDisposition)?
+
+ /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didBecomeDownloadTask:`.
+ public var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveData:`.
+ public var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:willCacheResponse:completionHandler:`.
+ public var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> NSCachedURLResponse!)?
+
+ // MARK: Delegate Methods
+
+ /**
+ Tells the delegate that the data task received the initial reply (headers) from the server.
+
+ - parameter session: The session containing the data task that received an initial reply.
+ - parameter dataTask: The data task that received an initial reply.
+ - parameter response: A URL response object populated with headers.
+ - parameter completionHandler: A completion handler that your code calls to continue the transfer, passing a
+ constant to indicate whether the transfer should continue as a data task or
+ should become a download task.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ didReceiveResponse response: NSURLResponse,
+ completionHandler: ((NSURLSessionResponseDisposition) -> Void))
+ {
+ var disposition: NSURLSessionResponseDisposition = .Allow
+
+ if let dataTaskDidReceiveResponse = dataTaskDidReceiveResponse {
+ disposition = dataTaskDidReceiveResponse(session, dataTask, response)
+ }
+
+ completionHandler(disposition)
+ }
+
+ /**
+ Tells the delegate that the data task was changed to a download task.
+
+ - parameter session: The session containing the task that was replaced by a download task.
+ - parameter dataTask: The data task that was replaced by a download task.
+ - parameter downloadTask: The new download task that replaced the data task.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask)
+ {
+ if let dataTaskDidBecomeDownloadTask = dataTaskDidBecomeDownloadTask {
+ dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask)
+ } else {
+ let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
+ self[downloadTask] = downloadDelegate
+ }
+ }
+
+ /**
+ Tells the delegate that the data task has received some of the expected data.
+
+ - parameter session: The session containing the data task that provided data.
+ - parameter dataTask: The data task that provided data.
+ - parameter data: A data object containing the transferred data.
+ */
+ public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
+ if let dataTaskDidReceiveData = dataTaskDidReceiveData {
+ dataTaskDidReceiveData(session, dataTask, data)
+ } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
+ delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
+ }
+ }
+
+ /**
+ Asks the delegate whether the data (or upload) task should store the response in the cache.
+
+ - parameter session: The session containing the data (or upload) task.
+ - parameter dataTask: The data (or upload) task.
+ - parameter proposedResponse: The default caching behavior. This behavior is determined based on the current
+ caching policy and the values of certain received headers, such as the Pragma
+ and Cache-Control headers.
+ - parameter completionHandler: A block that your handler must call, providing either the original proposed
+ response, a modified version of that response, or NULL to prevent caching the
+ response. If your delegate implements this method, it must call this completion
+ handler; otherwise, your app leaks memory.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ willCacheResponse proposedResponse: NSCachedURLResponse,
+ completionHandler: ((NSCachedURLResponse?) -> Void))
+ {
+ if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
+ completionHandler(dataTaskWillCacheResponse(session, dataTask, proposedResponse))
+ } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
+ delegate.URLSession(
+ session,
+ dataTask: dataTask,
+ willCacheResponse: proposedResponse,
+ completionHandler: completionHandler
+ )
+ } else {
+ completionHandler(proposedResponse)
+ }
+ }
+
+ // MARK: - NSURLSessionDownloadDelegate
+
+ // MARK: Override Closures
+
+ /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didFinishDownloadingToURL:`.
+ public var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:`.
+ public var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)?
+
+ /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`.
+ public var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)?
+
+ // MARK: Delegate Methods
+
+ /**
+ Tells the delegate that a download task has finished downloading.
+
+ - parameter session: The session containing the download task that finished.
+ - parameter downloadTask: The download task that finished.
+ - parameter location: A file URL for the temporary file. Because the file is temporary, you must either
+ open the file for reading or move it to a permanent location in your app’s sandbox
+ container directory before returning from this delegate method.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didFinishDownloadingToURL location: NSURL)
+ {
+ if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
+ downloadTaskDidFinishDownloadingToURL(session, downloadTask, location)
+ } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+ delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
+ }
+ }
+
+ /**
+ Periodically informs the delegate about the download’s progress.
+
+ - parameter session: The session containing the download task.
+ - parameter downloadTask: The download task.
+ - parameter bytesWritten: The number of bytes transferred since the last time this delegate
+ method was called.
+ - parameter totalBytesWritten: The total number of bytes transferred so far.
+ - parameter totalBytesExpectedToWrite: The expected length of the file, as provided by the Content-Length
+ header. If this header was not provided, the value is
+ `NSURLSessionTransferSizeUnknown`.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didWriteData bytesWritten: Int64,
+ totalBytesWritten: Int64,
+ totalBytesExpectedToWrite: Int64)
+ {
+ if let downloadTaskDidWriteData = downloadTaskDidWriteData {
+ downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
+ } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+ delegate.URLSession(
+ session,
+ downloadTask: downloadTask,
+ didWriteData: bytesWritten,
+ totalBytesWritten: totalBytesWritten,
+ totalBytesExpectedToWrite: totalBytesExpectedToWrite
+ )
+ }
+ }
+
+ /**
+ Tells the delegate that the download task has resumed downloading.
+
+ - parameter session: The session containing the download task that finished.
+ - parameter downloadTask: The download task that resumed. See explanation in the discussion.
+ - parameter fileOffset: If the file's cache policy or last modified date prevents reuse of the
+ existing content, then this value is zero. Otherwise, this value is an
+ integer representing the number of bytes on disk that do not need to be
+ retrieved again.
+ - parameter expectedTotalBytes: The expected length of the file, as provided by the Content-Length header.
+ If this header was not provided, the value is NSURLSessionTransferSizeUnknown.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ downloadTask: NSURLSessionDownloadTask,
+ didResumeAtOffset fileOffset: Int64,
+ expectedTotalBytes: Int64)
+ {
+ if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
+ downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
+ } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+ delegate.URLSession(
+ session,
+ downloadTask: downloadTask,
+ didResumeAtOffset: fileOffset,
+ expectedTotalBytes: expectedTotalBytes
+ )
+ }
+ }
+
+ // MARK: - NSURLSessionStreamDelegate
+
+ var _streamTaskReadClosed: Any?
+ var _streamTaskWriteClosed: Any?
+ var _streamTaskBetterRouteDiscovered: Any?
+ var _streamTaskDidBecomeInputStream: Any?
+
+ // MARK: - NSObject
+
+ public override func respondsToSelector(selector: Selector) -> Bool {
+ switch selector {
+ case "URLSession:didBecomeInvalidWithError:":
+ return sessionDidBecomeInvalidWithError != nil
+ case "URLSession:didReceiveChallenge:completionHandler:":
+ return sessionDidReceiveChallenge != nil
+ case "URLSessionDidFinishEventsForBackgroundURLSession:":
+ return sessionDidFinishEventsForBackgroundURLSession != nil
+ case "URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:":
+ return taskWillPerformHTTPRedirection != nil
+ case "URLSession:dataTask:didReceiveResponse:completionHandler:":
+ return dataTaskDidReceiveResponse != nil
+ default:
+ return self.dynamicType.instancesRespondToSelector(selector)
+ }
+ }
+ }
+}
diff --git a/Pods/Alamofire/Source/MultipartFormData.swift b/Pods/Alamofire/Source/MultipartFormData.swift
new file mode 100644
index 0000000..24d952c
--- /dev/null
+++ b/Pods/Alamofire/Source/MultipartFormData.swift
@@ -0,0 +1,669 @@
+// MultipartFormData.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+#if os(iOS) || os(watchOS)
+import MobileCoreServices
+#elseif os(OSX)
+import CoreServices
+#endif
+
+/**
+ Constructs `multipart/form-data` for uploads within an HTTP or HTTPS body. There are currently two ways to encode
+ multipart form data. The first way is to encode the data directly in memory. This is very efficient, but can lead
+ to memory issues if the dataset is too large. The second way is designed for larger datasets and will write all the
+ data to a single file on disk with all the proper boundary segmentation. The second approach MUST be used for
+ larger datasets such as video content, otherwise your app may run out of memory when trying to encode the dataset.
+
+ For more information on `multipart/form-data` in general, please refer to the RFC-2388 and RFC-2045 specs as well
+ and the w3 form documentation.
+
+ - https://www.ietf.org/rfc/rfc2388.txt
+ - https://www.ietf.org/rfc/rfc2045.txt
+ - https://www.w3.org/TR/html401/interact/forms.html#h-17.13
+*/
+public class MultipartFormData {
+
+ // MARK: - Helper Types
+
+ struct EncodingCharacters {
+ static let CRLF = "\r\n"
+ }
+
+ struct BoundaryGenerator {
+ enum BoundaryType {
+ case Initial, Encapsulated, Final
+ }
+
+ static func randomBoundary() -> String {
+ return String(format: "alamofire.boundary.%08x%08x", arc4random(), arc4random())
+ }
+
+ static func boundaryData(boundaryType boundaryType: BoundaryType, boundary: String) -> NSData {
+ let boundaryText: String
+
+ switch boundaryType {
+ case .Initial:
+ boundaryText = "--\(boundary)\(EncodingCharacters.CRLF)"
+ case .Encapsulated:
+ boundaryText = "\(EncodingCharacters.CRLF)--\(boundary)\(EncodingCharacters.CRLF)"
+ case .Final:
+ boundaryText = "\(EncodingCharacters.CRLF)--\(boundary)--\(EncodingCharacters.CRLF)"
+ }
+
+ return boundaryText.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
+ }
+ }
+
+ class BodyPart {
+ let headers: [String: String]
+ let bodyStream: NSInputStream
+ let bodyContentLength: UInt64
+ var hasInitialBoundary = false
+ var hasFinalBoundary = false
+
+ init(headers: [String: String], bodyStream: NSInputStream, bodyContentLength: UInt64) {
+ self.headers = headers
+ self.bodyStream = bodyStream
+ self.bodyContentLength = bodyContentLength
+ }
+ }
+
+ // MARK: - Properties
+
+ /// The `Content-Type` header value containing the boundary used to generate the `multipart/form-data`.
+ public var contentType: String { return "multipart/form-data; boundary=\(boundary)" }
+
+ /// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries.
+ public var contentLength: UInt64 { return bodyParts.reduce(0) { $0 + $1.bodyContentLength } }
+
+ /// The boundary used to separate the body parts in the encoded form data.
+ public let boundary: String
+
+ private var bodyParts: [BodyPart]
+ private var bodyPartError: NSError?
+ private let streamBufferSize: Int
+
+ // MARK: - Lifecycle
+
+ /**
+ Creates a multipart form data object.
+
+ - returns: The multipart form data object.
+ */
+ public init() {
+ self.boundary = BoundaryGenerator.randomBoundary()
+ self.bodyParts = []
+
+ /**
+ * The optimal read/write buffer size in bytes for input and output streams is 1024 (1KB). For more
+ * information, please refer to the following article:
+ * - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html
+ */
+
+ self.streamBufferSize = 1024
+ }
+
+ // MARK: - Body Parts
+
+ /**
+ Creates a body part from the data and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
+ - Encoded data
+ - Multipart form boundary
+
+ - parameter data: The data to encode into the multipart form data.
+ - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
+ */
+ public func appendBodyPart(data data: NSData, name: String) {
+ let headers = contentHeaders(name: name)
+ let stream = NSInputStream(data: data)
+ let length = UInt64(data.length)
+
+ appendBodyPart(stream: stream, length: length, headers: headers)
+ }
+
+ /**
+ Creates a body part from the data and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
+ - `Content-Type: #{generated mimeType}` (HTTP Header)
+ - Encoded data
+ - Multipart form boundary
+
+ - parameter data: The data to encode into the multipart form data.
+ - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
+ - parameter mimeType: The MIME type to associate with the data content type in the `Content-Type` HTTP header.
+ */
+ public func appendBodyPart(data data: NSData, name: String, mimeType: String) {
+ let headers = contentHeaders(name: name, mimeType: mimeType)
+ let stream = NSInputStream(data: data)
+ let length = UInt64(data.length)
+
+ appendBodyPart(stream: stream, length: length, headers: headers)
+ }
+
+ /**
+ Creates a body part from the data and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
+ - `Content-Type: #{mimeType}` (HTTP Header)
+ - Encoded file data
+ - Multipart form boundary
+
+ - parameter data: The data to encode into the multipart form data.
+ - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
+ - parameter fileName: The filename to associate with the data in the `Content-Disposition` HTTP header.
+ - parameter mimeType: The MIME type to associate with the data in the `Content-Type` HTTP header.
+ */
+ public func appendBodyPart(data data: NSData, name: String, fileName: String, mimeType: String) {
+ let headers = contentHeaders(name: name, fileName: fileName, mimeType: mimeType)
+ let stream = NSInputStream(data: data)
+ let length = UInt64(data.length)
+
+ appendBodyPart(stream: stream, length: length, headers: headers)
+ }
+
+ /**
+ Creates a body part from the file and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - `Content-Disposition: form-data; name=#{name}; filename=#{generated filename}` (HTTP Header)
+ - `Content-Type: #{generated mimeType}` (HTTP Header)
+ - Encoded file data
+ - Multipart form boundary
+
+ The filename in the `Content-Disposition` HTTP header is generated from the last path component of the
+ `fileURL`. The `Content-Type` HTTP header MIME type is generated by mapping the `fileURL` extension to the
+ system associated MIME type.
+
+ - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
+ - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
+ */
+ public func appendBodyPart(fileURL fileURL: NSURL, name: String) {
+ if let
+ fileName = fileURL.lastPathComponent,
+ pathExtension = fileURL.pathExtension
+ {
+ let mimeType = mimeTypeForPathExtension(pathExtension)
+ appendBodyPart(fileURL: fileURL, name: name, fileName: fileName, mimeType: mimeType)
+ } else {
+ let failureReason = "Failed to extract the fileName of the provided URL: \(fileURL)"
+ setBodyPartError(Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason))
+ }
+ }
+
+ /**
+ Creates a body part from the file and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - Content-Disposition: form-data; name=#{name}; filename=#{filename} (HTTP Header)
+ - Content-Type: #{mimeType} (HTTP Header)
+ - Encoded file data
+ - Multipart form boundary
+
+ - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
+ - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
+ - parameter fileName: The filename to associate with the file content in the `Content-Disposition` HTTP header.
+ - parameter mimeType: The MIME type to associate with the file content in the `Content-Type` HTTP header.
+ */
+ public func appendBodyPart(fileURL fileURL: NSURL, name: String, fileName: String, mimeType: String) {
+ let headers = contentHeaders(name: name, fileName: fileName, mimeType: mimeType)
+
+ //============================================================
+ // Check 1 - is file URL?
+ //============================================================
+
+ guard fileURL.fileURL else {
+ let failureReason = "The file URL does not point to a file URL: \(fileURL)"
+ let error = Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason)
+ setBodyPartError(error)
+ return
+ }
+
+ //============================================================
+ // Check 2 - is file URL reachable?
+ //============================================================
+
+ var isReachable = true
+
+ if #available(OSX 10.10, *) {
+ isReachable = fileURL.checkPromisedItemIsReachableAndReturnError(nil)
+ }
+
+ guard isReachable else {
+ let error = Error.errorWithCode(NSURLErrorBadURL, failureReason: "The file URL is not reachable: \(fileURL)")
+ setBodyPartError(error)
+ return
+ }
+
+ //============================================================
+ // Check 3 - is file URL a directory?
+ //============================================================
+
+ var isDirectory: ObjCBool = false
+
+ guard let
+ path = fileURL.path
+ where NSFileManager.defaultManager().fileExistsAtPath(path, isDirectory: &isDirectory) && !isDirectory else
+ {
+ let failureReason = "The file URL is a directory, not a file: \(fileURL)"
+ let error = Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason)
+ setBodyPartError(error)
+ return
+ }
+
+ //============================================================
+ // Check 4 - can the file size be extracted?
+ //============================================================
+
+ var bodyContentLength: UInt64?
+
+ do {
+ if let
+ path = fileURL.path,
+ fileSize = try NSFileManager.defaultManager().attributesOfItemAtPath(path)[NSFileSize] as? NSNumber
+ {
+ bodyContentLength = fileSize.unsignedLongLongValue
+ }
+ } catch {
+ // No-op
+ }
+
+ guard let length = bodyContentLength else {
+ let failureReason = "Could not fetch attributes from the file URL: \(fileURL)"
+ let error = Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason)
+ setBodyPartError(error)
+ return
+ }
+
+ //============================================================
+ // Check 5 - can a stream be created from file URL?
+ //============================================================
+
+ guard let stream = NSInputStream(URL: fileURL) else {
+ let failureReason = "Failed to create an input stream from the file URL: \(fileURL)"
+ let error = Error.errorWithCode(NSURLErrorCannotOpenFile, failureReason: failureReason)
+ setBodyPartError(error)
+ return
+ }
+
+ appendBodyPart(stream: stream, length: length, headers: headers)
+ }
+
+ /**
+ Creates a body part from the stream and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
+ - `Content-Type: #{mimeType}` (HTTP Header)
+ - Encoded stream data
+ - Multipart form boundary
+
+ - parameter stream: The input stream to encode in the multipart form data.
+ - parameter length: The content length of the stream.
+ - parameter name: The name to associate with the stream content in the `Content-Disposition` HTTP header.
+ - parameter fileName: The filename to associate with the stream content in the `Content-Disposition` HTTP header.
+ - parameter mimeType: The MIME type to associate with the stream content in the `Content-Type` HTTP header.
+ */
+ public func appendBodyPart(
+ stream stream: NSInputStream,
+ length: UInt64,
+ name: String,
+ fileName: String,
+ mimeType: String)
+ {
+ let headers = contentHeaders(name: name, fileName: fileName, mimeType: mimeType)
+ appendBodyPart(stream: stream, length: length, headers: headers)
+ }
+
+ /**
+ Creates a body part with the headers, stream and length and appends it to the multipart form data object.
+
+ The body part data will be encoded using the following format:
+
+ - HTTP headers
+ - Encoded stream data
+ - Multipart form boundary
+
+ - parameter stream: The input stream to encode in the multipart form data.
+ - parameter length: The content length of the stream.
+ - parameter headers: The HTTP headers for the body part.
+ */
+ public func appendBodyPart(stream stream: NSInputStream, length: UInt64, headers: [String: String]) {
+ let bodyPart = BodyPart(headers: headers, bodyStream: stream, bodyContentLength: length)
+ bodyParts.append(bodyPart)
+ }
+
+ // MARK: - Data Encoding
+
+ /**
+ Encodes all the appended body parts into a single `NSData` object.
+
+ It is important to note that this method will load all the appended body parts into memory all at the same
+ time. This method should only be used when the encoded data will have a small memory footprint. For large data
+ cases, please use the `writeEncodedDataToDisk(fileURL:completionHandler:)` method.
+
+ - throws: An `NSError` if encoding encounters an error.
+
+ - returns: The encoded `NSData` if encoding is successful.
+ */
+ public func encode() throws -> NSData {
+ if let bodyPartError = bodyPartError {
+ throw bodyPartError
+ }
+
+ let encoded = NSMutableData()
+
+ bodyParts.first?.hasInitialBoundary = true
+ bodyParts.last?.hasFinalBoundary = true
+
+ for bodyPart in bodyParts {
+ let encodedData = try encodeBodyPart(bodyPart)
+ encoded.appendData(encodedData)
+ }
+
+ return encoded
+ }
+
+ /**
+ Writes the appended body parts into the given file URL.
+
+ This process is facilitated by reading and writing with input and output streams, respectively. Thus,
+ this approach is very memory efficient and should be used for large body part data.
+
+ - parameter fileURL: The file URL to write the multipart form data into.
+
+ - throws: An `NSError` if encoding encounters an error.
+ */
+ public func writeEncodedDataToDisk(fileURL: NSURL) throws {
+ if let bodyPartError = bodyPartError {
+ throw bodyPartError
+ }
+
+ if let path = fileURL.path where NSFileManager.defaultManager().fileExistsAtPath(path) {
+ let failureReason = "A file already exists at the given file URL: \(fileURL)"
+ throw Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason)
+ } else if !fileURL.fileURL {
+ let failureReason = "The URL does not point to a valid file: \(fileURL)"
+ throw Error.errorWithCode(NSURLErrorBadURL, failureReason: failureReason)
+ }
+
+ let outputStream: NSOutputStream
+
+ if let possibleOutputStream = NSOutputStream(URL: fileURL, append: false) {
+ outputStream = possibleOutputStream
+ } else {
+ let failureReason = "Failed to create an output stream with the given URL: \(fileURL)"
+ throw Error.errorWithCode(NSURLErrorCannotOpenFile, failureReason: failureReason)
+ }
+
+ outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+ outputStream.open()
+
+ self.bodyParts.first?.hasInitialBoundary = true
+ self.bodyParts.last?.hasFinalBoundary = true
+
+ for bodyPart in self.bodyParts {
+ try writeBodyPart(bodyPart, toOutputStream: outputStream)
+ }
+
+ outputStream.close()
+ outputStream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+ }
+
+ // MARK: - Private - Body Part Encoding
+
+ private func encodeBodyPart(bodyPart: BodyPart) throws -> NSData {
+ let encoded = NSMutableData()
+
+ let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
+ encoded.appendData(initialData)
+
+ let headerData = encodeHeaderDataForBodyPart(bodyPart)
+ encoded.appendData(headerData)
+
+ let bodyStreamData = try encodeBodyStreamDataForBodyPart(bodyPart)
+ encoded.appendData(bodyStreamData)
+
+ if bodyPart.hasFinalBoundary {
+ encoded.appendData(finalBoundaryData())
+ }
+
+ return encoded
+ }
+
+ private func encodeHeaderDataForBodyPart(bodyPart: BodyPart) -> NSData {
+ var headerText = ""
+
+ for (key, value) in bodyPart.headers {
+ headerText += "\(key): \(value)\(EncodingCharacters.CRLF)"
+ }
+ headerText += EncodingCharacters.CRLF
+
+ return headerText.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
+ }
+
+ private func encodeBodyStreamDataForBodyPart(bodyPart: BodyPart) throws -> NSData {
+ let inputStream = bodyPart.bodyStream
+ inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+ inputStream.open()
+
+ var error: NSError?
+ let encoded = NSMutableData()
+
+ while inputStream.hasBytesAvailable {
+ var buffer = [UInt8](count: streamBufferSize, repeatedValue: 0)
+ let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
+
+ if inputStream.streamError != nil {
+ error = inputStream.streamError
+ break
+ }
+
+ if bytesRead > 0 {
+ encoded.appendBytes(buffer, length: bytesRead)
+ } else if bytesRead < 0 {
+ let failureReason = "Failed to read from input stream: \(inputStream)"
+ error = Error.errorWithCode(.InputStreamReadFailed, failureReason: failureReason)
+ break
+ } else {
+ break
+ }
+ }
+
+ inputStream.close()
+ inputStream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+
+ if let error = error {
+ throw error
+ }
+
+ return encoded
+ }
+
+ // MARK: - Private - Writing Body Part to Output Stream
+
+ private func writeBodyPart(bodyPart: BodyPart, toOutputStream outputStream: NSOutputStream) throws {
+ try writeInitialBoundaryDataForBodyPart(bodyPart, toOutputStream: outputStream)
+ try writeHeaderDataForBodyPart(bodyPart, toOutputStream: outputStream)
+ try writeBodyStreamForBodyPart(bodyPart, toOutputStream: outputStream)
+ try writeFinalBoundaryDataForBodyPart(bodyPart, toOutputStream: outputStream)
+ }
+
+ private func writeInitialBoundaryDataForBodyPart(
+ bodyPart: BodyPart,
+ toOutputStream outputStream: NSOutputStream)
+ throws
+ {
+ let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
+ return try writeData(initialData, toOutputStream: outputStream)
+ }
+
+ private func writeHeaderDataForBodyPart(bodyPart: BodyPart, toOutputStream outputStream: NSOutputStream) throws {
+ let headerData = encodeHeaderDataForBodyPart(bodyPart)
+ return try writeData(headerData, toOutputStream: outputStream)
+ }
+
+ private func writeBodyStreamForBodyPart(bodyPart: BodyPart, toOutputStream outputStream: NSOutputStream) throws {
+ let inputStream = bodyPart.bodyStream
+ inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
+ inputStream.open()
+
+ while inputStream.hasBytesAvailable {
+ var buffer = [UInt8](count: streamBufferSize, repeatedValue: 0)
+ let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
+
+ if let streamError = inputStream.streamError {
+ throw streamError
+ }
+
+ if bytesRead > 0 {
+ if buffer.count != bytesRead {
+ buffer = Array(buffer[0.. 0 {
+ if outputStream.hasSpaceAvailable {
+ let bytesWritten = outputStream.write(buffer, maxLength: bytesToWrite)
+
+ if let streamError = outputStream.streamError {
+ throw streamError
+ }
+
+ if bytesWritten < 0 {
+ let failureReason = "Failed to write to output stream: \(outputStream)"
+ throw Error.errorWithCode(.OutputStreamWriteFailed, failureReason: failureReason)
+ }
+
+ bytesToWrite -= bytesWritten
+
+ if bytesToWrite > 0 {
+ buffer = Array(buffer[bytesWritten.. String {
+ if let
+ id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil)?.takeRetainedValue(),
+ contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue()
+ {
+ return contentType as String
+ }
+
+ return "application/octet-stream"
+ }
+
+ // MARK: - Private - Content Headers
+
+ private func contentHeaders(name name: String) -> [String: String] {
+ return ["Content-Disposition": "form-data; name=\"\(name)\""]
+ }
+
+ private func contentHeaders(name name: String, mimeType: String) -> [String: String] {
+ return [
+ "Content-Disposition": "form-data; name=\"\(name)\"",
+ "Content-Type": "\(mimeType)"
+ ]
+ }
+
+ private func contentHeaders(name name: String, fileName: String, mimeType: String) -> [String: String] {
+ return [
+ "Content-Disposition": "form-data; name=\"\(name)\"; filename=\"\(fileName)\"",
+ "Content-Type": "\(mimeType)"
+ ]
+ }
+
+ // MARK: - Private - Boundary Encoding
+
+ private func initialBoundaryData() -> NSData {
+ return BoundaryGenerator.boundaryData(boundaryType: .Initial, boundary: boundary)
+ }
+
+ private func encapsulatedBoundaryData() -> NSData {
+ return BoundaryGenerator.boundaryData(boundaryType: .Encapsulated, boundary: boundary)
+ }
+
+ private func finalBoundaryData() -> NSData {
+ return BoundaryGenerator.boundaryData(boundaryType: .Final, boundary: boundary)
+ }
+
+ // MARK: - Private - Errors
+
+ private func setBodyPartError(error: NSError) {
+ if bodyPartError == nil {
+ bodyPartError = error
+ }
+ }
+}
diff --git a/Pods/Alamofire/Source/ParameterEncoding.swift b/Pods/Alamofire/Source/ParameterEncoding.swift
new file mode 100644
index 0000000..94f7d42
--- /dev/null
+++ b/Pods/Alamofire/Source/ParameterEncoding.swift
@@ -0,0 +1,245 @@
+// ParameterEncoding.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/**
+ HTTP method definitions.
+
+ See https://tools.ietf.org/html/rfc7231#section-4.3
+*/
+public enum Method: String {
+ case OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT
+}
+
+// MARK: ParameterEncoding
+
+/**
+ Used to specify the way in which a set of parameters are applied to a URL request.
+
+ - `URL`: Creates a query string to be set as or appended to any existing URL query for `GET`, `HEAD`,
+ and `DELETE` requests, or set as the body for requests with any other HTTP method. The
+ `Content-Type` HTTP header field of an encoded request with HTTP body is set to
+ `application/x-www-form-urlencoded; charset=utf-8`. Since there is no published specification
+ for how to encode collection types, the convention of appending `[]` to the key for array
+ values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for nested
+ dictionary values (`foo[bar]=baz`).
+
+ - `URLEncodedInURL`: Creates query string to be set as or appended to any existing URL query. Uses the same
+ implementation as the `.URL` case, but always applies the encoded result to the URL.
+
+ - `JSON`: Uses `NSJSONSerialization` to create a JSON representation of the parameters object, which is
+ set as the body of the request. The `Content-Type` HTTP header field of an encoded request is
+ set to `application/json`.
+
+ - `PropertyList`: Uses `NSPropertyListSerialization` to create a plist representation of the parameters object,
+ according to the associated format and write options values, which is set as the body of the
+ request. The `Content-Type` HTTP header field of an encoded request is set to
+ `application/x-plist`.
+
+ - `Custom`: Uses the associated closure value to construct a new request given an existing request and
+ parameters.
+*/
+public enum ParameterEncoding {
+ case URL
+ case URLEncodedInURL
+ case JSON
+ case PropertyList(NSPropertyListFormat, NSPropertyListWriteOptions)
+ case Custom((URLRequestConvertible, [String: AnyObject]?) -> (NSMutableURLRequest, NSError?))
+
+ /**
+ Creates a URL request by encoding parameters and applying them onto an existing request.
+
+ - parameter URLRequest: The request to have parameters applied
+ - parameter parameters: The parameters to apply
+
+ - returns: A tuple containing the constructed request and the error that occurred during parameter encoding,
+ if any.
+ */
+ public func encode(
+ URLRequest: URLRequestConvertible,
+ parameters: [String: AnyObject]?)
+ -> (NSMutableURLRequest, NSError?)
+ {
+ var mutableURLRequest = URLRequest.URLRequest
+
+ guard let parameters = parameters else {
+ return (mutableURLRequest, nil)
+ }
+
+ var encodingError: NSError? = nil
+
+ switch self {
+ case .URL, .URLEncodedInURL:
+ func query(parameters: [String: AnyObject]) -> String {
+ var components: [(String, String)] = []
+ for key in Array(parameters.keys).sort(<) {
+ let value = parameters[key]!
+ components += queryComponents(key, value)
+ }
+
+ return (components.map { "\($0)=\($1)" } as [String]).joinWithSeparator("&")
+ }
+
+ func encodesParametersInURL(method: Method) -> Bool {
+ switch self {
+ case .URLEncodedInURL:
+ return true
+ default:
+ break
+ }
+
+ switch method {
+ case .GET, .HEAD, .DELETE:
+ return true
+ default:
+ return false
+ }
+ }
+
+ if let method = Method(rawValue: mutableURLRequest.HTTPMethod) where encodesParametersInURL(method) {
+ if let URLComponents = NSURLComponents(URL: mutableURLRequest.URL!, resolvingAgainstBaseURL: false) {
+ let percentEncodedQuery = (URLComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
+ URLComponents.percentEncodedQuery = percentEncodedQuery
+ mutableURLRequest.URL = URLComponents.URL
+ }
+ } else {
+ if mutableURLRequest.valueForHTTPHeaderField("Content-Type") == nil {
+ mutableURLRequest.setValue(
+ "application/x-www-form-urlencoded; charset=utf-8",
+ forHTTPHeaderField: "Content-Type"
+ )
+ }
+
+ mutableURLRequest.HTTPBody = query(parameters).dataUsingEncoding(
+ NSUTF8StringEncoding,
+ allowLossyConversion: false
+ )
+ }
+ case .JSON:
+ do {
+ let options = NSJSONWritingOptions()
+ let data = try NSJSONSerialization.dataWithJSONObject(parameters, options: options)
+
+ mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
+ mutableURLRequest.HTTPBody = data
+ } catch {
+ encodingError = error as NSError
+ }
+ case .PropertyList(let format, let options):
+ do {
+ let data = try NSPropertyListSerialization.dataWithPropertyList(
+ parameters,
+ format: format,
+ options: options
+ )
+ mutableURLRequest.setValue("application/x-plist", forHTTPHeaderField: "Content-Type")
+ mutableURLRequest.HTTPBody = data
+ } catch {
+ encodingError = error as NSError
+ }
+ case .Custom(let closure):
+ (mutableURLRequest, encodingError) = closure(mutableURLRequest, parameters)
+ }
+
+ return (mutableURLRequest, encodingError)
+ }
+
+ /**
+ Creates percent-escaped, URL encoded query string components from the given key-value pair using recursion.
+
+ - parameter key: The key of the query component.
+ - parameter value: The value of the query component.
+
+ - returns: The percent-escaped, URL encoded query string components.
+ */
+ public func queryComponents(key: String, _ value: AnyObject) -> [(String, String)] {
+ var components: [(String, String)] = []
+ if let dictionary = value as? [String: AnyObject] {
+ for (nestedKey, value) in dictionary {
+ components += queryComponents("\(key)[\(nestedKey)]", value)
+ }
+ } else if let array = value as? [AnyObject] {
+ for value in array {
+ components += queryComponents("\(key)[]", value)
+ }
+ } else {
+ components.append((escape(key), escape("\(value)")))
+ }
+
+ return components
+ }
+
+ /**
+ Returns a percent-escaped string following RFC 3986 for a query string key or value.
+
+ RFC 3986 states that the following characters are "reserved" characters.
+
+ - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
+ - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
+
+ In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
+ query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
+ should be percent-escaped in the query string.
+
+ - parameter string: The string to be percent-escaped.
+
+ - returns: The percent-escaped string.
+ */
+ public func escape(string: String) -> String {
+ let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
+ let subDelimitersToEncode = "!$&'()*+,;="
+
+ let allowedCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet
+ allowedCharacterSet.removeCharactersInString(generalDelimitersToEncode + subDelimitersToEncode)
+
+ //==========================================================================================================
+ //
+ // Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few
+ // hundred Chinense characters causes various malloc error crashes. To avoid this issue until iOS 8 is no
+ // longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more
+ // info, please refer to:
+ //
+ // - https://github.com/Alamofire/Alamofire/issues/206
+ //
+ //==========================================================================================================
+
+ let batchSize = 50
+ var index = string.startIndex
+
+ var escaped = ""
+
+ while index != string.endIndex {
+ let startIndex = index
+ let endIndex = index.advancedBy(batchSize, limit: string.endIndex)
+ let range = Range(start: startIndex, end: endIndex)
+
+ let substring = string.substringWithRange(range)
+
+ escaped += substring.stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet) ?? substring
+
+ index = endIndex
+ }
+
+ return escaped
+ }
+}
diff --git a/Pods/Alamofire/Source/Request.swift b/Pods/Alamofire/Source/Request.swift
new file mode 100644
index 0000000..8df4856
--- /dev/null
+++ b/Pods/Alamofire/Source/Request.swift
@@ -0,0 +1,536 @@
+// Request.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/**
+ Responsible for sending a request and receiving the response and associated data from the server, as well as
+ managing its underlying `NSURLSessionTask`.
+*/
+public class Request {
+
+ // MARK: - Properties
+
+ /// The delegate for the underlying task.
+ public let delegate: TaskDelegate
+
+ /// The underlying task.
+ public var task: NSURLSessionTask { return delegate.task }
+
+ /// The session belonging to the underlying task.
+ public let session: NSURLSession
+
+ /// The request sent or to be sent to the server.
+ public var request: NSURLRequest? { return task.originalRequest }
+
+ /// The response received from the server, if any.
+ public var response: NSHTTPURLResponse? { return task.response as? NSHTTPURLResponse }
+
+ /// The progress of the request lifecycle.
+ public var progress: NSProgress { return delegate.progress }
+
+ // MARK: - Lifecycle
+
+ init(session: NSURLSession, task: NSURLSessionTask) {
+ self.session = session
+
+ switch task {
+ case is NSURLSessionUploadTask:
+ self.delegate = UploadTaskDelegate(task: task)
+ case is NSURLSessionDataTask:
+ self.delegate = DataTaskDelegate(task: task)
+ case is NSURLSessionDownloadTask:
+ self.delegate = DownloadTaskDelegate(task: task)
+ default:
+ self.delegate = TaskDelegate(task: task)
+ }
+ }
+
+ // MARK: - Authentication
+
+ /**
+ Associates an HTTP Basic credential with the request.
+
+ - parameter user: The user.
+ - parameter password: The password.
+ - parameter persistence: The URL credential persistence. `.ForSession` by default.
+
+ - returns: The request.
+ */
+ public func authenticate(
+ user user: String,
+ password: String,
+ persistence: NSURLCredentialPersistence = .ForSession)
+ -> Self
+ {
+ let credential = NSURLCredential(user: user, password: password, persistence: persistence)
+
+ return authenticate(usingCredential: credential)
+ }
+
+ /**
+ Associates a specified credential with the request.
+
+ - parameter credential: The credential.
+
+ - returns: The request.
+ */
+ public func authenticate(usingCredential credential: NSURLCredential) -> Self {
+ delegate.credential = credential
+
+ return self
+ }
+
+ // MARK: - Progress
+
+ /**
+ Sets a closure to be called periodically during the lifecycle of the request as data is written to or read
+ from the server.
+
+ - For uploads, the progress closure returns the bytes written, total bytes written, and total bytes expected
+ to write.
+ - For downloads and data tasks, the progress closure returns the bytes read, total bytes read, and total bytes
+ expected to read.
+
+ - parameter closure: The code to be executed periodically during the lifecycle of the request.
+
+ - returns: The request.
+ */
+ public func progress(closure: ((Int64, Int64, Int64) -> Void)? = nil) -> Self {
+ if let uploadDelegate = delegate as? UploadTaskDelegate {
+ uploadDelegate.uploadProgress = closure
+ } else if let dataDelegate = delegate as? DataTaskDelegate {
+ dataDelegate.dataProgress = closure
+ } else if let downloadDelegate = delegate as? DownloadTaskDelegate {
+ downloadDelegate.downloadProgress = closure
+ }
+
+ return self
+ }
+
+ /**
+ Sets a closure to be called periodically during the lifecycle of the request as data is read from the server.
+
+ This closure returns the bytes most recently received from the server, not including data from previous calls.
+ If this closure is set, data will only be available within this closure, and will not be saved elsewhere. It is
+ also important to note that the `response` closure will be called with nil `responseData`.
+
+ - parameter closure: The code to be executed periodically during the lifecycle of the request.
+
+ - returns: The request.
+ */
+ public func stream(closure: (NSData -> Void)? = nil) -> Self {
+ if let dataDelegate = delegate as? DataTaskDelegate {
+ dataDelegate.dataStream = closure
+ }
+
+ return self
+ }
+
+ // MARK: - State
+
+ /**
+ Suspends the request.
+ */
+ public func suspend() {
+ task.suspend()
+ }
+
+ /**
+ Resumes the request.
+ */
+ public func resume() {
+ task.resume()
+ }
+
+ /**
+ Cancels the request.
+ */
+ public func cancel() {
+ if let
+ downloadDelegate = delegate as? DownloadTaskDelegate,
+ downloadTask = downloadDelegate.downloadTask
+ {
+ downloadTask.cancelByProducingResumeData { data in
+ downloadDelegate.resumeData = data
+ }
+ } else {
+ task.cancel()
+ }
+ }
+
+ // MARK: - TaskDelegate
+
+ /**
+ The task delegate is responsible for handling all delegate callbacks for the underlying task as well as
+ executing all operations attached to the serial operation queue upon task completion.
+ */
+ public class TaskDelegate: NSObject {
+
+ /// The serial operation queue used to execute all operations after the task completes.
+ public let queue: NSOperationQueue
+
+ let task: NSURLSessionTask
+ let progress: NSProgress
+
+ var data: NSData? { return nil }
+ var error: ErrorType?
+
+ var credential: NSURLCredential?
+
+ init(task: NSURLSessionTask) {
+ self.task = task
+ self.progress = NSProgress(totalUnitCount: 0)
+ self.queue = {
+ let operationQueue = NSOperationQueue()
+ operationQueue.maxConcurrentOperationCount = 1
+ operationQueue.suspended = true
+
+ if #available(OSX 10.10, *) {
+ operationQueue.qualityOfService = NSQualityOfService.Utility
+ }
+
+ return operationQueue
+ }()
+ }
+
+ deinit {
+ queue.cancelAllOperations()
+ queue.suspended = false
+ }
+
+ // MARK: - NSURLSessionTaskDelegate
+
+ // MARK: Override Closures
+
+ var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> NSURLRequest?)?
+ var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?
+ var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> NSInputStream?)?
+ var taskDidCompleteWithError: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)?
+
+ // MARK: Delegate Methods
+
+ func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ willPerformHTTPRedirection response: NSHTTPURLResponse,
+ newRequest request: NSURLRequest,
+ completionHandler: ((NSURLRequest?) -> Void))
+ {
+ var redirectRequest: NSURLRequest? = request
+
+ if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection {
+ redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request)
+ }
+
+ completionHandler(redirectRequest)
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ didReceiveChallenge challenge: NSURLAuthenticationChallenge,
+ completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
+ {
+ var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
+ var credential: NSURLCredential?
+
+ if let taskDidReceiveChallenge = taskDidReceiveChallenge {
+ (disposition, credential) = taskDidReceiveChallenge(session, task, challenge)
+ } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
+ let host = challenge.protectionSpace.host
+
+ if let
+ serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host),
+ serverTrust = challenge.protectionSpace.serverTrust
+ {
+ if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
+ disposition = .UseCredential
+ credential = NSURLCredential(forTrust: serverTrust)
+ } else {
+ disposition = .CancelAuthenticationChallenge
+ }
+ }
+ } else {
+ if challenge.previousFailureCount > 0 {
+ disposition = .CancelAuthenticationChallenge
+ } else {
+ credential = self.credential ?? session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
+
+ if credential != nil {
+ disposition = .UseCredential
+ }
+ }
+ }
+
+ completionHandler(disposition, credential)
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ needNewBodyStream completionHandler: ((NSInputStream?) -> Void))
+ {
+ var bodyStream: NSInputStream?
+
+ if let taskNeedNewBodyStream = taskNeedNewBodyStream {
+ bodyStream = taskNeedNewBodyStream(session, task)
+ }
+
+ completionHandler(bodyStream)
+ }
+
+ func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
+ if let taskDidCompleteWithError = taskDidCompleteWithError {
+ taskDidCompleteWithError(session, task, error)
+ } else {
+ if let error = error {
+ self.error = error
+
+ if let
+ downloadDelegate = self as? DownloadTaskDelegate,
+ userInfo = error.userInfo as? [String: AnyObject],
+ resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? NSData
+ {
+ downloadDelegate.resumeData = resumeData
+ }
+ }
+
+ queue.suspended = false
+ }
+ }
+ }
+
+ // MARK: - DataTaskDelegate
+
+ class DataTaskDelegate: TaskDelegate, NSURLSessionDataDelegate {
+ var dataTask: NSURLSessionDataTask? { return task as? NSURLSessionDataTask }
+
+ private var totalBytesReceived: Int64 = 0
+ private var mutableData: NSMutableData
+ override var data: NSData? {
+ if dataStream != nil {
+ return nil
+ } else {
+ return mutableData
+ }
+ }
+
+ private var expectedContentLength: Int64?
+ private var dataProgress: ((bytesReceived: Int64, totalBytesReceived: Int64, totalBytesExpectedToReceive: Int64) -> Void)?
+ private var dataStream: ((data: NSData) -> Void)?
+
+ override init(task: NSURLSessionTask) {
+ mutableData = NSMutableData()
+ super.init(task: task)
+ }
+
+ // MARK: - NSURLSessionDataDelegate
+
+ // MARK: Override Closures
+
+ var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> NSURLSessionResponseDisposition)?
+ var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)?
+ var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)?
+ var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> NSCachedURLResponse?)?
+
+ // MARK: Delegate Methods
+
+ func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ didReceiveResponse response: NSURLResponse,
+ completionHandler: (NSURLSessionResponseDisposition -> Void))
+ {
+ var disposition: NSURLSessionResponseDisposition = .Allow
+
+ expectedContentLength = response.expectedContentLength
+
+ if let dataTaskDidReceiveResponse = dataTaskDidReceiveResponse {
+ disposition = dataTaskDidReceiveResponse(session, dataTask, response)
+ }
+
+ completionHandler(disposition)
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask)
+ {
+ dataTaskDidBecomeDownloadTask?(session, dataTask, downloadTask)
+ }
+
+ func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
+ if let dataTaskDidReceiveData = dataTaskDidReceiveData {
+ dataTaskDidReceiveData(session, dataTask, data)
+ } else {
+ if let dataStream = dataStream {
+ dataStream(data: data)
+ } else {
+ mutableData.appendData(data)
+ }
+
+ totalBytesReceived += data.length
+ let totalBytesExpected = dataTask.response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
+
+ progress.totalUnitCount = totalBytesExpected
+ progress.completedUnitCount = totalBytesReceived
+
+ dataProgress?(
+ bytesReceived: Int64(data.length),
+ totalBytesReceived: totalBytesReceived,
+ totalBytesExpectedToReceive: totalBytesExpected
+ )
+ }
+ }
+
+ func URLSession(
+ session: NSURLSession,
+ dataTask: NSURLSessionDataTask,
+ willCacheResponse proposedResponse: NSCachedURLResponse,
+ completionHandler: ((NSCachedURLResponse?) -> Void))
+ {
+ var cachedResponse: NSCachedURLResponse? = proposedResponse
+
+ if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
+ cachedResponse = dataTaskWillCacheResponse(session, dataTask, proposedResponse)
+ }
+
+ completionHandler(cachedResponse)
+ }
+ }
+}
+
+// MARK: - CustomStringConvertible
+
+extension Request: CustomStringConvertible {
+
+ /**
+ The textual representation used when written to an output stream, which includes the HTTP method and URL, as
+ well as the response status code if a response has been received.
+ */
+ public var description: String {
+ var components: [String] = []
+
+ if let HTTPMethod = request?.HTTPMethod {
+ components.append(HTTPMethod)
+ }
+
+ if let URLString = request?.URL?.absoluteString {
+ components.append(URLString)
+ }
+
+ if let response = response {
+ components.append("(\(response.statusCode))")
+ }
+
+ return components.joinWithSeparator(" ")
+ }
+}
+
+// MARK: - CustomDebugStringConvertible
+
+extension Request: CustomDebugStringConvertible {
+ func cURLRepresentation() -> String {
+ var components = ["$ curl -i"]
+
+ guard let request = self.request else {
+ return "$ curl command could not be created"
+ }
+
+ let URL = request.URL
+
+ if let HTTPMethod = request.HTTPMethod where HTTPMethod != "GET" {
+ components.append("-X \(HTTPMethod)")
+ }
+
+ if let credentialStorage = self.session.configuration.URLCredentialStorage {
+ let protectionSpace = NSURLProtectionSpace(
+ host: URL!.host!,
+ port: URL!.port?.integerValue ?? 0,
+ `protocol`: URL!.scheme,
+ realm: URL!.host!,
+ authenticationMethod: NSURLAuthenticationMethodHTTPBasic
+ )
+
+ if let credentials = credentialStorage.credentialsForProtectionSpace(protectionSpace)?.values {
+ for credential in credentials {
+ components.append("-u \(credential.user!):\(credential.password!)")
+ }
+ } else {
+ if let credential = delegate.credential {
+ components.append("-u \(credential.user!):\(credential.password!)")
+ }
+ }
+ }
+
+ if session.configuration.HTTPShouldSetCookies {
+ if let
+ cookieStorage = session.configuration.HTTPCookieStorage,
+ cookies = cookieStorage.cookiesForURL(URL!) where !cookies.isEmpty
+ {
+ let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value ?? String());" }
+ components.append("-b \"\(string.substringToIndex(string.endIndex.predecessor()))\"")
+ }
+ }
+
+ if let headerFields = request.allHTTPHeaderFields {
+ for (field, value) in headerFields {
+ switch field {
+ case "Cookie":
+ continue
+ default:
+ components.append("-H \"\(field): \(value)\"")
+ }
+ }
+ }
+
+ if let additionalHeaders = session.configuration.HTTPAdditionalHeaders {
+ for (field, value) in additionalHeaders {
+ switch field {
+ case "Cookie":
+ continue
+ default:
+ components.append("-H \"\(field): \(value)\"")
+ }
+ }
+ }
+
+ if let
+ HTTPBodyData = request.HTTPBody,
+ HTTPBody = NSString(data: HTTPBodyData, encoding: NSUTF8StringEncoding)
+ {
+ let escapedBody = HTTPBody.stringByReplacingOccurrencesOfString("\"", withString: "\\\"")
+ components.append("-d \"\(escapedBody)\"")
+ }
+
+ components.append("\"\(URL!.absoluteString)\"")
+
+ return components.joinWithSeparator(" \\\n\t")
+ }
+
+ /// The textual representation used when written to an output stream, in the form of a cURL command.
+ public var debugDescription: String {
+ return cURLRepresentation()
+ }
+}
diff --git a/Pods/Alamofire/Source/ResponseSerialization.swift b/Pods/Alamofire/Source/ResponseSerialization.swift
new file mode 100644
index 0000000..23d8ab2
--- /dev/null
+++ b/Pods/Alamofire/Source/ResponseSerialization.swift
@@ -0,0 +1,331 @@
+// ResponseSerialization.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+// MARK: ResponseSerializer
+
+/**
+ The type in which all response serializers must conform to in order to serialize a response.
+*/
+public protocol ResponseSerializer {
+ /// The type of serialized object to be created by this `ResponseSerializer`.
+ typealias SerializedObject
+
+ /**
+ A closure used by response handlers that takes a request, response, and data and returns a result.
+ */
+ var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result { get }
+}
+
+// MARK: -
+
+/**
+ A generic `ResponseSerializer` used to serialize a request, response, and data into a serialized object.
+*/
+public struct GenericResponseSerializer: ResponseSerializer {
+ /// The type of serialized object to be created by this `ResponseSerializer`.
+ public typealias SerializedObject = T
+
+ /**
+ A closure used by response handlers that takes a request, response, and data and returns a result.
+ */
+ public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result
+
+ /**
+ Initializes the `GenericResponseSerializer` instance with the given serialize response closure.
+
+ - parameter serializeResponse: The closure used to serialize the response.
+
+ - returns: The new generic response serializer instance.
+ */
+ public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result) {
+ self.serializeResponse = serializeResponse
+ }
+}
+
+// MARK: - Default
+
+extension Request {
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter queue: The queue on which the completion handler is dispatched.
+ - parameter completionHandler: The code to be executed once the request has finished.
+
+ - returns: The request.
+ */
+ public func response(
+ queue queue: dispatch_queue_t? = nil,
+ completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, ErrorType?) -> Void)
+ -> Self
+ {
+ delegate.queue.addOperationWithBlock {
+ dispatch_async(queue ?? dispatch_get_main_queue()) {
+ completionHandler(self.request, self.response, self.delegate.data, self.delegate.error)
+ }
+ }
+
+ return self
+ }
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter queue: The queue on which the completion handler is dispatched.
+ - parameter responseSerializer: The response serializer responsible for serializing the request, response,
+ and data.
+ - parameter completionHandler: The code to be executed once the request has finished.
+
+ - returns: The request.
+ */
+ public func response(
+ queue queue: dispatch_queue_t? = nil,
+ responseSerializer: T,
+ completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void)
+ -> Self
+ {
+ delegate.queue.addOperationWithBlock {
+ let result: Result = {
+ if let error = self.delegate.error {
+ return .Failure(self.delegate.data, error)
+ } else {
+ return responseSerializer.serializeResponse(self.request, self.response, self.delegate.data)
+ }
+ }()
+
+ dispatch_async(queue ?? dispatch_get_main_queue()) {
+ completionHandler(self.request, self.response, result)
+ }
+ }
+
+ return self
+ }
+}
+
+// MARK: - Data
+
+extension Request {
+
+ /**
+ Creates a response serializer that returns the associated data as-is.
+
+ - returns: A data response serializer.
+ */
+ public static func dataResponseSerializer() -> GenericResponseSerializer {
+ return GenericResponseSerializer { _, _, data in
+ guard let validData = data else {
+ let failureReason = "Data could not be serialized. Input data was nil."
+ let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+
+ return .Success(validData)
+ }
+ }
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter completionHandler: The code to be executed once the request has finished.
+
+ - returns: The request.
+ */
+ public func responseData(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void) -> Self {
+ return response(responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler)
+ }
+}
+
+// MARK: - String
+
+extension Request {
+
+ /**
+ Creates a response serializer that returns a string initialized from the response data with the specified
+ string encoding.
+
+ - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the server
+ response, falling back to the default HTTP default character set, ISO-8859-1.
+
+ - returns: A string response serializer.
+ */
+ public static func stringResponseSerializer(
+ var encoding encoding: NSStringEncoding? = nil)
+ -> GenericResponseSerializer
+ {
+ return GenericResponseSerializer { _, response, data in
+ guard let validData = data else {
+ let failureReason = "String could not be serialized because input data was nil."
+ let error = Error.errorWithCode(.StringSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+
+ if let encodingName = response?.textEncodingName where encoding == nil {
+ encoding = CFStringConvertEncodingToNSStringEncoding(
+ CFStringConvertIANACharSetNameToEncoding(encodingName)
+ )
+ }
+
+ let actualEncoding = encoding ?? NSISOLatin1StringEncoding
+
+ if let string = NSString(data: validData, encoding: actualEncoding) as? String {
+ return .Success(string)
+ } else {
+ let failureReason = "String could not be serialized with encoding: \(actualEncoding)"
+ let error = Error.errorWithCode(.StringSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+ }
+ }
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter encoding: The string encoding. If `nil`, the string encoding will be determined from the
+ server response, falling back to the default HTTP default character set,
+ ISO-8859-1.
+ - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3
+ arguments: the URL request, the URL response and the result produced while
+ creating the string.
+
+ - returns: The request.
+ */
+ public func responseString(
+ encoding encoding: NSStringEncoding? = nil,
+ completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void)
+ -> Self
+ {
+ return response(
+ responseSerializer: Request.stringResponseSerializer(encoding: encoding),
+ completionHandler: completionHandler
+ )
+ }
+}
+
+// MARK: - JSON
+
+extension Request {
+
+ /**
+ Creates a response serializer that returns a JSON object constructed from the response data using
+ `NSJSONSerialization` with the specified reading options.
+
+ - parameter options: The JSON serialization reading options. `.AllowFragments` by default.
+
+ - returns: A JSON object response serializer.
+ */
+ public static func JSONResponseSerializer(
+ options options: NSJSONReadingOptions = .AllowFragments)
+ -> GenericResponseSerializer
+ {
+ return GenericResponseSerializer { _, _, data in
+ guard let validData = data else {
+ let failureReason = "JSON could not be serialized because input data was nil."
+ let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+
+ do {
+ let JSON = try NSJSONSerialization.JSONObjectWithData(validData, options: options)
+ return .Success(JSON)
+ } catch {
+ return .Failure(data, error as NSError)
+ }
+ }
+ }
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter options: The JSON serialization reading options. `.AllowFragments` by default.
+ - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3
+ arguments: the URL request, the URL response and the result produced while
+ creating the JSON object.
+
+ - returns: The request.
+ */
+ public func responseJSON(
+ options options: NSJSONReadingOptions = .AllowFragments,
+ completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void)
+ -> Self
+ {
+ return response(
+ responseSerializer: Request.JSONResponseSerializer(options: options),
+ completionHandler: completionHandler
+ )
+ }
+}
+
+// MARK: - Property List
+
+extension Request {
+
+ /**
+ Creates a response serializer that returns an object constructed from the response data using
+ `NSPropertyListSerialization` with the specified reading options.
+
+ - parameter options: The property list reading options. `NSPropertyListReadOptions()` by default.
+
+ - returns: A property list object response serializer.
+ */
+ public static func propertyListResponseSerializer(
+ options options: NSPropertyListReadOptions = NSPropertyListReadOptions())
+ -> GenericResponseSerializer
+ {
+ return GenericResponseSerializer { _, _, data in
+ guard let validData = data else {
+ let failureReason = "Property list could not be serialized because input data was nil."
+ let error = Error.errorWithCode(.PropertyListSerializationFailed, failureReason: failureReason)
+ return .Failure(data, error)
+ }
+
+ do {
+ let plist = try NSPropertyListSerialization.propertyListWithData(validData, options: options, format: nil)
+ return .Success(plist)
+ } catch {
+ return .Failure(data, error as NSError)
+ }
+ }
+ }
+
+ /**
+ Adds a handler to be called once the request has finished.
+
+ - parameter options: The property list reading options. `0` by default.
+ - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3
+ arguments: the URL request, the URL response and the result produced while
+ creating the property list.
+
+ - returns: The request.
+ */
+ public func responsePropertyList(
+ options options: NSPropertyListReadOptions = NSPropertyListReadOptions(),
+ completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result) -> Void)
+ -> Self
+ {
+ return response(
+ responseSerializer: Request.propertyListResponseSerializer(options: options),
+ completionHandler: completionHandler
+ )
+ }
+}
diff --git a/Pods/Alamofire/Source/Result.swift b/Pods/Alamofire/Source/Result.swift
new file mode 100644
index 0000000..958e3ad
--- /dev/null
+++ b/Pods/Alamofire/Source/Result.swift
@@ -0,0 +1,114 @@
+// Result.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/**
+ Used to represent whether a request was successful or encountered an error.
+
+ - Success: The request and all post processing operations were successful resulting in the serialization of the
+ provided associated value.
+ - Failure: The request encountered an error resulting in a failure. The associated values are the original data
+ provided by the server as well as the error that caused the failure.
+*/
+public enum Result {
+ case Success(Value)
+ case Failure(NSData?, ErrorType)
+
+ /// Returns `true` if the result is a success, `false` otherwise.
+ public var isSuccess: Bool {
+ switch self {
+ case .Success:
+ return true
+ case .Failure:
+ return false
+ }
+ }
+
+ /// Returns `true` if the result is a failure, `false` otherwise.
+ public var isFailure: Bool {
+ return !isSuccess
+ }
+
+ /// Returns the associated value if the result is a success, `nil` otherwise.
+ public var value: Value? {
+ switch self {
+ case .Success(let value):
+ return value
+ case .Failure:
+ return nil
+ }
+ }
+
+ /// Returns the associated data value if the result is a failure, `nil` otherwise.
+ public var data: NSData? {
+ switch self {
+ case .Success:
+ return nil
+ case .Failure(let data, _):
+ return data
+ }
+ }
+
+ /// Returns the associated error value if the result is a failure, `nil` otherwise.
+ public var error: ErrorType? {
+ switch self {
+ case .Success:
+ return nil
+ case .Failure(_, let error):
+ return error
+ }
+ }
+}
+
+// MARK: - CustomStringConvertible
+
+extension Result: CustomStringConvertible {
+ public var description: String {
+ switch self {
+ case .Success:
+ return "SUCCESS"
+ case .Failure:
+ return "FAILURE"
+ }
+ }
+}
+
+// MARK: - CustomDebugStringConvertible
+
+extension Result: CustomDebugStringConvertible {
+ public var debugDescription: String {
+ switch self {
+ case .Success(let value):
+ return "SUCCESS: \(value)"
+ case .Failure(let data, let error):
+ if let
+ data = data,
+ utf8Data = NSString(data: data, encoding: NSUTF8StringEncoding)
+ {
+ return "FAILURE: \(error) \(utf8Data)"
+ } else {
+ return "FAILURE with Error: \(error)"
+ }
+ }
+ }
+}
diff --git a/Pods/Alamofire/Source/ServerTrustPolicy.swift b/Pods/Alamofire/Source/ServerTrustPolicy.swift
new file mode 100644
index 0000000..b6efbce
--- /dev/null
+++ b/Pods/Alamofire/Source/ServerTrustPolicy.swift
@@ -0,0 +1,305 @@
+// ServerTrustPolicy.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+/// Responsible for managing the mapping of `ServerTrustPolicy` objects to a given host.
+public class ServerTrustPolicyManager {
+ /// The dictionary of policies mapped to a particular host.
+ public let policies: [String: ServerTrustPolicy]
+
+ /**
+ Initializes the `ServerTrustPolicyManager` instance with the given policies.
+
+ Since different servers and web services can have different leaf certificates, intermediate and even root
+ certficates, it is important to have the flexibility to specify evaluation policies on a per host basis. This
+ allows for scenarios such as using default evaluation for host1, certificate pinning for host2, public key
+ pinning for host3 and disabling evaluation for host4.
+
+ - parameter policies: A dictionary of all policies mapped to a particular host.
+
+ - returns: The new `ServerTrustPolicyManager` instance.
+ */
+ public init(policies: [String: ServerTrustPolicy]) {
+ self.policies = policies
+ }
+
+ /**
+ Returns the `ServerTrustPolicy` for the given host if applicable.
+
+ By default, this method will return the policy that perfectly matches the given host. Subclasses could override
+ this method and implement more complex mapping implementations such as wildcards.
+
+ - parameter host: The host to use when searching for a matching policy.
+
+ - returns: The server trust policy for the given host if found.
+ */
+ public func serverTrustPolicyForHost(host: String) -> ServerTrustPolicy? {
+ return policies[host]
+ }
+}
+
+// MARK: -
+
+extension NSURLSession {
+ private struct AssociatedKeys {
+ static var ManagerKey = "NSURLSession.ServerTrustPolicyManager"
+ }
+
+ var serverTrustPolicyManager: ServerTrustPolicyManager? {
+ get {
+ return objc_getAssociatedObject(self, &AssociatedKeys.ManagerKey) as? ServerTrustPolicyManager
+ }
+ set (manager) {
+ objc_setAssociatedObject(self, &AssociatedKeys.ManagerKey, manager, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+ }
+ }
+}
+
+// MARK: - ServerTrustPolicy
+
+/**
+ The `ServerTrustPolicy` evaluates the server trust generally provided by an `NSURLAuthenticationChallenge` when
+ connecting to a server over a secure HTTPS connection. The policy configuration then evaluates the server trust
+ with a given set of criteria to determine whether the server trust is valid and the connection should be made.
+
+ Using pinned certificates or public keys for evaluation helps prevent man-in-the-middle (MITM) attacks and other
+ vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged
+ to route all communication over an HTTPS connection with pinning enabled.
+
+ - PerformDefaultEvaluation: Uses the default server trust evaluation while allowing you to control whether to
+ validate the host provided by the challenge. Applications are encouraged to always
+ validate the host in production environments to guarantee the validity of the server's
+ certificate chain.
+
+ - PinCertificates: Uses the pinned certificates to validate the server trust. The server trust is
+ considered valid if one of the pinned certificates match one of the server certificates.
+ By validating both the certificate chain and host, certificate pinning provides a very
+ secure form of server trust validation mitigating most, if not all, MITM attacks.
+ Applications are encouraged to always validate the host and require a valid certificate
+ chain in production environments.
+
+ - PinPublicKeys: Uses the pinned public keys to validate the server trust. The server trust is considered
+ valid if one of the pinned public keys match one of the server certificate public keys.
+ By validating both the certificate chain and host, public key pinning provides a very
+ secure form of server trust validation mitigating most, if not all, MITM attacks.
+ Applications are encouraged to always validate the host and require a valid certificate
+ chain in production environments.
+
+ - DisableEvaluation: Disables all evaluation which in turn will always consider any server trust as valid.
+
+ - CustomEvaluation: Uses the associated closure to evaluate the validity of the server trust.
+*/
+public enum ServerTrustPolicy {
+ case PerformDefaultEvaluation(validateHost: Bool)
+ case PinCertificates(certificates: [SecCertificate], validateCertificateChain: Bool, validateHost: Bool)
+ case PinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool)
+ case DisableEvaluation
+ case CustomEvaluation((serverTrust: SecTrust, host: String) -> Bool)
+
+ // MARK: - Bundle Location
+
+ /**
+ Returns all certificates within the given bundle with a `.cer` file extension.
+
+ - parameter bundle: The bundle to search for all `.cer` files.
+
+ - returns: All certificates within the given bundle.
+ */
+ public static func certificatesInBundle(bundle: NSBundle = NSBundle.mainBundle()) -> [SecCertificate] {
+ var certificates: [SecCertificate] = []
+
+ for path in bundle.pathsForResourcesOfType(".cer", inDirectory: nil) {
+ if let
+ certificateData = NSData(contentsOfFile: path),
+ certificate = SecCertificateCreateWithData(nil, certificateData)
+ {
+ certificates.append(certificate)
+ }
+ }
+
+ return certificates
+ }
+
+ /**
+ Returns all public keys within the given bundle with a `.cer` file extension.
+
+ - parameter bundle: The bundle to search for all `*.cer` files.
+
+ - returns: All public keys within the given bundle.
+ */
+ public static func publicKeysInBundle(bundle: NSBundle = NSBundle.mainBundle()) -> [SecKey] {
+ var publicKeys: [SecKey] = []
+
+ for certificate in certificatesInBundle(bundle) {
+ if let publicKey = publicKeyForCertificate(certificate) {
+ publicKeys.append(publicKey)
+ }
+ }
+
+ return publicKeys
+ }
+
+ // MARK: - Evaluation
+
+ /**
+ Evaluates whether the server trust is valid for the given host.
+
+ - parameter serverTrust: The server trust to evaluate.
+ - parameter host: The host of the challenge protection space.
+
+ - returns: Whether the server trust is valid.
+ */
+ public func evaluateServerTrust(serverTrust: SecTrust, isValidForHost host: String) -> Bool {
+ var serverTrustIsValid = false
+
+ switch self {
+ case let .PerformDefaultEvaluation(validateHost):
+ let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil)
+ SecTrustSetPolicies(serverTrust, [policy])
+
+ serverTrustIsValid = trustIsValid(serverTrust)
+ case let .PinCertificates(pinnedCertificates, validateCertificateChain, validateHost):
+ if validateCertificateChain {
+ let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil)
+ SecTrustSetPolicies(serverTrust, [policy])
+
+ SecTrustSetAnchorCertificates(serverTrust, pinnedCertificates)
+ SecTrustSetAnchorCertificatesOnly(serverTrust, true)
+
+ serverTrustIsValid = trustIsValid(serverTrust)
+ } else {
+ let serverCertificatesDataArray = certificateDataForTrust(serverTrust)
+
+ //======================================================================================================
+ // The following `[] +` is a temporary workaround for a Swift 2.0 compiler error. This workaround should
+ // be removed once the following radar has been resolved:
+ // - http://openradar.appspot.com/radar?id=6082025006039040
+ //======================================================================================================
+
+ let pinnedCertificatesDataArray = certificateDataForCertificates([] + pinnedCertificates)
+
+ outerLoop: for serverCertificateData in serverCertificatesDataArray {
+ for pinnedCertificateData in pinnedCertificatesDataArray {
+ if serverCertificateData.isEqualToData(pinnedCertificateData) {
+ serverTrustIsValid = true
+ break outerLoop
+ }
+ }
+ }
+ }
+ case let .PinPublicKeys(pinnedPublicKeys, validateCertificateChain, validateHost):
+ var certificateChainEvaluationPassed = true
+
+ if validateCertificateChain {
+ let policy = SecPolicyCreateSSL(true, validateHost ? host as CFString : nil)
+ SecTrustSetPolicies(serverTrust, [policy])
+
+ certificateChainEvaluationPassed = trustIsValid(serverTrust)
+ }
+
+ if certificateChainEvaluationPassed {
+ outerLoop: for serverPublicKey in ServerTrustPolicy.publicKeysForTrust(serverTrust) as [AnyObject] {
+ for pinnedPublicKey in pinnedPublicKeys as [AnyObject] {
+ if serverPublicKey.isEqual(pinnedPublicKey) {
+ serverTrustIsValid = true
+ break outerLoop
+ }
+ }
+ }
+ }
+ case .DisableEvaluation:
+ serverTrustIsValid = true
+ case let .CustomEvaluation(closure):
+ serverTrustIsValid = closure(serverTrust: serverTrust, host: host)
+ }
+
+ return serverTrustIsValid
+ }
+
+ // MARK: - Private - Trust Validation
+
+ private func trustIsValid(trust: SecTrust) -> Bool {
+ var isValid = false
+
+ var result = SecTrustResultType(kSecTrustResultInvalid)
+ let status = SecTrustEvaluate(trust, &result)
+
+ if status == errSecSuccess {
+ let unspecified = SecTrustResultType(kSecTrustResultUnspecified)
+ let proceed = SecTrustResultType(kSecTrustResultProceed)
+
+ isValid = result == unspecified || result == proceed
+ }
+
+ return isValid
+ }
+
+ // MARK: - Private - Certificate Data
+
+ private func certificateDataForTrust(trust: SecTrust) -> [NSData] {
+ var certificates: [SecCertificate] = []
+
+ for index in 0.. [NSData] {
+ return certificates.map { SecCertificateCopyData($0) as NSData }
+ }
+
+ // MARK: - Private - Public Key Extraction
+
+ private static func publicKeysForTrust(trust: SecTrust) -> [SecKey] {
+ var publicKeys: [SecKey] = []
+
+ for index in 0.. SecKey? {
+ var publicKey: SecKey?
+
+ let policy = SecPolicyCreateBasicX509()
+ var trust: SecTrust?
+ let trustCreationStatus = SecTrustCreateWithCertificates(certificate, policy, &trust)
+
+ if let trust = trust where trustCreationStatus == errSecSuccess {
+ publicKey = SecTrustCopyPublicKey(trust)
+ }
+
+ return publicKey
+ }
+}
diff --git a/Pods/Alamofire/Source/Stream.swift b/Pods/Alamofire/Source/Stream.swift
new file mode 100644
index 0000000..af89d5d
--- /dev/null
+++ b/Pods/Alamofire/Source/Stream.swift
@@ -0,0 +1,180 @@
+// Stream.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+#if !os(watchOS)
+
+@available(iOS 9.0, OSX 10.11, *)
+extension Manager {
+ private enum Streamable {
+ case Stream(String, Int)
+ case NetService(NSNetService)
+ }
+
+ private func stream(streamable: Streamable) -> Request {
+ var streamTask: NSURLSessionStreamTask!
+
+ switch streamable {
+ case .Stream(let hostName, let port):
+ dispatch_sync(queue) {
+ streamTask = self.session.streamTaskWithHostName(hostName, port: port)
+ }
+ case .NetService(let netService):
+ dispatch_sync(queue) {
+ streamTask = self.session.streamTaskWithNetService(netService)
+ }
+ }
+
+ let request = Request(session: session, task: streamTask)
+
+ delegate[request.delegate.task] = request.delegate
+
+ if startRequestsImmediately {
+ request.resume()
+ }
+
+ return request
+ }
+
+ /**
+ Creates a request for bidirectional streaming with the given hostname and port.
+
+ - parameter hostName: The hostname of the server to connect to.
+ - parameter port: The port of the server to connect to.
+
+ :returns: The created stream request.
+ */
+ public func stream(hostName hostName: String, port: Int) -> Request {
+ return stream(.Stream(hostName, port))
+ }
+
+ /**
+ Creates a request for bidirectional streaming with the given `NSNetService`.
+
+ - parameter netService: The net service used to identify the endpoint.
+
+ - returns: The created stream request.
+ */
+ public func stream(netService netService: NSNetService) -> Request {
+ return stream(.NetService(netService))
+ }
+}
+
+// MARK: -
+
+@available(iOS 9.0, OSX 10.11, *)
+extension Manager.SessionDelegate: NSURLSessionStreamDelegate {
+
+ // MARK: Override Closures
+
+ /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:readClosedForStreamTask:`.
+ public var streamTaskReadClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
+ get {
+ return _streamTaskReadClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void
+ }
+ set {
+ _streamTaskReadClosed = newValue
+ }
+ }
+
+ /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:writeClosedForStreamTask:`.
+ public var streamTaskWriteClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
+ get {
+ return _streamTaskWriteClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void
+ }
+ set {
+ _streamTaskWriteClosed = newValue
+ }
+ }
+
+ /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:betterRouteDiscoveredForStreamTask:`.
+ public var streamTaskBetterRouteDiscovered: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
+ get {
+ return _streamTaskBetterRouteDiscovered as? (NSURLSession, NSURLSessionStreamTask) -> Void
+ }
+ set {
+ _streamTaskBetterRouteDiscovered = newValue
+ }
+ }
+
+ /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:streamTask:didBecomeInputStream:outputStream:`.
+ public var streamTaskDidBecomeInputStream: ((NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void)? {
+ get {
+ return _streamTaskDidBecomeInputStream as? (NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void
+ }
+ set {
+ _streamTaskDidBecomeInputStream = newValue
+ }
+ }
+
+ // MARK: Delegate Methods
+
+ /**
+ Tells the delegate that the read side of the connection has been closed.
+
+ - parameter session: The session.
+ - parameter streamTask: The stream task.
+ */
+ public func URLSession(session: NSURLSession, readClosedForStreamTask streamTask: NSURLSessionStreamTask) {
+ streamTaskReadClosed?(session, streamTask)
+ }
+
+ /**
+ Tells the delegate that the write side of the connection has been closed.
+
+ - parameter session: The session.
+ - parameter streamTask: The stream task.
+ */
+ public func URLSession(session: NSURLSession, writeClosedForStreamTask streamTask: NSURLSessionStreamTask) {
+ streamTaskWriteClosed?(session, streamTask)
+ }
+
+ /**
+ Tells the delegate that the system has determined that a better route to the host is available.
+
+ - parameter session: The session.
+ - parameter streamTask: The stream task.
+ */
+ public func URLSession(session: NSURLSession, betterRouteDiscoveredForStreamTask streamTask: NSURLSessionStreamTask) {
+ streamTaskBetterRouteDiscovered?(session, streamTask)
+ }
+
+ /**
+ Tells the delegate that the stream task has been completed and provides the unopened stream objects.
+
+ - parameter session: The session.
+ - parameter streamTask: The stream task.
+ - parameter inputStream: The new input stream.
+ - parameter outputStream: The new output stream.
+ */
+ public func URLSession(
+ session: NSURLSession,
+ streamTask: NSURLSessionStreamTask,
+ didBecomeInputStream inputStream: NSInputStream,
+ outputStream: NSOutputStream)
+ {
+ streamTaskDidBecomeInputStream?(session, streamTask, inputStream, outputStream)
+ }
+}
+
+#endif
diff --git a/Pods/Alamofire/Source/Upload.swift b/Pods/Alamofire/Source/Upload.swift
new file mode 100644
index 0000000..f7cc8bc
--- /dev/null
+++ b/Pods/Alamofire/Source/Upload.swift
@@ -0,0 +1,372 @@
+// Upload.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+extension Manager {
+ private enum Uploadable {
+ case Data(NSURLRequest, NSData)
+ case File(NSURLRequest, NSURL)
+ case Stream(NSURLRequest, NSInputStream)
+ }
+
+ private func upload(uploadable: Uploadable) -> Request {
+ var uploadTask: NSURLSessionUploadTask!
+ var HTTPBodyStream: NSInputStream?
+
+ switch uploadable {
+ case .Data(let request, let data):
+ dispatch_sync(queue) {
+ uploadTask = self.session.uploadTaskWithRequest(request, fromData: data)
+ }
+ case .File(let request, let fileURL):
+ dispatch_sync(queue) {
+ uploadTask = self.session.uploadTaskWithRequest(request, fromFile: fileURL)
+ }
+ case .Stream(let request, let stream):
+ dispatch_sync(queue) {
+ uploadTask = self.session.uploadTaskWithStreamedRequest(request)
+ }
+
+ HTTPBodyStream = stream
+ }
+
+ let request = Request(session: session, task: uploadTask)
+
+ if HTTPBodyStream != nil {
+ request.delegate.taskNeedNewBodyStream = { _, _ in
+ return HTTPBodyStream
+ }
+ }
+
+ delegate[request.delegate.task] = request.delegate
+
+ if startRequestsImmediately {
+ request.resume()
+ }
+
+ return request
+ }
+
+ // MARK: File
+
+ /**
+ Creates a request for uploading a file to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request
+ - parameter file: The file to upload
+
+ - returns: The created upload request.
+ */
+ public func upload(URLRequest: URLRequestConvertible, file: NSURL) -> Request {
+ return upload(.File(URLRequest.URLRequest, file))
+ }
+
+ /**
+ Creates a request for uploading a file to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter file: The file to upload
+
+ - returns: The created upload request.
+ */
+ public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ file: NSURL)
+ -> Request
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+ return upload(mutableURLRequest, file: file)
+ }
+
+ // MARK: Data
+
+ /**
+ Creates a request for uploading data to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request.
+ - parameter data: The data to upload.
+
+ - returns: The created upload request.
+ */
+ public func upload(URLRequest: URLRequestConvertible, data: NSData) -> Request {
+ return upload(.Data(URLRequest.URLRequest, data))
+ }
+
+ /**
+ Creates a request for uploading data to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter data: The data to upload
+
+ - returns: The created upload request.
+ */
+ public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ data: NSData)
+ -> Request
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+
+ return upload(mutableURLRequest, data: data)
+ }
+
+ // MARK: Stream
+
+ /**
+ Creates a request for uploading a stream to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request.
+ - parameter stream: The stream to upload.
+
+ - returns: The created upload request.
+ */
+ public func upload(URLRequest: URLRequestConvertible, stream: NSInputStream) -> Request {
+ return upload(.Stream(URLRequest.URLRequest, stream))
+ }
+
+ /**
+ Creates a request for uploading a stream to the specified URL request.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter stream: The stream to upload.
+
+ - returns: The created upload request.
+ */
+ public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ stream: NSInputStream)
+ -> Request
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+
+ return upload(mutableURLRequest, stream: stream)
+ }
+
+ // MARK: MultipartFormData
+
+ /// Default memory threshold used when encoding `MultipartFormData`.
+ public static let MultipartFormDataEncodingMemoryThreshold: UInt64 = 10 * 1024 * 1024
+
+ /**
+ Defines whether the `MultipartFormData` encoding was successful and contains result of the encoding as
+ associated values.
+
+ - Success: Represents a successful `MultipartFormData` encoding and contains the new `Request` along with
+ streaming information.
+ - Failure: Used to represent a failure in the `MultipartFormData` encoding and also contains the encoding
+ error.
+ */
+ public enum MultipartFormDataEncodingResult {
+ case Success(request: Request, streamingFromDisk: Bool, streamFileURL: NSURL?)
+ case Failure(ErrorType)
+ }
+
+ /**
+ Encodes the `MultipartFormData` and creates a request to upload the result to the specified URL request.
+
+ It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
+ payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
+ efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
+ be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
+ footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
+ used for larger payloads such as video content.
+
+ The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
+ or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
+ encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
+ during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
+ technique was used.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter method: The HTTP method.
+ - parameter URLString: The URL string.
+ - parameter headers: The HTTP headers. `nil` by default.
+ - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
+ - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
+ `MultipartFormDataEncodingMemoryThreshold` by default.
+ - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
+ */
+ public func upload(
+ method: Method,
+ _ URLString: URLStringConvertible,
+ headers: [String: String]? = nil,
+ multipartFormData: MultipartFormData -> Void,
+ encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold,
+ encodingCompletion: (MultipartFormDataEncodingResult -> Void)?)
+ {
+ let mutableURLRequest = URLRequest(method, URLString, headers: headers)
+
+ return upload(
+ mutableURLRequest,
+ multipartFormData: multipartFormData,
+ encodingMemoryThreshold: encodingMemoryThreshold,
+ encodingCompletion: encodingCompletion
+ )
+ }
+
+ /**
+ Encodes the `MultipartFormData` and creates a request to upload the result to the specified URL request.
+
+ It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
+ payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
+ efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
+ be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
+ footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
+ used for larger payloads such as video content.
+
+ The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
+ or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
+ encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
+ during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
+ technique was used.
+
+ If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+
+ - parameter URLRequest: The URL request.
+ - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
+ - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
+ `MultipartFormDataEncodingMemoryThreshold` by default.
+ - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
+ */
+ public func upload(
+ URLRequest: URLRequestConvertible,
+ multipartFormData: MultipartFormData -> Void,
+ encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold,
+ encodingCompletion: (MultipartFormDataEncodingResult -> Void)?)
+ {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
+ let formData = MultipartFormData()
+ multipartFormData(formData)
+
+ let URLRequestWithContentType = URLRequest.URLRequest
+ URLRequestWithContentType.setValue(formData.contentType, forHTTPHeaderField: "Content-Type")
+
+ let isBackgroundSession = self.session.configuration.identifier != nil
+
+ if formData.contentLength < encodingMemoryThreshold && !isBackgroundSession {
+ do {
+ let data = try formData.encode()
+ let encodingResult = MultipartFormDataEncodingResult.Success(
+ request: self.upload(URLRequestWithContentType, data: data),
+ streamingFromDisk: false,
+ streamFileURL: nil
+ )
+
+ dispatch_async(dispatch_get_main_queue()) {
+ encodingCompletion?(encodingResult)
+ }
+ } catch {
+ dispatch_async(dispatch_get_main_queue()) {
+ encodingCompletion?(.Failure(error as NSError))
+ }
+ }
+ } else {
+ let fileManager = NSFileManager.defaultManager()
+ let tempDirectoryURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
+ let directoryURL = tempDirectoryURL.URLByAppendingPathComponent("com.alamofire.manager/multipart.form.data")
+ let fileName = NSUUID().UUIDString
+ let fileURL = directoryURL.URLByAppendingPathComponent(fileName)
+
+ do {
+ try fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
+ try formData.writeEncodedDataToDisk(fileURL)
+
+ dispatch_async(dispatch_get_main_queue()) {
+ let encodingResult = MultipartFormDataEncodingResult.Success(
+ request: self.upload(URLRequestWithContentType, file: fileURL),
+ streamingFromDisk: true,
+ streamFileURL: fileURL
+ )
+ encodingCompletion?(encodingResult)
+ }
+ } catch {
+ dispatch_async(dispatch_get_main_queue()) {
+ encodingCompletion?(.Failure(error as NSError))
+ }
+ }
+ }
+ }
+ }
+}
+
+// MARK: -
+
+extension Request {
+
+ // MARK: - UploadTaskDelegate
+
+ class UploadTaskDelegate: DataTaskDelegate {
+ var uploadTask: NSURLSessionUploadTask? { return task as? NSURLSessionUploadTask }
+ var uploadProgress: ((Int64, Int64, Int64) -> Void)!
+
+ // MARK: - NSURLSessionTaskDelegate
+
+ // MARK: Override Closures
+
+ var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)?
+
+ // MARK: Delegate Methods
+
+ func URLSession(
+ session: NSURLSession,
+ task: NSURLSessionTask,
+ didSendBodyData bytesSent: Int64,
+ totalBytesSent: Int64,
+ totalBytesExpectedToSend: Int64)
+ {
+ if let taskDidSendBodyData = taskDidSendBodyData {
+ taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
+ } else {
+ progress.totalUnitCount = totalBytesExpectedToSend
+ progress.completedUnitCount = totalBytesSent
+
+ uploadProgress?(bytesSent, totalBytesSent, totalBytesExpectedToSend)
+ }
+ }
+ }
+}
diff --git a/Pods/Alamofire/Source/Validation.swift b/Pods/Alamofire/Source/Validation.swift
new file mode 100644
index 0000000..24f29d7
--- /dev/null
+++ b/Pods/Alamofire/Source/Validation.swift
@@ -0,0 +1,187 @@
+// Validation.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// 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
+
+extension Request {
+
+ /**
+ Used to represent whether validation was successful or encountered an error resulting in a failure.
+
+ - Success: The validation was successful.
+ - Failure: The validation failed encountering the provided error.
+ */
+ public enum ValidationResult {
+ case Success
+ case Failure(ErrorType)
+ }
+
+ /**
+ A closure used to validate a request that takes a URL request and URL response, and returns whether the
+ request was valid.
+ */
+ public typealias Validation = (NSURLRequest?, NSHTTPURLResponse) -> ValidationResult
+
+ /**
+ Validates the request, using the specified closure.
+
+ If validation fails, subsequent calls to response handlers will have an associated error.
+
+ - parameter validation: A closure to validate the request.
+
+ - returns: The request.
+ */
+ public func validate(validation: Validation) -> Self {
+ delegate.queue.addOperationWithBlock {
+ if let
+ response = self.response where self.delegate.error == nil,
+ case let .Failure(error) = validation(self.request, response)
+ {
+ self.delegate.error = error
+ }
+ }
+
+ return self
+ }
+
+ // MARK: - Status Code
+
+ /**
+ Validates that the response has a status code in the specified range.
+
+ If validation fails, subsequent calls to response handlers will have an associated error.
+
+ - parameter range: The range of acceptable status codes.
+
+ - returns: The request.
+ */
+ public func validate(statusCode acceptableStatusCode: S) -> Self {
+ return validate { _, response in
+ if acceptableStatusCode.contains(response.statusCode) {
+ return .Success
+ } else {
+ let failureReason = "Response status code was unacceptable: \(response.statusCode)"
+ return .Failure(Error.errorWithCode(.StatusCodeValidationFailed, failureReason: failureReason))
+ }
+ }
+ }
+
+ // MARK: - Content-Type
+
+ private struct MIMEType {
+ let type: String
+ let subtype: String
+
+ init?(_ string: String) {
+ let components: [String] = {
+ let stripped = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
+ let split = stripped.substringToIndex(stripped.rangeOfString(";")?.endIndex ?? stripped.endIndex)
+ return split.componentsSeparatedByString("/")
+ }()
+
+ if let
+ type = components.first,
+ subtype = components.last
+ {
+ self.type = type
+ self.subtype = subtype
+ } else {
+ return nil
+ }
+ }
+
+ func matches(MIME: MIMEType) -> Bool {
+ switch (type, subtype) {
+ case (MIME.type, MIME.subtype), (MIME.type, "*"), ("*", MIME.subtype), ("*", "*"):
+ return true
+ default:
+ return false
+ }
+ }
+ }
+
+ /**
+ Validates that the response has a content type in the specified array.
+
+ If validation fails, subsequent calls to response handlers will have an associated error.
+
+ - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes.
+
+ - returns: The request.
+ */
+ public func validate(contentType acceptableContentTypes: S) -> Self {
+ return validate { _, response in
+ if let
+ responseContentType = response.MIMEType,
+ responseMIMEType = MIMEType(responseContentType)
+ {
+ for contentType in acceptableContentTypes {
+ if let acceptableMIMEType = MIMEType(contentType) where acceptableMIMEType.matches(responseMIMEType) {
+ return .Success
+ }
+ }
+ } else {
+ for contentType in acceptableContentTypes {
+ if let MIMEType = MIMEType(contentType) where MIMEType.type == "*" && MIMEType.subtype == "*" {
+ return .Success
+ }
+ }
+ }
+
+ let failureReason: String
+
+ if let responseContentType = response.MIMEType {
+ failureReason = (
+ "Response content type \"\(responseContentType)\" does not match any acceptable " +
+ "content types: \(acceptableContentTypes)"
+ )
+ } else {
+ failureReason = "Response content type was missing and acceptable content type does not match \"*/*\""
+ }
+
+ return .Failure(Error.errorWithCode(.ContentTypeValidationFailed, failureReason: failureReason))
+ }
+ }
+
+ // MARK: - Automatic
+
+ /**
+ Validates that the response has a status code in the default acceptable range of 200...299, and that the content
+ type matches any specified in the Accept HTTP header field.
+
+ If validation fails, subsequent calls to response handlers will have an associated error.
+
+ - returns: The request.
+ */
+ public func validate() -> Self {
+ let acceptableStatusCodes: Range = 200..<300
+ let acceptableContentTypes: [String] = {
+ if let accept = request?.valueForHTTPHeaderField("Accept") {
+ return accept.componentsSeparatedByString(",")
+ }
+
+ return ["*/*"]
+ }()
+
+ return validate(statusCode: acceptableStatusCodes).validate(contentType: acceptableContentTypes)
+ }
+}
diff --git a/Pods/Firebase/Empty.m b/Pods/Firebase/Empty.m
new file mode 100644
index 0000000..e69de29
diff --git a/Pods/Firebase/FAuthData.h b/Pods/Firebase/FAuthData.h
new file mode 100644
index 0000000..b2f0b7f
--- /dev/null
+++ b/Pods/Firebase/FAuthData.h
@@ -0,0 +1,55 @@
+//
+// FAuthData.h
+// Firebase
+//
+// Created by Katherine Fang on 7/30/14.
+//
+
+#import
+#import "FAuthType.h"
+
+
+/**
+* The FAuthData class is a wrapper around the user metadata returned from the Firebase auth server.
+* It includes the provider authenticated against, a uid (with the possible exception of authenticating against a custom
+* backend), and a token used to authenticate with Firebase.
+*
+* It may include other metadata about the user, depending on the provider used to do the authentication.
+*/
+@interface FAuthData : NSObject
+
+/**
+* @return Raw authentication token payload returned by the server
+*/
+@property (nonatomic, strong, readonly) NSDictionary *auth;
+
+/**
+ * @return Authentication token expiration timestamp (seconds since epoch) returned by the server
+ */
+@property (nonatomic, strong, readonly) NSNumber *expires;
+
+/**
+* @return A uid for this user. It is unique across all auth providers.
+*/
+@property (nonatomic, strong, readonly) NSString *uid;
+
+
+/**
+* @return The provider that authenticated this user
+*/
+@property (nonatomic, readonly) NSString *provider;
+
+
+/**
+* @return The token that was used to authenticate this user with Firebase
+*/
+@property (nonatomic, strong, readonly) NSString *token;
+
+
+/**
+* @return Provider data keyed by provider. Includes cached data from third-party providers
+*/
+@property (nonatomic, strong, readonly) NSDictionary *providerData;
+
+
+@end
diff --git a/Pods/Firebase/FAuthType.h b/Pods/Firebase/FAuthType.h
new file mode 100644
index 0000000..0f772b1
--- /dev/null
+++ b/Pods/Firebase/FAuthType.h
@@ -0,0 +1,41 @@
+//
+// FAuthType.h
+// Firebase
+//
+// Created by Katherine Fang on 7/30/14.
+//
+// All public-facing auth enums.
+//
+
+#ifndef Firebase_FAuthenticationTypes_h
+#define Firebase_FAuthenticationTypes_h
+
+typedef NS_ENUM(NSInteger, FAuthenticationError) {
+ // Developer / Config Errors
+ FAuthenticationErrorProviderDisabled = -1,
+ FAuthenticationErrorInvalidConfiguration = -2,
+ FAuthenticationErrorInvalidOrigin = -3,
+ FAuthenticationErrorInvalidProvider = -4,
+
+ // User Errors (Email / Password)
+ FAuthenticationErrorInvalidEmail = -5,
+ FAuthenticationErrorInvalidPassword = -6,
+ FAuthenticationErrorInvalidToken = -7,
+ FAuthenticationErrorUserDoesNotExist = -8,
+ FAuthenticationErrorEmailTaken = -9,
+
+ // User Errors (Facebook / Twitter / Github / Google)
+ FAuthenticationErrorDeniedByUser = -10,
+ FAuthenticationErrorInvalidCredentials = -11,
+ FAuthenticationErrorInvalidArguments = -12,
+ FAuthenticationErrorProviderError = -13,
+ FAuthenticationErrorLimitsExceeded = -14,
+
+ // Client side errors
+ FAuthenticationErrorNetworkError = -15,
+ FAuthenticationErrorPreempted = -16,
+
+ FAuthenticationErrorUnknown = -9999
+};
+
+#endif
\ No newline at end of file
diff --git a/Pods/Firebase/FConfig.h b/Pods/Firebase/FConfig.h
new file mode 100644
index 0000000..dcfdefa
--- /dev/null
+++ b/Pods/Firebase/FConfig.h
@@ -0,0 +1,69 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2015 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import
+
+/**
+ * Configuration object for Firebase. You can get the default FConfig object via
+ * `[Firebase defaultConfig]` and modify it. You must make all changes to it before
+ * you create your first Firebase instance.
+ */
+@interface FConfig : NSObject
+
+/**
+ * By default the Firebase client will keep data in memory while your application is running, but not
+ * when it is restarted. By setting this value to YES, the data will be persisted to on-device (disk)
+ * storage and will thus be available again when the app is restarted (even when there is no network
+ * connectivity at that time). Note that this property must be set before creating your first Firebase
+ * reference and only needs to be called once per application.
+ *
+ * If your app uses Firebase Authentication, the client will automatically persist the user's authentication
+ * token across restarts, even without persistence enabled. But if the auth token expired while offline and
+ * you've enabled persistence, the client will pause write operations until you successfully re-authenticate
+ * (or explicitly unauthenticate) to prevent your writes from being sent unauthenticated and failing due to
+ * security rules.
+ */
+@property (nonatomic) BOOL persistenceEnabled;
+
+/**
+ * By default Firebase will use up to 10MB of disk space to cache data. If the cache grows beyond this size,
+ * Firebase will start removing data that hasn't been recently used. If you find that your application caches too
+ * little or too much data, call this method to change the cache size. This property must be set before creating
+ * your first Firebase reference and only needs to be called once per application.
+ *
+ * Note that the specified cache size is only an approximation and the size on disk may temporarily exceed it
+ * at times.
+ */
+@property (nonatomic) NSUInteger persistenceCacheSizeBytes;
+
+/**
+ * Sets the dispatch queue on which all events are raised. The default queue is the main queue.
+ */
+@property (nonatomic, strong) dispatch_queue_t callbackQueue;
+
+@end
diff --git a/Pods/Firebase/FDataSnapshot.h b/Pods/Firebase/FDataSnapshot.h
new file mode 100644
index 0000000..fc794ac
--- /dev/null
+++ b/Pods/Firebase/FDataSnapshot.h
@@ -0,0 +1,154 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import
+
+@class Firebase;
+
+/**
+ * An FDataSnapshot contains data from a Firebase location. Any time you read
+ * Firebase data, you receive the data as an FDataSnapshot.
+ *
+ * FDataSnapshots are passed to the blocks you attach with observeEventType:withBlock: or observeSingleEvent:withBlock:.
+ * They are efficiently-generated immutable copies of the data at a Firebase location.
+ * They can't be modified and will never change. To modify data at a location,
+ * use a Firebase reference (e.g. with setValue:).
+ */
+@interface FDataSnapshot : NSObject
+
+
+/** @name Navigating and inspecting a snapshot */
+
+/**
+ * Get an FDataSnapshot for the location at the specified relative path.
+ * The relative path can either be a simple child key (e.g. 'fred')
+ * or a deeper slash-separated path (e.g. 'fred/name/first'). If the child
+ * location has no data, an empty FDataSnapshot is returned.
+ *
+ * @param childPathString A relative path to the location of child data.
+ * @return The FDataSnapshot for the child location.
+ */
+- (FDataSnapshot *) childSnapshotForPath:(NSString *)childPathString;
+
+
+/**
+ * Return YES if the specified child exists.
+ *
+ * @param childPathString A relative path to the location of a potential child.
+ * @return YES if data exists at the specified childPathString, else false.
+ */
+- (BOOL) hasChild:(NSString *)childPathString;
+
+
+/**
+ * Return YES if the DataSnapshot has any children.
+ *
+ * @return YES if this snapshot has any children, else NO.
+ */
+- (BOOL) hasChildren;
+
+
+/**
+ * Return YES if the DataSnapshot contains a non-null value.
+ *
+ * @return YES if this snapshot contains a non-null value, otherwise NO.
+ */
+- (BOOL) exists;
+
+
+/** @name Data export */
+
+/**
+ * Returns the raw value at this location, coupled with any metadata, such as priority.
+ *
+ * Priorities, where they exist, are accessible under the ".priority" key in instances of NSDictionary.
+ * For leaf locations with priorities, the value will be under the ".value" key.
+ */
+- (id) valueInExportFormat;
+
+
+/** @name Properties */
+
+/**
+ * Returns the contents of this data snapshot as native types.
+ *
+ * Data types returned:
+ * * NSDictionary
+ * * NSArray
+ * * NSNumber (also includes booleans)
+ * * NSString
+ *
+ * @return The data as a native object.
+ */
+@property (strong, readonly, nonatomic) id value;
+
+
+/**
+ * Get the number of children for this DataSnapshot.
+ *
+ * @return An integer indicating the number of children.
+ */
+@property (readonly, nonatomic) NSUInteger childrenCount;
+
+
+/**
+ * Get a Firebase reference for the location that this data came from
+ *
+ * @return A Firebase instance for the location of this data
+ */
+@property (nonatomic, readonly, strong) Firebase* ref;
+
+
+/**
+ * The key of the location that generated this FDataSnapshot.
+ *
+ * @return An NSString containing the key for the location of this FDataSnapshot.
+ */
+@property (strong, readonly, nonatomic) NSString* key;
+
+
+/**
+ * An iterator for snapshots of the child nodes in this snapshot.
+ * You can use the native for..in syntax:
+ *
+ * for (FDataSnapshot* child in snapshot.children) {
+ * ...
+ * }
+ *
+ * @return An NSEnumerator of the children
+ */
+@property (strong, readonly, nonatomic) NSEnumerator* children;
+
+/**
+ * The priority of the data in this FDataSnapshot.
+ *
+ * @return The priority as a string, or nil if no priority was set.
+ */
+@property (strong, readonly, nonatomic) id priority;
+
+@end
diff --git a/Pods/Firebase/FEventType.h b/Pods/Firebase/FEventType.h
new file mode 100644
index 0000000..6d672bd
--- /dev/null
+++ b/Pods/Firebase/FEventType.h
@@ -0,0 +1,43 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Firebase_FEventType_h
+#define Firebase_FEventType_h
+
+/**
+ * This enum is the set of events that you can observe at a Firebase location.
+ */
+typedef NS_ENUM(NSInteger, FEventType) {
+ FEventTypeChildAdded, // 0, fired when a new child node is added to a location
+ FEventTypeChildRemoved, // 1, fired when a child node is removed from a location
+ FEventTypeChildChanged, // 2, fired when a child node at a location changes
+ FEventTypeChildMoved, // 3, fired when a child node moves relative to the other child nodes at a location
+ FEventTypeValue // 4, fired when any data changes at a location and, recursively, any children
+};
+
+#endif
diff --git a/Pods/Firebase/FMutableData.h b/Pods/Firebase/FMutableData.h
new file mode 100644
index 0000000..4dbefca
--- /dev/null
+++ b/Pods/Firebase/FMutableData.h
@@ -0,0 +1,143 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import
+
+/**
+ * An FMutableData instance is populated with data from a Firebase location.
+ * When you are using runTransactionBlock:, you will be given an instance containing the current
+ * data at that location. Your block will be responsible for updating that instance to the data
+ * you wish to save at that location, and then returning using [FTransactionResult successWithValue:].
+ *
+ * To modify the data, set its value property to any of the native types support by Firebase:
+ * * NSNumber (includes BOOL)
+ * * NSDictionary
+ * * NSArray
+ * * NSString
+ * * nil / NSNull to remove the data
+ *
+ * Note that changes made to a child FMutableData instance will be visible to the parent.
+ */
+@interface FMutableData : NSObject
+
+
+/** @name Inspecting and navigating the data */
+
+
+/**
+ * Returns boolean indicating whether this mutable data has children.
+ *
+ * @return YES if this data contains child nodes.
+ */
+- (BOOL) hasChildren;
+
+
+/**
+ * Indicates whether this mutable data has a child at the given path.
+ *
+ * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child'
+ * @return YES if this data contains a child at the specified relative path
+ */
+- (BOOL) hasChildAtPath:(NSString *)path;
+
+
+/**
+ * Used to obtain an FMutableData instance that encapsulates the data at the given relative path.
+ * Note that changes made to the child will be visible to the parent.
+ *
+ * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child'
+ * @return An FMutableData instance containing the data at the given path
+ */
+- (FMutableData *) childDataByAppendingPath:(NSString *)path;
+
+
+/** @name Properties */
+
+
+/**
+ * This method is deprecated.
+ *
+ * @return An FMutableData instance containing the data at the parent location, or nil if this is the top-most location
+ */
+@property (strong, readonly, nonatomic) FMutableData* parent __attribute__((deprecated("Deprecated. Do not use.")));;
+
+
+/**
+ * To modify the data contained by this instance of FMutableData, set this to any of the native types support by Firebase:
+ *
+ * * NSNumber (includes BOOL)
+ * * NSDictionary
+ * * NSArray
+ * * NSString
+ * * nil / NSNull to remove the data
+ *
+ * Note that setting the value will override the priority at this location.
+ *
+ * @return The current data at this location as a native object
+ */
+@property (strong, nonatomic) id value;
+
+
+/**
+ * Set this property to update the priority of the data at this location. Can be set to the following types:
+ *
+ * * NSNumber
+ * * NSString
+ * * nil / NSNull to remove the priority
+ *
+ * @return The priority of the data at this location
+ */
+@property (strong, nonatomic) id priority;
+
+
+/**
+ * @return The number of child nodes at this location
+ */
+@property (readonly, nonatomic) NSUInteger childrenCount;
+
+
+/**
+ * Used to iterate over the children at this location. You can use the native for .. in syntax:
+ *
+ * for (FMutableData* child in data.children) {
+ * ...
+ * }
+ *
+ * Note that this enumerator operates on an immutable copy of the child list. So, you can modify the instance
+ * during iteration, but the new additions will not be visible until you get a new enumerator.
+ */
+@property (readonly, nonatomic, strong) NSEnumerator* children;
+
+
+/**
+ * @return The key name of this node, or nil if it is the top-most location
+ */
+@property (readonly, nonatomic, strong) NSString* key;
+
+
+@end
diff --git a/Pods/Firebase/FQuery.h b/Pods/Firebase/FQuery.h
new file mode 100644
index 0000000..f2588b9
--- /dev/null
+++ b/Pods/Firebase/FQuery.h
@@ -0,0 +1,412 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import
+#import "FEventType.h"
+#import "FDataSnapshot.h"
+
+typedef NSUInteger FirebaseHandle;
+
+/**
+ * An FQuery instance represents a query over the data at a particular location.
+ *
+ * You create one by calling one of the query methods (queryStartingAtPriority:, queryEndingAtPriority:, etc.)
+ * on a Firebase reference. The query methods can be chained to further specify the data you are interested in
+ * observing
+ */
+@interface FQuery : NSObject
+
+
+/** @name Attaching observers to read data */
+
+/**
+ * observeEventType:withBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot.
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block;
+
+
+/**
+ * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot
+ * and the previous child's key.
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block;
+
+
+/**
+ * observeEventType:withBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes.
+ *
+ * The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot.
+ * @param cancelBlock The block that should be called if this client no longer has permission to receive these events
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot
+ * and the previous child's key.
+ * @param cancelBlock The block that should be called if this client no longer has permission to receive these events
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot.
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot and the previous child's key.
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
+ *
+ * The cancelBlock will be called if you do not have permission to read data at this location.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot.
+ * @param cancelBlock The block that will be called if you don't have permission to access this data
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * The cancelBlock will be called if you do not have permission to read data at this location.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot and the previous child's key.
+ * @param cancelBlock The block that will be called if you don't have permission to access this data
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+/** @name Detaching observers */
+
+/**
+ * Detach a block previously attached with observeEventType:withBlock:.
+ *
+ * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove.
+ */
+- (void) removeObserverWithHandle:(FirebaseHandle)handle;
+
+
+/**
+ * Detach all blocks previously attached to this Firebase location with observeEventType:withBlock:
+ */
+- (void) removeAllObservers;
+
+/**
+ * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and
+ * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept
+ * synced, it will not be evicted from the persistent disk cache.
+ *
+ * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization.
+*/
+ - (void) keepSynced:(BOOL)keepSynced;
+
+
+/** @name Querying and limiting */
+
+
+/**
+* This method is deprecated in favor of using queryStartingAtValue:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+ * queryStartingAtPriority: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtPriority: will respond to events at nodes with a priority
+ * greater than or equal to startPriority
+ *
+ * @param startPriority The lower bound, inclusive, for the priority of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with priority greater than or equal to startPriority
+ */
+- (FQuery *) queryStartingAtPriority:(id)startPriority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryStartingAtValue:] instead")));
+
+
+/**
+* This method is deprecated in favor of using queryStartingAtValue:childKey:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+ * queryStartingAtPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtPriority:andChildName will respond to events at nodes with a priority
+ * greater than startPriority, or equal to startPriority and with a name greater than or equal to childName
+ *
+ * @param startPriority The lower bound, inclusive, for the priority of data visible to the returned FQuery
+ * @param childName The lower bound, inclusive, for the name of nodes with priority equal to startPriority
+ * @return An FQuery instance, limited to data with priority greater than or equal to startPriority
+ */
+- (FQuery *) queryStartingAtPriority:(id)startPriority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryStartingAtValue:childKey:] instead")));
+
+/**
+* This method is deprecated in favor of using queryEndingAtValue:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+ * queryEndingAtPriority: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtPriority: will respond to events at nodes with a priority
+ * less than or equal to startPriority and with a name greater than or equal to childName
+ *
+ * @param endPriority The upper bound, inclusive, for the priority of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with priority less than or equal to endPriority
+ */
+- (FQuery *) queryEndingAtPriority:(id)endPriority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEndingAtValue:] instead")));
+
+
+/**
+* This method is deprecated in favor of using queryEndingAtValue:childKey:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+ * queryEndingAtPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtPriority:andChildName will respond to events at nodes with a priority
+ * less than endPriority, or equal to endPriority and with a name less than or equal to childName
+ *
+ * @param endPriority The upper bound, inclusive, for the priority of data visible to the returned FQuery
+ * @param childName The upper bound, inclusive, for the name of nodes with priority equal to endPriority
+ * @return An FQuery instance, limited to data with priority less than endPriority or equal to endPriority and with a name less than or equal to childName
+ */
+- (FQuery *) queryEndingAtPriority:(id)endPriority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEndingAtValue:childKey:] instead")));
+
+
+/**
+* This method is deprecated in favor of using queryEqualToValue:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+* queryEqualToPriority: is used to generate a reference to a limited view of the data at this location.
+* The FQuery instance returned by queryEqualToPriority: will respond to events at nodes with a priority equal to
+* supplied argument.
+*
+* @param priority The priority that the data returned by this FQuery will have
+* @return An Fquery instance, limited to data with the supplied priority.
+*/
+- (FQuery *) queryEqualToPriority:(id)priority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEqualToValue:] instead")));
+
+
+/**
+* This method is deprecated in favor of using queryEqualAtValue:childKey:. This can be used with queryOrderedByPriority
+* to query by priority.
+*
+* queryEqualToPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+* The FQuery instance returned by queryEqualToPriority:andChildName will respond to events at nodes with a priority
+* equal to the supplied argument with a name equal to childName. There will be at most one node that matches because
+* child names are unique.
+*
+* @param priority The priority that the data returned by this FQuery will have
+* @param childName The name of nodes with the right priority
+* @return An FQuery instance, limited to data with the supplied priority and the name.
+*/
+- (FQuery *) queryEqualToPriority:(id)priority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEqualToValue:childKey:] instead")));
+
+/**
+ * This method is deprecated in favor of using queryLimitedToFirst:limit or queryLimitedToLast:limit instead.
+ *
+ * queryLimitedToNumberOfChildren: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryLimitedToNumberOfChildren: will respond to events from at most limit child nodes.
+ *
+ * @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+ * @return An FQuery instance, limited to at most limit child nodes.
+ */
+- (FQuery *) queryLimitedToNumberOfChildren:(NSUInteger)limit __attribute__((deprecated("Use [FQuery queryLimitedToFirst:limit] or [FQuery queryLimitedToLast:limit] instead")));
+
+
+/**
+* queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location.
+* The FQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes.
+*
+* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+* @return An FQuery instance, limited to at most limit child nodes.
+*/
+- (FQuery *) queryLimitedToFirst:(NSUInteger)limit;
+
+
+/**
+* queryLimitedToLast: is used to generate a reference to a limited view of the data at this location.
+* The FQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes.
+*
+* @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+* @return An FQuery instance, limited to at most limit child nodes.
+*/
+- (FQuery *) queryLimitedToLast:(NSUInteger)limit;
+
+/**
+* queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of
+* a particular child key. This method is intended to be used in combination with queryStartingAtValue:,
+* queryEndingAtValue:, or queryEqualToValue:.
+*
+ * @param key The child key to use in ordering data visible to the returned FQuery
+ * @return An FQuery instance, ordered by the values of the specified child key.
+*/
+- (FQuery *) queryOrderedByChild:(NSString *)key;
+
+/**
+ * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key.
+ * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
+ * or queryEqualToValue:.
+ *
+ * @return An FQuery instance, ordered by child keys.
+ */
+- (FQuery *) queryOrderedByKey;
+
+/**
+ * queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value.
+ * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
+ * or queryEqualToValue:.
+ *
+ * @return An FQuery instance, ordered by child value.
+ */
+- (FQuery *) queryOrderedByValue;
+
+/**
+ * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child
+ * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
+ * or queryEqualToValue:.
+ *
+ * @return An FQuery instance, ordered by child priorities.
+ */
+- (FQuery *) queryOrderedByPriority;
+
+/**
+ * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value
+ * greater than or equal to startValue.
+ *
+ * @param startValue The lower bound, inclusive, for the value of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with value greater than or equal to startValue
+ */
+- (FQuery *) queryStartingAtValue:(id)startValue;
+
+/**
+ * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value
+ * greater than startValue, or equal to startValue and with a key greater than or equal to childKey.
+ *
+ * @param startValue The lower bound, inclusive, for the value of data visible to the returned FQuery
+ * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue
+ * @return An FQuery instance, limited to data with value greater than or equal to startValue
+ */
+- (FQuery *) queryStartingAtValue:(id)startValue childKey:(NSString *)childKey;
+
+/**
+ * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value
+ * less than or equal to endValue.
+ *
+ * @param endValue The upper bound, inclusive, for the value of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with value less than or equal to endValue
+ */
+- (FQuery *) queryEndingAtValue:(id)endValue;
+
+/**
+ * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value
+ * less than endValue, or equal to endValue and with a key less than or equal to childKey.
+ *
+ * @param endValue The upper bound, inclusive, for the value of data visible to the returned FQuery
+ * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue
+ * @return An FQuery instance, limited to data with value less than or equal to endValue
+ */
+- (FQuery *) queryEndingAtValue:(id)endValue childKey:(NSString *)childKey;
+
+/**
+ * queryEqualToValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal
+ * to the supplied argument.
+ *
+ * @param value The value that the data returned by this FQuery will have
+ * @return An Fquery instance, limited to data with the supplied value.
+ */
+- (FQuery *) queryEqualToValue:(id)value;
+
+/**
+ * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value
+ * equal to the supplied argument with a name equal to childKey. There will be at most one node that matches because
+ * child keys are unique.
+ *
+ * @param value The value that the data returned by this FQuery will have
+ * @param childKey The name of nodes with the right value
+ * @return An FQuery instance, limited to data with the supplied value and the key.
+ */
+- (FQuery *) queryEqualToValue:(id)value childKey:(NSString *)childKey;
+
+
+/** @name Properties */
+
+
+/**
+* Get a Firebase reference for the location of this query.
+*
+* @return A Firebase instance for the location of this query.
+*/
+@property (nonatomic, readonly, strong) Firebase* ref;
+
+@end
diff --git a/Pods/Firebase/FTransactionResult.h b/Pods/Firebase/FTransactionResult.h
new file mode 100644
index 0000000..a478f65
--- /dev/null
+++ b/Pods/Firebase/FTransactionResult.h
@@ -0,0 +1,53 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import
+#import "FMutableData.h"
+
+/**
+ * Used for runTransactionBlock:. An FTransactionResult instance is a container for the results of the transaction.
+ */
+@interface FTransactionResult : NSObject
+
+/**
+ * Used for runTransactionBlock:. Indicates that the new value should be saved at this location
+ *
+ * @param value An FMutableData instance containing the new value to be set
+ * @return An FTransactionResult instance that can be used as a return value from the block given to runTransactionBlock:
+ */
++ (FTransactionResult *) successWithValue:(FMutableData *)value;
+
+
+/**
+ * Used for runTransactionBlock:. Indicates that the current transaction should no longer proceed.
+ *
+ * @return An FTransactionResult instance that can be used as a return value from the block given to runTransactionBlock:
+ */
++ (FTransactionResult *) abort;
+
+@end
diff --git a/Pods/Firebase/Firebase.framework/Firebase b/Pods/Firebase/Firebase.framework/Firebase
new file mode 100644
index 0000000..6d95b57
Binary files /dev/null and b/Pods/Firebase/Firebase.framework/Firebase differ
diff --git a/Pods/Firebase/Firebase.h b/Pods/Firebase/Firebase.h
new file mode 100644
index 0000000..7938d04
--- /dev/null
+++ b/Pods/Firebase/Firebase.h
@@ -0,0 +1,1055 @@
+/*
+ * Firebase iOS Client Library
+ *
+ * Copyright © 2013 Firebase - All Rights Reserved
+ * https://www.firebase.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binaryform must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#import
+#import "FQuery.h"
+#import "FirebaseApp.h"
+#import "FDataSnapshot.h"
+#import "FMutableData.h"
+#import "FTransactionResult.h"
+#import "FAuthData.h"
+#import "FAuthType.h"
+#import "FirebaseServerValue.h"
+#import "FConfig.h"
+
+/**
+ * A Firebase reference represents a particular location in your Firebase
+ * and can be used for reading or writing data to that Firebase location.
+ *
+ * This class is the starting point for all Firebase operations. After you've
+ * initialized it with initWithUrl: you can use it
+ * to read data (ie. observeEventType:withBlock:), write data (ie. setValue:), and to create new
+ * Firebase references (ie. child:).
+ */
+@interface Firebase : FQuery
+
+
+/** @name Initializing a Firebase object */
+
+/**
+ * Initialize this Firebase reference with an absolute URL.
+ *
+ * @param url The Firebase URL (ie: https://SampleChat.firebaseIO-demo.com)
+ */
+- (id)initWithUrl:(NSString *)url;
+
+/** @name Getting references to children locations */
+
+/**
+ * Get a Firebase reference for the location at the specified relative path.
+ * The relative path can either be a simple child key (e.g. 'fred') or a
+ * deeper slash-separated path (e.g. 'fred/name/first').
+ *
+ * @param pathString A relative path from this location to the desired child location.
+ * @return A Firebase reference for the specified relative path.
+ */
+- (Firebase *) childByAppendingPath:(NSString *)pathString;
+
+
+/**
+ * childByAutoId generates a new child location using a unique key and returns a
+ * Firebase reference to it. This is useful when the children of a Firebase
+ * location represent a list of items.
+ *
+ * The unique key generated by childByAutoId: is prefixed with a client-generated
+ * timestamp so that the resulting list will be chronologically-sorted.
+ *
+ * @return A Firebase reference for the generated location.
+ */
+- (Firebase *) childByAutoId;
+
+
+/** @name Writing data */
+
+/*! Write data to this Firebase location.
+
+This will overwrite any data at this location and all child locations.
+
+Data types that can be set are:
+
+- NSString -- @"Hello World"
+- NSNumber (also includes boolean) -- @YES, @43, @4.333
+- NSDictionary -- @{@"key": @"value", @"nested": @{@"another": @"value"} }
+- NSArray
+
+The effect of the write will be visible immediately and the corresponding
+events will be triggered. Synchronization of the data to the Firebase
+servers will also be started.
+
+Passing null for the new value is equivalent to calling remove:;
+all data at this location or any child location will be deleted.
+
+Note that setValue: will remove any priority stored at this location, so if priority
+is meant to be preserved, you should use setValue:andPriority: instead.
+
+
+**Server Values** - Placeholder values you may write into Firebase as a value or priority
+that will automatically be populated by the Firebase Server.
+
+- kFirebaseServerValueTimestamp - The number of milliseconds since the Unix epoch
+
+
+@param value The value to be written.
+ */
+- (void) setValue:(id)value;
+
+
+#define kFirebaseServerValueTimestamp @{ @".sv": @"timestamp" }
+
+/**
+ * The same as setValue: with a block that gets triggered after the write operation has
+ * been committed to the Firebase servers.
+ *
+ * @param value The value to be written.
+ * @param block The block to be called after the write has been committed to the Firebase servers.
+ */
+- (void) setValue:(id)value withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/**
+ * The same as setValue: with an additional priority to be attached to the data being written.
+ * Priorities are used to order items.
+ *
+ * @param value The value to be written.
+ * @param priority The priority to be attached to that data.
+ */
+- (void) setValue:(id)value andPriority:(id)priority;
+
+
+/**
+ * The same as setValue:andPriority: with a block that gets triggered after the write operation has
+ * been committed to the Firebase servers.
+ *
+ * @param value The value to be written.
+ * @param priority The priority to be attached to that data.
+ * @param block The block to be called after the write has been committed to the Firebase servers.
+ */
+- (void) setValue:(id)value andPriority:(id)priority withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/**
+ * Remove the data at this Firebase location. Any data at child locations will also be deleted.
+ *
+ * The effect of the delete will be visible immediately and the corresponding events
+ * will be triggered. Synchronization of the delete to the Firebase servers will
+ * also be started.
+ *
+ * remove: is equivalent to calling setValue:nil
+ */
+- (void) removeValue;
+
+
+/**
+ * The same as remove: with a block that gets triggered after the remove operation has
+ * been committed to the Firebase servers.
+ *
+ * @param block The block to be called after the remove has been committed to the Firebase servers.
+ */
+- (void) removeValueWithCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+/**
+ * Set a priority for the data at this Firebase location.
+ * Priorities can be used to provide a custom ordering for the children at a location
+ * (if no priorities are specified, the children are ordered by key).
+ *
+ * You cannot set a priority on an empty location. For this reason
+ * setValue:andPriority: should be used when setting initial data with a specific priority
+ * and setPriority: should be used when updating the priority of existing data.
+ *
+ * Children are sorted based on this priority using the following rules:
+ *
+ * Children with no priority come first.
+ * Children with a number as their priority come next. They are sorted numerically by priority (small to large).
+ * Children with a string as their priority come last. They are sorted lexicographically by priority.
+ * Whenever two children have the same priority (including no priority), they are sorted by key. Numeric
+ * keys come first (sorted numerically), followed by the remaining keys (sorted lexicographically).
+ *
+ * Note that priorities are parsed and ordered as IEEE 754 double-precision floating-point numbers.
+ * Keys are always stored as strings and are treated as numbers only when they can be parsed as a
+ * 32-bit integer
+ *
+ * @param priority The priority to set at the specified location.
+ */
+- (void) setPriority:(id)priority;
+
+
+/**
+ * The same as setPriority: with a block block that is called once the priority has
+ * been committed to the Firebase servers.
+ *
+ * @param priority The priority to set at the specified location.
+ * @param block The block that is triggered after the priority has been written on the servers.
+ */
+- (void) setPriority:(id)priority withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+/**
+ * Update changes the values at the specified paths in the dictionary without overwriting other
+ * keys at this location.
+ *
+ * @param values A dictionary of the keys to change and their new values
+ */
+- (void) updateChildValues:(NSDictionary *)values;
+
+/**
+ * The same as update: with a block block that is called once the update has been committed to the
+ * Firebase servers
+ *
+ * @param values A dictionary of the keys to change and their new values
+ * @param block The block that is triggered after the update has been written on the Firebase servers
+ */
+- (void) updateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/** @name Attaching observers to read data */
+
+/**
+ * observeEventType:withBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot.
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block;
+
+
+/**
+ * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot
+ * and the previous child's key.
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block;
+
+
+/**
+ * observeEventType:withBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes.
+ *
+ * The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot.
+ * @param cancelBlock The block that should be called if this client no longer has permission to receive these events
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location.
+ * This is the primary way to read data from Firebase. Your block will be triggered
+ * for the initial data and again whenever the data changes. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * The cancelBlock will be called if you will no longer receive new events due to no longer having permission.
+ *
+ * Use removeObserverWithHandle: to stop receiving updates.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called with initial data and updates. It is passed the data as an FDataSnapshot
+ * and the previous child's key.
+ * @param cancelBlock The block that should be called if this client no longer has permission to receive these events
+ * @return A handle used to unregister this block later using removeObserverWithHandle:
+ */
+- (FirebaseHandle) observeEventType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot.
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot and the previous child's key.
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned.
+ *
+ * The cancelBlock will be called if you do not have permission to read data at this location.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot.
+ * @param cancelBlock The block that will be called if you don't have permission to access this data
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType withBlock:(void (^)(FDataSnapshot* snapshot))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+
+/**
+ * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FEventTypeChildAdded, FEventTypeChildMoved, and
+ * FEventTypeChildChanged events, your block will be passed the key of the previous node by priority order.
+ *
+ * The cancelBlock will be called if you do not have permission to read data at this location.
+ *
+ * @param eventType The type of event to listen for.
+ * @param block The block that should be called. It is passed the data as an FDataSnapshot and the previous child's key.
+ * @param cancelBlock The block that will be called if you don't have permission to access this data
+ */
+- (void) observeSingleEventOfType:(FEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FDataSnapshot* snapshot, NSString* prevKey))block withCancelBlock:(void (^)(NSError* error))cancelBlock;
+
+/** @name Detaching observers */
+
+/**
+ * Detach a block previously attached with observeEventType:withBlock:.
+ *
+ * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove.
+ */
+- (void) removeObserverWithHandle:(FirebaseHandle)handle;
+
+/**
+ * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and
+ * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept
+ * synced, it will not be evicted from the persistent disk cache.
+ *
+ * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization.
+ */
+- (void) keepSynced:(BOOL)keepSynced;
+
+
+/**
+ * Calling removeAllObservers does not remove any observers at child references.
+ * removeAllObservers must be called again for each child reference where a listener was established to remove the observers.
+ */
+- (void) removeAllObservers;
+
+/** @name Querying and limiting */
+
+
+/**
+ * This method is deprecated in favor of using queryStartingAtValue:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryStartingAtPriority: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtPriority: will respond to events at nodes with a priority
+ * greater than or equal to startPriority
+ *
+ * @param startPriority The lower bound, inclusive, for the priority of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with priority greater than or equal to startPriority
+ */
+- (FQuery *) queryStartingAtPriority:(id)startPriority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryStartingAtValue:] instead")));
+
+
+/**
+ * This method is deprecated in favor of using queryStartingAtValue:childKey:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryStartingAtPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtPriority:andChildName will respond to events at nodes with a priority
+ * greater than startPriority, or equal to startPriority and with a name greater than or equal to childName
+ *
+ * @param startPriority The lower bound, inclusive, for the priority of data visible to the returned FQuery
+ * @param childName The lower bound, inclusive, for the name of nodes with priority equal to startPriority
+ * @return An FQuery instance, limited to data with priority greater than or equal to startPriority
+ */
+- (FQuery *) queryStartingAtPriority:(id)startPriority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryStartingAtValue:childKey:] instead")));
+
+/**
+ * This method is deprecated in favor of using queryEndingAtValue:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryEndingAtPriority: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtPriority: will respond to events at nodes with a priority
+ * less than or equal to startPriority and with a name greater than or equal to childName
+ *
+ * @param endPriority The upper bound, inclusive, for the priority of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with priority less than or equal to endPriority
+ */
+- (FQuery *) queryEndingAtPriority:(id)endPriority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEndingAtValue:] instead")));
+
+
+/**
+ * This method is deprecated in favor of using queryEndingAtValue:childKey:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryEndingAtPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtPriority:andChildName will respond to events at nodes with a priority
+ * less than endPriority, or equal to endPriority and with a name less than or equal to childName
+ *
+ * @param endPriority The upper bound, inclusive, for the priority of data visible to the returned FQuery
+ * @param childName The upper bound, inclusive, for the name of nodes with priority equal to endPriority
+ * @return An FQuery instance, limited to data with priority less than endPriority or equal to endPriority and with a name less than or equal to childName
+ */
+- (FQuery *) queryEndingAtPriority:(id)endPriority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEndingAtValue:childKey:] instead")));
+
+
+/**
+ * This method is deprecated in favor of using queryEqualToValue:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryEqualToPriority: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToPriority: will respond to events at nodes with a priority equal to
+ * supplied argument.
+ *
+ * @param priority The priority that the data returned by this FQuery will have
+ * @return An Fquery instance, limited to data with the supplied priority.
+ */
+- (FQuery *) queryEqualToPriority:(id)priority __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEqualToValue:] instead")));
+
+
+/**
+ * This method is deprecated in favor of using queryEqualAtValue:childKey:. This can be used with queryOrderedByPriority
+ * to query by priority.
+ *
+ * queryEqualToPriority:andChildName: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToPriority:andChildName will respond to events at nodes with a priority
+ * equal to the supplied argument with a name equal to childName. There will be at most one node that matches because
+ * child names are unique.
+ *
+ * @param priority The priority that the data returned by this FQuery will have
+ * @param childName The name of nodes with the right priority
+ * @return An FQuery instance, limited to data with the supplied priority and the name.
+ */
+- (FQuery *) queryEqualToPriority:(id)priority andChildName:(NSString *)childName __attribute__((deprecated("Use [[FQuery queryOrderedByPriority] queryEqualToValue:childKey:] instead")));
+
+/**
+ * This method is deprecated in favor of using queryLimitedToFirst:limit or queryLimitedToLast:limit instead.
+ *
+ * queryLimitedToNumberOfChildren: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryLimitedToNumberOfChildren: will respond to events from at most limit child nodes.
+ *
+ * @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+ * @return An FQuery instance, limited to at most limit child nodes.
+ */
+- (FQuery *) queryLimitedToNumberOfChildren:(NSUInteger)limit __attribute__((deprecated("Use [FQuery queryLimitedToFirst:limit] or [FQuery queryLimitedToLast:limit] instead")));
+
+
+/**
+ * queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes.
+ *
+ * @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+ * @return An FQuery instance, limited to at most limit child nodes.
+ */
+- (FQuery *) queryLimitedToFirst:(NSUInteger)limit;
+
+
+/**
+ * queryLimitedToLast: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes.
+ *
+ * @param limit The upper bound, inclusive, for the number of child nodes to receive events for
+ * @return An FQuery instance, limited to at most limit child nodes.
+ */
+- (FQuery *) queryLimitedToLast:(NSUInteger)limit;
+
+/**
+ * queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of
+ * a particular child key. This method is intended to be used in combination with queryStartingAtValue:,
+ * queryEndingAtValue:, or queryEqualToValue:.
+ *
+ * @param key The child key to use in ordering data visible to the returned FQuery
+ * @return An FQuery instance, ordered by the values of the specified child key.
+ */
+- (FQuery *) queryOrderedByChild:(NSString *)key;
+
+/**
+ * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key.
+ * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
+ * or queryEqualToValue:.
+ *
+ * @return An FQuery instance, ordered by child keys.
+ */
+- (FQuery *) queryOrderedByKey;
+
+/**
+ * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child
+ * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:,
+ * or queryEqualToValue:.
+ *
+ * @return An FQuery instance, ordered by child priorities.
+ */
+- (FQuery *) queryOrderedByPriority;
+
+/**
+ * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value
+ * greater than or equal to startValue.
+ *
+ * @param startValue The lower bound, inclusive, for the value of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with value greater than or equal to startValue
+ */
+- (FQuery *) queryStartingAtValue:(id)startValue;
+
+/**
+ * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value
+ * greater than startValue, or equal to startValue and with a key greater than or equal to childKey.
+ *
+ * @param startValue The lower bound, inclusive, for the value of data visible to the returned FQuery
+ * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue
+ * @return An FQuery instance, limited to data with value greater than or equal to startValue
+ */
+- (FQuery *) queryStartingAtValue:(id)startValue childKey:(NSString *)childKey;
+
+/**
+ * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value
+ * less than or equal to endValue.
+ *
+ * @param endValue The upper bound, inclusive, for the value of data visible to the returned FQuery
+ * @return An FQuery instance, limited to data with value less than or equal to endValue
+ */
+- (FQuery *) queryEndingAtValue:(id)endValue;
+
+/**
+ * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value
+ * less than endValue, or equal to endValue and with a key less than or equal to childKey.
+ *
+ * @param endValue The upper bound, inclusive, for the value of data visible to the returned FQuery
+ * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue
+ * @return An FQuery instance, limited to data with value less than or equal to endValue
+ */
+- (FQuery *) queryEndingAtValue:(id)endValue childKey:(NSString *)childKey;
+
+/**
+ * queryEqualToValue: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal
+ * to the supplied argument.
+ *
+ * @param value The value that the data returned by this FQuery will have
+ * @return An Fquery instance, limited to data with the supplied value.
+ */
+- (FQuery *) queryEqualToValue:(id)value;
+
+/**
+ * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location.
+ * The FQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value
+ * equal to the supplied argument with a key equal to childKey. There will be at most one node that matches because
+ * child keys are unique.
+ *
+ * @param value The value that the data returned by this FQuery will have
+ * @param childKey The key of nodes with the right value
+ * @return An FQuery instance, limited to data with the supplied value and the key.
+ */
+- (FQuery *) queryEqualToValue:(id)value childKey:(NSString *)childKey;
+
+/** @name Managing presence */
+
+/**
+ * Ensure the data at this location is set to the specified value when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ * onDisconnectSetValue: is especially useful for implementing "presence" systems,
+ * where a value should be changed or cleared when a user disconnects
+ * so that he appears "offline" to other users.
+ *
+ * @param value The value to be set after the connection is lost.
+ */
+- (void) onDisconnectSetValue:(id)value;
+
+
+/**
+ * Ensure the data at this location is set to the specified value when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ * The completion block will be triggered when the operation has been successfully queued up on the Firebase servers
+ *
+ * @param value The value to be set after the connection is lost.
+ * @param block Block to be triggered when the operation has been queued up on the Firebase servers
+ */
+- (void) onDisconnectSetValue:(id)value withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/**
+ * Ensure the data at this location is set to the specified value and priority when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ * @param value The value to be set after the connection is lost.
+ * @param priority The priority to be set after the connection is lost.
+ */
+- (void) onDisconnectSetValue:(id)value andPriority:(id)priority;
+
+
+/**
+ * Ensure the data at this location is set to the specified value and priority when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ * The completion block will be triggered when the operation has been successfully queued up on the Firebase servers
+ *
+ * @param value The value to be set after the connection is lost.
+ * @param priority The priority to be set after the connection is lost.
+ * @param block Block to be triggered when the operation has been queued up on the Firebase servers
+ */
+- (void) onDisconnectSetValue:(id)value andPriority:(id)priority withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/**
+ * Ensure the data at this location is removed when
+ * the client is disconnected (due to closing the app, navigating
+ * to a new page, or network issues).
+ *
+ * onDisconnectRemoveValue is especially useful for implementing "presence" systems.
+ */
+- (void) onDisconnectRemoveValue;
+
+
+/**
+ * Ensure the data at this location is removed when
+ * the client is disconnected (due to closing the app, navigating
+ * to a new page, or network issues).
+ *
+ * onDisconnectRemoveValueWithCompletionBlock: is especially useful for implementing "presence" systems.
+ *
+ * @param block Block to be triggered when the operation has been queued up on the Firebase servers
+ */
+- (void) onDisconnectRemoveValueWithCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+
+/**
+ * Ensure the data has the specified child values updated when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ *
+ * @param values A dictionary of child node keys and the values to set them to after the connection is lost.
+ */
+- (void) onDisconnectUpdateChildValues:(NSDictionary *)values;
+
+
+/**
+ * Ensure the data has the specified child values updated when
+ * the client is disconnected (due to closing the browser, navigating
+ * to a new page, or network issues).
+ *
+ *
+ * @param values A dictionary of child node keys and the values to set them to after the connection is lost.
+ * @param block A block that will be called once the operation has been queued up on the Firebase servers
+ */
+- (void) onDisconnectUpdateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/**
+ * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:,
+ * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the
+ * connection is lost, call cancelDisconnectOperations:
+ */
+- (void) cancelDisconnectOperations;
+
+
+/**
+ * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:,
+ * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the
+ * connection is lost, call cancelDisconnectOperations:
+ *
+ * @param block A block that will be triggered once the Firebase servers have acknowledged the cancel request.
+ */
+- (void) cancelDisconnectOperationsWithCompletionBlock:(void (^)(NSError* error, Firebase* ref))block;
+
+
+/** @name Reading and observing authentication data */
+
+/**
+* Get the authentication data of the current user.
+*
+* @return Authentication data of the current user.
+*/
+@property (nonatomic, strong, readonly) FAuthData *authData;
+
+
+/**
+* Observer block will be triggered whenever a user gets authenticated or logged out.
+*
+* Authentication data is persisted across app restarts. If your have an old authentication, Firebase will attempt to
+* resume your old session. This approach does not wait for a server roundtrip. Rather, it inspects the
+* contents of the persisted JWT and assumes that the Firebase secret used to generate the token has not been revoked.
+*
+* In the event that the Firebase secret used to generate the token has been revoked, observers will likely see one
+* flicker / rapid flip-flop of authentication state once the server rejects the token.
+*
+* Use removeAuthEventObserverWithHandle: to stop receiving updates.
+*
+* @param block The block that should be called with initial authentication data and future updates
+* @return A handle used to unregister this block later with removeAuthEventObserverWithHandle:
+*/
+- (FirebaseHandle) observeAuthEventWithBlock:(void (^)(FAuthData *authData))block;
+
+
+/**
+* Detach a block previously attached with observeAuthEventWithBlock:.
+*
+* @param handle The handle returned by the call to observeAuthEventWithBlock: which we are trying to remove.
+*/
+- (void) removeAuthEventObserverWithHandle:(FirebaseHandle)handle;
+
+/** @name User creation and modification */
+
+/**
+* Used to create a new user account with the given email and password combo. The results will be passed to the given block.
+* Note that this method will not log the new user in.
+*
+* @param email The email for the account to be created
+* @param password The password for the account to be created
+* @param block The block to be called with the results of the operation
+*/
+- (void) createUser:(NSString *)email password:(NSString *)password withCompletionBlock:(void (^)(NSError *error))block;
+
+/**
+ * Used to create a new user account with the given email and password combo. The results will be passed
+ * to the given block. Note that this method will not log the new user in. On success, invokes the result
+ * block with an dictionary of user data, including the user id.
+ *
+ * @param email The email for the account to be created
+ * @param password The password for the account to be created
+ * @param block The block to be called with the results of the operation
+ */
+- (void) createUser:(NSString *)email password:(NSString *)password withValueCompletionBlock:(void (^)(NSError *error, NSDictionary *result))block;
+
+/**
+* Remove a user account with the given email and password.
+*
+* @param email The email of the account to be removed
+* @param password The password for the account to be removed
+* @param block A block to receive the results of the operation
+*/
+- (void) removeUser:(NSString *)email password:(NSString *)password withCompletionBlock:(void (^)(NSError *error))block;
+
+
+/**
+* Attempts to change the password for the account with the given credentials to the new password given. Results are reported to the supplied block.
+*
+* @param email The email for the account to be changed
+* @param oldPassword The old password for the account to be changed
+* @param newPassword The desired newPassword for the account
+* @param block A block to receive the results of the operation
+*/
+- (void) changePasswordForUser:(NSString *)email fromOld:(NSString *)oldPassword toNew:(NSString *)newPassword withCompletionBlock:(void (^)(NSError *error))block;
+
+
+/**
+ * Attempts to change the email for the account with the given credentials to the new email given. Results are reported to the supplied block.
+ *
+ * @param email The email for the account to be changed
+ * @param password The password for the account to be changed
+ * @param newEmail The desired newEmail for the account
+ * @param block A block to receive the results of the operation
+ */
+- (void) changeEmailForUser:(NSString *)email password:(NSString *)password toNewEmail:(NSString *)newEmail withCompletionBlock:(void (^)(NSError *error))block;
+
+
+/**
+* Send a password reset email to the owner of the account with the given email. Results are reported to the supplied block.
+*
+* @param email The email of the account to be removed
+* @param block A block to receive the results of the operation
+*/
+- (void) resetPasswordForUser:(NSString *)email withCompletionBlock:(void (^)(NSError* error))block;
+
+/** @name Authenticating */
+
+/**
+* Attempts to log the user in anonymously. The block will receive the results of the attempt.
+*
+* @param block A block to receive the results of the authentication attempt.
+*/
+- (void) authAnonymouslyWithCompletionBlock:(void (^)(NSError *error, FAuthData *authData))block;
+
+/**
+* Attempts to authenticate to Firebase with the given credentials. The block will receive the results of the attempt.
+*
+* @param email The email of the account
+* @param password The password for the account
+* @param block A block to receive the results of the authentication attempt
+*/
+- (void) authUser:(NSString *)email password:(NSString *)password withCompletionBlock:(void (^)(NSError *error, FAuthData *authData))block;
+
+/**
+* Authenticate access to this Firebase using the provided credentials.
+*
+* The completion block will be called with the results of the authenticated attempt. Unlike
+* authWithCredential:withCompletionBlock:withCancelBlock:, no block will be called when the credentials become invalid.
+*
+* Instead, please use observeAuthEventWithBlock: to observe if a user gets logged out.
+*
+* @param token The Firebase authentication JWT generated by a secure code on a remote server.
+* @param block This block will be called with the results of the authentication attempt
+*/
+- (void) authWithCustomToken:(NSString *)token withCompletionBlock:(void (^)(NSError *error, FAuthData *authData))block;
+
+/**
+* Authenticate to Firebase with an OAuth token from a provider.
+*
+* This method works with current OAuth 2.0 providers such as Facebook, Google+, and Github.
+*
+* For other providers that Firebase supports which require additional parameters for login, such as Twitter, please use authWithOAuthProvider:parameters:withCompletionBlock:.
+*
+* @param provider The provider, all lower case with no spaces.
+* @param oauthToken The OAuth Token to authenticate with the provider
+* @param block A block to receive the results of the authentication attempt
+*/
+- (void) authWithOAuthProvider:(NSString *)provider token:(NSString *)oauthToken withCompletionBlock:(void (^) (NSError *error, FAuthData *authData))block;
+
+/**
+* Authenticate to Firebase with an OAuth token from a provider.
+*
+* This method is for OAuth providers that require extra parameters when authentication with the server, such as Twitter.
+* The OAuth token should be included as a parameter.
+*
+* @param provider The provider, all lowercase with no spaces.
+* @param parameters The parameters necessary to authenticate with the provider
+* @param block A block to receive the results of the authentication attempt
+*/
+- (void) authWithOAuthProvider:(NSString *)provider parameters:(NSDictionary *)parameters withCompletionBlock:(void (^) (NSError *error, FAuthData *authData))block;
+
+/**
+* Make a reverse OAuth Request to a provider.
+*
+* This method is for OAuth providers that require a reverse request be made first. The json output of this block
+*
+* @param provider The provider, all lowercase with no spaces.
+* @param block The block to receive the results of the reverse OAuth request.
+*/
+- (void) makeReverseOAuthRequestTo:(NSString *)provider withCompletionBlock:(void (^)(NSError *error, NSDictionary *json))block;
+
+/**
+* Removes any credentials associated with this Firebase.
+*/
+- (void) unauth;
+
+/**
+* This method is deprecated. Use authWithCustomToken:withCompletionBlock: instead.
+*
+* Authenticate access to this Firebase using the provided credentials. The completion block will be called with
+* the results of the authenticated attempt, and the cancelBlock will be called if the credentials become invalid
+* at some point after authentication has succeeded.
+*
+* @param credential The Firebase authentication JWT generated by a secure code on a remote server.
+* @param block This block will be called with the results of the authentication attempt
+* @param cancelBlock This block will be called if at any time in the future the credentials become invalid
+*/
+- (void) authWithCredential:(NSString *)credential withCompletionBlock:(void (^) (NSError* error, id data))block withCancelBlock:(void (^)(NSError* error))cancelBlock __attribute__((deprecated("Use authWithCustomToken:withCompletionblock: instead")));
+
+/**
+* This method is deprecated. Use unauth: instead.
+*
+* Removes any credentials associated with this Firebase. The callback block will be triggered after this operation
+* has been acknowledged by the Firebase servers.
+*
+* @param block This block will be called once the unauth has completed.
+*/
+- (void) unauthWithCompletionBlock:(void (^)(NSError* error))block __attribute__((deprecated("Use unauth: instead")));
+
+
+/** @name Manual Connection Management */
+
+/**
+ * Manually disconnect the Firebase client from the server and disable automatic reconnection.
+ *
+ * The Firebase client automatically maintains a persistent connection to the Firebase server,
+ * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( )
+ * and goOnline( ) methods may be used to manually control the client connection in cases where
+ * a persistent connection is undesirable.
+ *
+ * While offline, the Firebase client will no longer receive data updates from the server. However,
+ * all Firebase operations performed locally will continue to immediately fire events, allowing
+ * your application to continue behaving normally. Additionally, each operation performed locally
+ * will automatically be queued and retried upon reconnection to the Firebase server.
+ *
+ * To reconnect to the Firebase server and begin receiving remote events, see goOnline( ).
+ * Once the connection is reestablished, the Firebase client will transmit the appropriate data
+ * and fire the appropriate events so that your client "catches up" automatically.
+ *
+ * Note: Invoking this method will impact all Firebase connections.
+ */
++ (void) goOffline;
+
+/**
+ * Manually reestablish a connection to the Firebase server and enable automatic reconnection.
+ *
+ * The Firebase client automatically maintains a persistent connection to the Firebase server,
+ * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( )
+ * and goOnline( ) methods may be used to manually control the client connection in cases where
+ * a persistent connection is undesirable.
+ *
+ * This method should be used after invoking goOffline( ) to disable the active connection.
+ * Once reconnected, the Firebase client will automatically transmit the proper data and fire
+ * the appropriate events so that your client "catches up" automatically.
+ *
+ * To disconnect from the Firebase server, see goOffline( ).
+ *
+ * Note: Invoking this method will impact all Firebase connections.
+ */
++ (void) goOnline;
+
+
+/** @name Transactions */
+
+/**
+ * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with an FMutableData
+ * instance that contains the current data at this location. Your block should update this data to the value you
+ * wish to write to this location, and then return an instance of FTransactionResult with the new data.
+ *
+ * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
+ * again with the latest data from the server.
+ *
+ * When your block is run, you may decide to abort the transaction by return [FTransactionResult abort].
+ *
+ * @param block This block receives the current data at this location and must return an instance of FTransactionResult
+ */
+- (void) runTransactionBlock:(FTransactionResult* (^) (FMutableData* currentData))block;
+
+
+/**
+ * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with an FMutableData
+ * instance that contains the current data at this location. Your block should update this data to the value you
+ * wish to write to this location, and then return an instance of FTransactionResult with the new data.
+ *
+ * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
+ * again with the latest data from the server.
+ *
+ * When your block is run, you may decide to abort the transaction by return [FTransactionResult abort].
+ *
+ * @param block This block receives the current data at this location and must return an instance of FTransactionResult
+ * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is.
+ */
+- (void) runTransactionBlock:(FTransactionResult* (^) (FMutableData* currentData))block andCompletionBlock:(void (^) (NSError* error, BOOL committed, FDataSnapshot* snapshot))completionBlock;
+
+
+
+/**
+ * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with an FMutableData
+ * instance that contains the current data at this location. Your block should update this data to the value you
+ * wish to write to this location, and then return an instance of FTransactionResult with the new data.
+ *
+ * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run
+ * again with the latest data from the server.
+ *
+ * When your block is run, you may decide to abort the transaction by return [FTransactionResult abort].
+ *
+ * Since your block may be run multiple times, this client could see several immediate states that don't exist on the server. You can suppress those immediate states until the server confirms the final state of the transaction.
+ *
+ * @param block This block receives the current data at this location and must return an instance of FTransactionResult
+ * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is.
+ * @param localEvents Set this to NO to suppress events raised for intermediate states, and only get events based on the final state of the transaction.
+ */
+- (void) runTransactionBlock:(FTransactionResult* (^) (FMutableData* currentData))block andCompletionBlock:(void (^) (NSError* error, BOOL committed, FDataSnapshot* snapshot))completionBlock withLocalEvents:(BOOL)localEvents;
+
+
+/** @name Retrieving String Representation */
+
+/**
+ * Gets the absolute URL of this Firebase location.
+ *
+ * @return The absolute URL of the referenced Firebase location.
+ */
+- (NSString *) description;
+
+/** @name Properties */
+
+/**
+ * Get a Firebase reference for the parent location.
+ * If this instance refers to the root of your Firebase, it has no parent,
+ * and therefore parent( ) will return null.
+ *
+ * @return A Firebase reference for the parent location.
+ */
+@property (strong, readonly, nonatomic) Firebase* parent;
+
+
+/**
+ * Get a Firebase reference for the root location
+ *
+ * @return A new Firebase reference to root location.
+ */
+@property (strong, readonly, nonatomic) Firebase* root;
+
+
+/**
+ * Gets last token in a Firebase location (e.g. 'fred' in https://SampleChat.firebaseIO-demo.com/users/fred)
+ *
+ * @return The key of the location this reference points to.
+ */
+@property (strong, readonly, nonatomic) NSString* key;
+
+/**
+ * Gets the FirebaseApp instance associated with this reference.
+ *
+ * @return The FirebaseApp object for this reference.
+ */
+@property (strong, readonly, nonatomic) FirebaseApp *app;
+
+
+/** @name Global configuration and settings */
+
+/** Set the default dispatch queue for event blocks.
+ *
+ * @param queue The queue to set as the default for running blocks for all Firebase event types.
+ * @deprecated This method is deprecated
+ * @note Please use [Firebase defaultConfig].callbackQueue instead
+*/
++ (void) setDispatchQueue:(dispatch_queue_t)queue __attribute__((deprecated));
+
+/** Retrieve the Firebase SDK version. */
++ (NSString *) sdkVersion;
+
++ (void) setLoggingEnabled:(BOOL)enabled;
+
+/**
+ * Returns the default config object, used for configuring Firebase client behavior.
+ *
+ * This can be modified until you create your first `Firebase` instance.
+ */
++ (FConfig *)defaultConfig;
+
+/**
+ * @deprecated This method is deprecated
+ * @note Please enable persistence by setting [Firebase defaultConfig].persistenceEnabled = YES instead.
+ * @param option Option to set.
+ * @param value Value to set.
+ */
++ (void) setOption:(NSString*)option to:(id)value __attribute__((deprecated));
+@end
diff --git a/Pods/Firebase/FirebaseApp.h b/Pods/Firebase/FirebaseApp.h
new file mode 100644
index 0000000..b909cee
--- /dev/null
+++ b/Pods/Firebase/FirebaseApp.h
@@ -0,0 +1,34 @@
+#import
+
+/**
+ * All Firebase references to the same database share a connection, persistent cache, etc. FirebaseApp
+ * represents this shared state and can be accessed from any reference via its `app` property.
+ * It has methods for managing your Firebase connection, etc.
+ *
+ * There is a one-to-one relationship between a FirebaseApp instance and a connection to Firebase.
+ */
+@interface FirebaseApp : NSObject
+
+/**
+ * The Firebase client automatically queues writes and sends them to the server at the earliest opportunity,
+ * depending on network connectivity. In some cases (e.g. offline usage) there may be a large number of writes
+ * waiting to be sent. Calling this method will purge all outstanding writes so they are abandoned.
+ *
+ * All writes will be purged, including transactions and {@link Firebase#onDisconnect} writes. The writes will
+ * be rolled back locally, perhaps triggering events for affected event listeners, and the client will not
+ * (re-)send them to the Firebase backend.
+ */
+- (void)purgeOutstandingWrites;
+
+
+/**
+ * Shuts down our connection to the Firebase backend until goOnline is called.
+ */
+- (void)goOffline;
+
+/**
+ * Resumes our connection to the Firebase backend after a previous goOffline call.
+ */
+- (void)goOnline;
+
+@end
diff --git a/Pods/Firebase/FirebaseServerValue.h b/Pods/Firebase/FirebaseServerValue.h
new file mode 100644
index 0000000..329ef11
--- /dev/null
+++ b/Pods/Firebase/FirebaseServerValue.h
@@ -0,0 +1,5 @@
+@interface FirebaseServerValue : NSObject
+
++ (NSDictionary *) timestamp;
+
+@end
\ No newline at end of file
diff --git a/Pods/Firebase/libFirebaseStatic.a b/Pods/Firebase/libFirebaseStatic.a
new file mode 100644
index 0000000..6d95b57
Binary files /dev/null and b/Pods/Firebase/libFirebaseStatic.a differ
diff --git a/Pods/Headers/Private/Firebase/FAuthData.h b/Pods/Headers/Private/Firebase/FAuthData.h
new file mode 120000
index 0000000..7489b45
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FAuthData.h
@@ -0,0 +1 @@
+../../../Firebase/FAuthData.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FAuthType.h b/Pods/Headers/Private/Firebase/FAuthType.h
new file mode 120000
index 0000000..502e35b
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FAuthType.h
@@ -0,0 +1 @@
+../../../Firebase/FAuthType.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FConfig.h b/Pods/Headers/Private/Firebase/FConfig.h
new file mode 120000
index 0000000..763c99a
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FConfig.h
@@ -0,0 +1 @@
+../../../Firebase/FConfig.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FDataSnapshot.h b/Pods/Headers/Private/Firebase/FDataSnapshot.h
new file mode 120000
index 0000000..8d3d769
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FDataSnapshot.h
@@ -0,0 +1 @@
+../../../Firebase/FDataSnapshot.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FEventType.h b/Pods/Headers/Private/Firebase/FEventType.h
new file mode 120000
index 0000000..4339807
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FEventType.h
@@ -0,0 +1 @@
+../../../Firebase/FEventType.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FMutableData.h b/Pods/Headers/Private/Firebase/FMutableData.h
new file mode 120000
index 0000000..56ea28f
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FMutableData.h
@@ -0,0 +1 @@
+../../../Firebase/FMutableData.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FQuery.h b/Pods/Headers/Private/Firebase/FQuery.h
new file mode 120000
index 0000000..f1006c6
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FQuery.h
@@ -0,0 +1 @@
+../../../Firebase/FQuery.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FTransactionResult.h b/Pods/Headers/Private/Firebase/FTransactionResult.h
new file mode 120000
index 0000000..dd01b82
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FTransactionResult.h
@@ -0,0 +1 @@
+../../../Firebase/FTransactionResult.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/Firebase.h b/Pods/Headers/Private/Firebase/Firebase.h
new file mode 120000
index 0000000..a9b6765
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/Firebase.h
@@ -0,0 +1 @@
+../../../Firebase/Firebase.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FirebaseApp.h b/Pods/Headers/Private/Firebase/FirebaseApp.h
new file mode 120000
index 0000000..af4c17e
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FirebaseApp.h
@@ -0,0 +1 @@
+../../../Firebase/FirebaseApp.h
\ No newline at end of file
diff --git a/Pods/Headers/Private/Firebase/FirebaseServerValue.h b/Pods/Headers/Private/Firebase/FirebaseServerValue.h
new file mode 120000
index 0000000..c0392db
--- /dev/null
+++ b/Pods/Headers/Private/Firebase/FirebaseServerValue.h
@@ -0,0 +1 @@
+../../../Firebase/FirebaseServerValue.h
\ No newline at end of file
diff --git a/Pods/Local Podspecs/SwiftyJSON.podspec.json b/Pods/Local Podspecs/SwiftyJSON.podspec.json
new file mode 100644
index 0000000..358633d
--- /dev/null
+++ b/Pods/Local Podspecs/SwiftyJSON.podspec.json
@@ -0,0 +1,23 @@
+{
+ "name": "SwiftyJSON",
+ "version": "2.3.0",
+ "summary": "SwiftyJSON makes it easy to deal with JSON data in Swift",
+ "homepage": "https://github.com/SwiftyJSON/SwiftyJSON",
+ "license": {
+ "type": "MIT"
+ },
+ "authors": {
+ "lingoer": "lingoerer@gmail.com",
+ "tangplin": "tangplin@gmail.com"
+ },
+ "requires_arc": true,
+ "platforms": {
+ "osx": "10.9",
+ "ios": "8.0"
+ },
+ "source": {
+ "git": "https://github.com/SwiftyJSON/SwiftyJSON.git",
+ "tag": "2.3.0"
+ },
+ "source_files": "Source/*.swift"
+}
diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock
new file mode 100644
index 0000000..e6f3572
--- /dev/null
+++ b/Pods/Manifest.lock
@@ -0,0 +1,28 @@
+PODS:
+ - Alamofire (2.0.2)
+ - Firebase (2.4.2)
+ - OAuthSwift (0.4.6)
+ - SwiftyJSON (2.3.0)
+
+DEPENDENCIES:
+ - Alamofire (= 2.0.2)
+ - Firebase (>= 2.4.1)
+ - OAuthSwift (~> 0.4.6)
+ - SwiftyJSON (from `https://github.com/SwiftyJSON/SwiftyJSON.git`)
+
+EXTERNAL SOURCES:
+ SwiftyJSON:
+ :git: https://github.com/SwiftyJSON/SwiftyJSON.git
+
+CHECKOUT OPTIONS:
+ SwiftyJSON:
+ :commit: 3b5d0d4e0c19173b1bf0dc823bde25ad870f70c0
+ :git: https://github.com/SwiftyJSON/SwiftyJSON.git
+
+SPEC CHECKSUMS:
+ Alamofire: 8edbab00802a752bb5240cc2abe70e7e881488ad
+ Firebase: 5e898ed5012c81d28ca5fae1113c6b61a172bc6d
+ OAuthSwift: 8c738cc56c942a541f5c6d0362a892cb149d10b1
+ SwiftyJSON: 8d6b61a70277ef2a5d710d372e06e7e2d87fb9e4
+
+COCOAPODS: 0.38.2
diff --git a/Pods/OAuthSwift/LICENSE b/Pods/OAuthSwift/LICENSE
new file mode 100644
index 0000000..fa84148
--- /dev/null
+++ b/Pods/OAuthSwift/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Dongri Jin
+
+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/Pods/OAuthSwift/OAuthSwift/Dictionary+OAuthSwift.swift b/Pods/OAuthSwift/OAuthSwift/Dictionary+OAuthSwift.swift
new file mode 100755
index 0000000..63986ac
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/Dictionary+OAuthSwift.swift
@@ -0,0 +1,62 @@
+//
+// Dictionary+OAuthSwift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/21/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+extension Dictionary {
+
+ func join(other: Dictionary) -> Dictionary {
+ var joinedDictionary = Dictionary()
+
+ for (key, value) in self {
+ joinedDictionary.updateValue(value, forKey: key)
+ }
+
+ for (key, value) in other {
+ joinedDictionary.updateValue(value, forKey: key)
+ }
+
+ return joinedDictionary
+ }
+
+ func filter(predicate: (key: Key, value: Value) -> Bool) -> Dictionary {
+ var filteredDictionary = Dictionary()
+
+ for (key, value) in self {
+ if predicate(key: key, value: value) {
+ filteredDictionary.updateValue(value, forKey: key)
+ }
+ }
+
+ return filteredDictionary
+ }
+
+ func urlEncodedQueryStringWithEncoding(encoding: NSStringEncoding) -> String {
+ var parts = [String]()
+
+ for (key, value) in self {
+ let keyString = "\(key)".urlEncodedStringWithEncoding(encoding)
+ let valueString = "\(value)".urlEncodedStringWithEncoding(encoding)
+ let query = "\(keyString)=\(valueString)" as String
+ parts.append(query)
+ }
+
+ return parts.joinWithSeparator("&") as String
+ }
+
+ mutating func merge(dictionaries: Dictionary...) {
+ for dict in dictionaries {
+ for (key, value) in dict {
+ self.updateValue(value as! Value, forKey: key as! Key)
+ }
+ }
+ }
+}
+
+public func += (inout left: [K : V], right: [K : V]) { left.merge(right) }
+public func + (left: [K : V], right: [K : V]) -> [K : V] { return left.join(right) }
diff --git a/Pods/OAuthSwift/OAuthSwift/HMAC.swift b/Pods/OAuthSwift/OAuthSwift/HMAC.swift
new file mode 100644
index 0000000..c623167
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/HMAC.swift
@@ -0,0 +1,47 @@
+//
+// HMAC.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 1/28/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+
+import Foundation
+
+public class HMAC {
+
+ let key:[UInt8] = []
+
+ class internal func sha1(key key: NSData, message: NSData) -> NSData? {
+ var key = key.bytes()
+ let message = message.bytes()
+
+ // key
+ if (key.count > 64) {
+ key = SHA1(NSData.withBytes(key)).calculate().bytes()
+ }
+
+ if (key.count < 64) {
+ key = key + [UInt8](count: 64 - key.count, repeatedValue: 0)
+ }
+
+ //
+ var opad = [UInt8](count: 64, repeatedValue: 0x5c)
+ for (idx, _) in key.enumerate() {
+ opad[idx] = key[idx] ^ opad[idx]
+ }
+ var ipad = [UInt8](count: 64, repeatedValue: 0x36)
+ for (idx, _) in key.enumerate() {
+ ipad[idx] = key[idx] ^ ipad[idx]
+ }
+
+ let ipadAndMessageHash = SHA1(NSData.withBytes(ipad + message)).calculate().bytes()
+ let finalHash = SHA1(NSData.withBytes(opad + ipadAndMessageHash)).calculate().bytes()
+ let mac = finalHash
+
+ return NSData(bytes: mac, length: mac.count)
+
+ }
+
+}
\ No newline at end of file
diff --git a/Pods/OAuthSwift/OAuthSwift/Int+OAuthSwift.swift b/Pods/OAuthSwift/OAuthSwift/Int+OAuthSwift.swift
new file mode 100644
index 0000000..edc46d8
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/Int+OAuthSwift.swift
@@ -0,0 +1,33 @@
+//
+// Int+OAuthSwift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 1/28/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+extension Int {
+ public func bytes(totalBytes: Int = sizeof(Int)) -> [UInt8] {
+ return arrayOfBytes(self, length: totalBytes)
+ }
+}
+
+func arrayOfBytes(value:T, length:Int? = nil) -> [UInt8] {
+ let totalBytes = length ?? (sizeofValue(value) * 8)
+
+ let valuePointer = UnsafeMutablePointer.alloc(1)
+ valuePointer.memory = value
+
+ let bytesPointer = UnsafeMutablePointer(valuePointer)
+ var bytes = [UInt8](count: totalBytes, repeatedValue: 0)
+ for j in 0.. [UInt8] {
+ let count = self.length / sizeof(UInt8)
+ var bytesArray = [UInt8](count: count, repeatedValue: 0)
+ self.getBytes(&bytesArray, length:count * sizeof(UInt8))
+ return bytesArray
+ }
+
+ class public func withBytes(bytes: [UInt8]) -> NSData {
+ return NSData(bytes: bytes, length: bytes.count)
+ }
+}
+
diff --git a/Pods/OAuthSwift/OAuthSwift/NSURL+OAuthSwift.swift b/Pods/OAuthSwift/OAuthSwift/NSURL+OAuthSwift.swift
new file mode 100755
index 0000000..da39f16
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/NSURL+OAuthSwift.swift
@@ -0,0 +1,30 @@
+//
+// NSURL+OAuthSwift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/21/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+
+extension NSURL {
+
+ func URLByAppendingQueryString(queryString: String) -> NSURL {
+ if queryString.utf16.count == 0 {
+ return self
+ }
+
+ var absoluteURLString = self.absoluteString
+
+ if absoluteURLString.hasSuffix("?") {
+ absoluteURLString = (absoluteURLString as NSString).substringToIndex(absoluteURLString.utf16.count - 1)
+ }
+
+ let URLString = absoluteURLString + (absoluteURLString.rangeOfString("?") != nil ? "&" : "?") + queryString
+
+ return NSURL(string: URLString)!
+ }
+
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuth1Swift.swift b/Pods/OAuthSwift/OAuthSwift/OAuth1Swift.swift
new file mode 100644
index 0000000..2c05d06
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuth1Swift.swift
@@ -0,0 +1,133 @@
+//
+// OAuth1Swift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/22/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+// OAuthSwift errors
+public let OAuthSwiftErrorDomain = "oauthswift.error"
+
+public class OAuth1Swift: NSObject {
+
+ public var client: OAuthSwiftClient
+
+ public var authorize_url_handler: OAuthSwiftURLHandlerType = OAuthSwiftOpenURLExternally.sharedInstance
+
+ public var allowMissingOauthVerifier: Bool = false
+
+ var consumer_key: String
+ var consumer_secret: String
+ var request_token_url: String
+ var authorize_url: String
+ var access_token_url: String
+
+ var observer: AnyObject?
+
+ public init(consumerKey: String, consumerSecret: String, requestTokenUrl: String, authorizeUrl: String, accessTokenUrl: String){
+ self.consumer_key = consumerKey
+ self.consumer_secret = consumerSecret
+ self.request_token_url = requestTokenUrl
+ self.authorize_url = authorizeUrl
+ self.access_token_url = accessTokenUrl
+ self.client = OAuthSwiftClient(consumerKey: consumerKey, consumerSecret: consumerSecret)
+ }
+
+ struct CallbackNotification {
+ static let notificationName = "OAuthSwiftCallbackNotificationName"
+ static let optionsURLKey = "OAuthSwiftCallbackNotificationOptionsURLKey"
+ }
+
+ struct OAuthSwiftError {
+ static let domain = "OAuthSwiftErrorDomain"
+ static let appOnlyAuthenticationErrorCode = 1
+ }
+
+ public typealias TokenSuccessHandler = (credential: OAuthSwiftCredential, response: NSURLResponse) -> Void
+ public typealias FailureHandler = (error: NSError) -> Void
+
+ // 0. Start
+ public func authorizeWithCallbackURL(callbackURL: NSURL, success: TokenSuccessHandler, failure: ((error: NSError) -> Void)) {
+ self.postOAuthRequestTokenWithCallbackURL(callbackURL, success: {
+ credential, response in
+
+ self.observer = NSNotificationCenter.defaultCenter().addObserverForName(CallbackNotification.notificationName, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock:{
+ notification in
+ //NSNotificationCenter.defaultCenter().removeObserver(self)
+ NSNotificationCenter.defaultCenter().removeObserver(self.observer!)
+ let url = notification.userInfo![CallbackNotification.optionsURLKey] as! NSURL
+ var parameters: Dictionary = Dictionary()
+ if ((url.query) != nil){
+ parameters += url.query!.parametersFromQueryString()
+ }
+ if ((url.fragment) != nil && url.fragment!.isEmpty == false) {
+ parameters += url.fragment!.parametersFromQueryString()
+ }
+ if let token = parameters["token"] {
+ parameters["oauth_token"] = token
+ }
+ if (parameters["oauth_token"] != nil && (self.allowMissingOauthVerifier || parameters["oauth_verifier"] != nil)) {
+ //var credential: OAuthSwiftCredential = self.client.credential
+ self.client.credential.oauth_token = parameters["oauth_token"]!
+ if (parameters["oauth_verifier"] != nil) {
+ self.client.credential.oauth_verifier = parameters["oauth_verifier"]!
+ }
+ self.postOAuthAccessTokenWithRequestToken({
+ credential, response in
+ success(credential: credential, response: response)
+ }, failure: failure)
+ } else {
+ let userInfo = [NSLocalizedFailureReasonErrorKey: NSLocalizedString("Oauth problem.", comment: "")]
+ failure(error: NSError(domain: OAuthSwiftErrorDomain, code: -1, userInfo: userInfo))
+ return
+ }
+ })
+ // 2. Authorize
+ if let queryURL = NSURL(string: self.authorize_url + (self.authorize_url.has("?") ? "&" : "?") + "oauth_token=\(credential.oauth_token)") {
+ self.authorize_url_handler.handle(queryURL)
+ }
+ }, failure: failure)
+ }
+
+ // 1. Request token
+ public func postOAuthRequestTokenWithCallbackURL(callbackURL: NSURL, success: TokenSuccessHandler, failure: FailureHandler?) {
+ var parameters = Dictionary()
+ if let callbackURLString: String = callbackURL.absoluteString {
+ parameters["oauth_callback"] = callbackURLString
+ }
+ self.client.credential.oauth_header_type = "oauth1"
+ self.client.post(self.request_token_url, parameters: parameters, success: {
+ data, response in
+ let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String!
+ let parameters = responseString.parametersFromQueryString()
+ self.client.credential.oauth_token = parameters["oauth_token"]!
+ self.client.credential.oauth_token_secret = parameters["oauth_token_secret"]!
+ success(credential: self.client.credential, response: response)
+ }, failure: failure)
+ }
+
+ // 3. Get Access token
+ func postOAuthAccessTokenWithRequestToken(success: TokenSuccessHandler, failure: FailureHandler?) {
+ var parameters = Dictionary()
+ parameters["oauth_token"] = self.client.credential.oauth_token
+ parameters["oauth_verifier"] = self.client.credential.oauth_verifier
+ self.client.post(self.access_token_url, parameters: parameters, success: {
+ data, response in
+ let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String!
+ let parameters = responseString.parametersFromQueryString()
+ self.client.credential.oauth_token = parameters["oauth_token"]!
+ self.client.credential.oauth_token_secret = parameters["oauth_token_secret"]!
+ success(credential: self.client.credential, response: response)
+ }, failure: failure)
+ }
+
+ public class func handleOpenURL(url: NSURL) {
+ let notification = NSNotification(name: CallbackNotification.notificationName, object: nil,
+ userInfo: [CallbackNotification.optionsURLKey: url])
+ NSNotificationCenter.defaultCenter().postNotification(notification)
+ }
+
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuth2Swift.swift b/Pods/OAuthSwift/OAuthSwift/OAuth2Swift.swift
new file mode 100644
index 0000000..afa08d0
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuth2Swift.swift
@@ -0,0 +1,162 @@
+//
+// OAuth2Swift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/22/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+public class OAuth2Swift: NSObject {
+
+ public var client: OAuthSwiftClient
+
+ public var authorize_url_handler: OAuthSwiftURLHandlerType = OAuthSwiftOpenURLExternally.sharedInstance
+
+ var consumer_key: String
+ var consumer_secret: String
+ var authorize_url: String
+ var access_token_url: String?
+ var response_type: String
+ var observer: AnyObject?
+ var content_type: String?
+
+ public convenience init(consumerKey: String, consumerSecret: String, authorizeUrl: String, accessTokenUrl: String, responseType: String){
+ self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, authorizeUrl: authorizeUrl, responseType: responseType)
+ self.access_token_url = accessTokenUrl
+ }
+
+ public convenience init(consumerKey: String, consumerSecret: String, authorizeUrl: String, accessTokenUrl: String, responseType: String, contentType: String){
+ self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, authorizeUrl: authorizeUrl, responseType: responseType)
+ self.access_token_url = accessTokenUrl
+ self.content_type = contentType
+ }
+
+ public init(consumerKey: String, consumerSecret: String, authorizeUrl: String, responseType: String){
+ self.consumer_key = consumerKey
+ self.consumer_secret = consumerSecret
+ self.authorize_url = authorizeUrl
+ self.response_type = responseType
+ self.client = OAuthSwiftClient(consumerKey: consumerKey, consumerSecret: consumerSecret)
+ }
+
+ struct CallbackNotification {
+ static let notificationName = "OAuthSwiftCallbackNotificationName"
+ static let optionsURLKey = "OAuthSwiftCallbackNotificationOptionsURLKey"
+ }
+
+ struct OAuthSwiftError {
+ static let domain = "OAuthSwiftErrorDomain"
+ static let appOnlyAuthenticationErrorCode = 1
+ }
+
+ public typealias TokenSuccessHandler = (credential: OAuthSwiftCredential, response: NSURLResponse?, parameters: NSDictionary) -> Void
+ public typealias FailureHandler = (error: NSError) -> Void
+
+
+ public func authorizeWithCallbackURL(callbackURL: NSURL, scope: String, state: String, params: Dictionary = Dictionary(), success: TokenSuccessHandler, failure: ((error: NSError) -> Void)) {
+ self.observer = NSNotificationCenter.defaultCenter().addObserverForName(CallbackNotification.notificationName, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock:{
+ notification in
+ NSNotificationCenter.defaultCenter().removeObserver(self.observer!)
+ let url = notification.userInfo![CallbackNotification.optionsURLKey] as! NSURL
+ var responseParameters: Dictionary = Dictionary()
+ if let query = url.query {
+ responseParameters += query.parametersFromQueryString()
+ }
+ if ((url.fragment) != nil && url.fragment!.isEmpty == false) {
+ responseParameters += url.fragment!.parametersFromQueryString()
+ }
+ if let accessToken = responseParameters["access_token"] {
+ self.client.credential.oauth_token = accessToken
+ success(credential: self.client.credential, response: nil, parameters: responseParameters)
+ }
+ if let code = responseParameters["code"] {
+ self.postOAuthAccessTokenWithRequestTokenByCode(code.stringByRemovingPercentEncoding!,
+ callbackURL:callbackURL,
+ success: { credential, response, responseParameters in
+ success(credential: credential, response: response, parameters: responseParameters)
+ }, failure: failure)
+ }
+ if let error = responseParameters["error"], error_description = responseParameters["error_description"] {
+ let errorInfo = [NSLocalizedFailureReasonErrorKey: NSLocalizedString(error, comment: error_description)]
+ failure(error: NSError(domain: OAuthSwiftErrorDomain, code: -1, userInfo: errorInfo))
+ }
+ })
+ //let authorizeURL = NSURL(string: )
+ var urlString = String()
+ urlString += self.authorize_url
+ urlString += (self.authorize_url.has("?") ? "&" : "?") + "client_id=\(self.consumer_key)"
+ urlString += "&redirect_uri=\(callbackURL.absoluteString)"
+ urlString += "&response_type=\(self.response_type)"
+ if (scope != "") {
+ urlString += "&scope=\(scope)"
+ }
+ if (state != "") {
+ urlString += "&state=\(state)"
+ }
+
+ for param in params {
+ urlString += "&\(param.0)=\(param.1)"
+ }
+
+ if let queryURL = NSURL(string: urlString) {
+ self.authorize_url_handler.handle(queryURL)
+ }
+ }
+
+ func postOAuthAccessTokenWithRequestTokenByCode(code: String, callbackURL: NSURL, success: TokenSuccessHandler, failure: FailureHandler?) {
+ var parameters = Dictionary()
+ parameters["client_id"] = self.consumer_key
+ parameters["client_secret"] = self.consumer_secret
+ parameters["code"] = code
+ parameters["grant_type"] = "authorization_code"
+ parameters["redirect_uri"] = callbackURL.absoluteString.stringByRemovingPercentEncoding
+
+ if self.content_type == "multipart/form-data" {
+ self.client.postMultiPartRequest(self.access_token_url!, method: "POST", parameters: parameters, success: {
+ data, response in
+ let responseJSON: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
+
+ let responseParameters: NSDictionary
+
+ if responseJSON != nil {
+ responseParameters = responseJSON as! NSDictionary
+ } else {
+ let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String!
+ responseParameters = responseString.parametersFromQueryString()
+ }
+
+ let accessToken = responseParameters["access_token"] as! String
+ self.client.credential.oauth_token = accessToken
+ success(credential: self.client.credential, response: response, parameters: responseParameters)
+ }, failure: failure)
+ } else {
+ self.client.credential.oauth_header_type = "oauth2"
+ self.client.post(self.access_token_url!, parameters: parameters, success: {
+ data, response in
+ let responseJSON: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
+
+ let responseParameters: NSDictionary
+
+ if responseJSON != nil {
+ responseParameters = responseJSON as! NSDictionary
+ } else {
+ let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String!
+ responseParameters = responseString.parametersFromQueryString()
+ }
+
+ let accessToken = responseParameters["access_token"] as! String
+ self.client.credential.oauth_token = accessToken
+ success(credential: self.client.credential, response: response, parameters: responseParameters)
+ }, failure: failure)
+ }
+ }
+
+ public class func handleOpenURL(url: NSURL) {
+ let notification = NSNotification(name: CallbackNotification.notificationName, object: nil,
+ userInfo: [CallbackNotification.optionsURLKey: url])
+ NSNotificationCenter.defaultCenter().postNotification(notification)
+ }
+
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuthSwiftClient.swift b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftClient.swift
new file mode 100644
index 0000000..3ae7f24
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftClient.swift
@@ -0,0 +1,199 @@
+//
+// OAuthSwiftClient.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/21/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+import Accounts
+
+var dataEncoding: NSStringEncoding = NSUTF8StringEncoding
+
+public class OAuthSwiftClient {
+
+ private(set) public var credential: OAuthSwiftCredential
+
+ public init(consumerKey: String, consumerSecret: String) {
+ self.credential = OAuthSwiftCredential(consumer_key: consumerKey, consumer_secret: consumerSecret)
+ }
+
+ public init(consumerKey: String, consumerSecret: String, accessToken: String, accessTokenSecret: String) {
+ self.credential = OAuthSwiftCredential(oauth_token: accessToken, oauth_token_secret: accessTokenSecret)
+ self.credential.consumer_key = consumerKey
+ self.credential.consumer_secret = consumerSecret
+ }
+
+ public func get(urlString: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.request(urlString, method: "GET", parameters: parameters, success: success, failure: failure)
+ }
+
+ public func post(urlString: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.request(urlString, method: "POST", parameters: parameters, success: success, failure: failure)
+ }
+
+ public func put(urlString: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.request(urlString, method: "PUT", parameters: parameters, success: success, failure: failure)
+ }
+
+ public func delete(urlString: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.request(urlString, method: "DELETE", parameters: parameters, success: success, failure: failure)
+ }
+
+ public func patch(urlString: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.request(urlString, method: "PATCH", parameters: parameters, success: success, failure: failure)
+ }
+
+ public func request(url: String, method: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ if let request = makeRequest(url, method: method, parameters: parameters) {
+
+ request.successHandler = success
+ request.failureHandler = failure
+ request.start()
+ }
+ }
+
+ public func makeRequest(urlString: String, method: String, parameters: Dictionary) -> OAuthSwiftHTTPRequest? {
+ if let url = NSURL(string: urlString) {
+ let request = OAuthSwiftHTTPRequest(URL: url, method: method, parameters: parameters)
+ request.headers = self.credential.makeHeaders(url, method: method, parameters: parameters)
+ request.dataEncoding = dataEncoding
+ request.encodeParameters = true
+ return request
+ }
+ return nil
+ }
+
+ public func postImage(urlString: String, parameters: Dictionary, image: NSData, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+ self.multiPartRequest(urlString, method: "POST", parameters: parameters, image: image, success: success, failure: failure)
+ }
+
+ func multiPartRequest(url: String, method: String, parameters: Dictionary, image: NSData, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+
+ if let request = makeRequest(url, method: method, parameters: parameters) {
+
+ var parmaImage = [String: AnyObject]()
+ parmaImage["media"] = image
+ let boundary = "AS-boundary-\(arc4random())-\(arc4random())"
+ let type = "multipart/form-data; boundary=\(boundary)"
+ let body = self.multiPartBodyFromParams(parmaImage, boundary: boundary)
+
+ request.HTTPBodyMultipart = body
+ request.contentTypeMultipart = type
+
+ request.successHandler = success
+ request.failureHandler = failure
+ request.start()
+ }
+ }
+
+ public func multiPartBodyFromParams(parameters: [String: AnyObject], boundary: String) -> NSData {
+ let data = NSMutableData()
+
+ let prefixData = "--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)
+ let seperData = "\r\n".dataUsingEncoding(NSUTF8StringEncoding)
+
+ for (key, value) in parameters {
+ var sectionData: NSData?
+ var sectionType: String?
+ var sectionFilename = ""
+
+ if key == "media" {
+ let multiData = value as! NSData
+ sectionData = multiData
+ sectionType = "image/jpeg"
+ sectionFilename = " filename=\"file\""
+ } else {
+ sectionData = "\(value)".dataUsingEncoding(NSUTF8StringEncoding)
+ }
+
+ data.appendData(prefixData!)
+
+ let sectionDisposition = "Content-Disposition: form-data; name=\"media\";\(sectionFilename)\r\n".dataUsingEncoding(NSUTF8StringEncoding)
+ data.appendData(sectionDisposition!)
+
+ if let type = sectionType {
+ let contentType = "Content-Type: \(type)\r\n".dataUsingEncoding(NSUTF8StringEncoding)
+ data.appendData(contentType!)
+ }
+
+ // append data
+ data.appendData(seperData!)
+ data.appendData(sectionData!)
+ data.appendData(seperData!)
+ }
+
+ data.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
+ return data
+ }
+
+ public func postMultiPartRequest(url: String, method: String, parameters: Dictionary, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {
+
+ if let request = makeRequest(url, method: method, parameters: parameters) {
+
+ let boundary = "POST-boundary-\(arc4random())-\(arc4random())"
+ let type = "multipart/form-data; boundary=\(boundary)"
+ let body = self.multiDataFromObject(parameters, boundary: boundary)
+
+ request.HTTPBodyMultipart = body
+ request.contentTypeMultipart = type
+
+ request.successHandler = success
+ request.failureHandler = failure
+ request.start()
+ }
+ }
+
+ func multiDataFromObject(object: [String:AnyObject], boundary: String) -> NSData? {
+ let data = NSMutableData()
+
+ let prefixString = "--\(boundary)\r\n"
+ let prefixData = prefixString.dataUsingEncoding(NSUTF8StringEncoding)!
+
+ let seperatorString = "\r\n"
+ let seperatorData = seperatorString.dataUsingEncoding(NSUTF8StringEncoding)!
+
+ for (key, value) in object {
+
+ var valueData: NSData?
+ let valueType: String = ""
+ let filenameClause = ""
+
+ let stringValue = "\(value)"
+ valueData = stringValue.dataUsingEncoding(NSUTF8StringEncoding)!
+
+ if valueData == nil {
+ continue
+ }
+ data.appendData(prefixData)
+ let contentDispositionString = "Content-Disposition: form-data; name=\"\(key)\";\(filenameClause)\r\n"
+ let contentDispositionData = contentDispositionString.dataUsingEncoding(NSUTF8StringEncoding)
+ data.appendData(contentDispositionData!)
+ if let type: String = valueType {
+ let contentTypeString = "Content-Type: \(type)\r\n"
+ let contentTypeData = contentTypeString.dataUsingEncoding(NSUTF8StringEncoding)
+ data.appendData(contentTypeData!)
+ }
+ data.appendData(seperatorData)
+ data.appendData(valueData!)
+ data.appendData(seperatorData)
+ }
+
+ let endingString = "--\(boundary)--\r\n"
+ let endingData = endingString.dataUsingEncoding(NSUTF8StringEncoding)!
+ data.appendData(endingData)
+
+ return data
+ }
+
+ @available(*, deprecated=0.4.6, message="Because method moved to OAuthSwiftCredential!")
+ public class func authorizationHeaderForMethod(method: String, url: NSURL, parameters: Dictionary, credential: OAuthSwiftCredential) -> String {
+ return credential.authorizationHeaderForMethod(method, url: url, parameters: parameters)
+ }
+
+ @available(*, deprecated=0.4.6, message="Because method moved to OAuthSwiftCredential!")
+ public class func signatureForMethod(method: String, url: NSURL, parameters: Dictionary, credential: OAuthSwiftCredential) -> String {
+ return credential.signatureForMethod(method, url: url, parameters: parameters)
+ }
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuthSwiftCredential.swift b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftCredential.swift
new file mode 100644
index 0000000..fa63dd3
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftCredential.swift
@@ -0,0 +1,136 @@
+//
+// OAuthSwiftCredential.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/22/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+import Foundation
+
+public class OAuthSwiftCredential: NSObject, NSCoding {
+
+ struct OAuth {
+ static let version = "1.0"
+ static let signatureMethod = "HMAC-SHA1"
+ }
+
+ var consumer_key: String = String()
+ var consumer_secret: String = String()
+ public var oauth_token: String = String()
+ public var oauth_token_secret: String = String()
+ var oauth_verifier: String = String()
+ public var oauth_header_type = String()
+
+ override init(){
+
+ }
+ public init(consumer_key: String, consumer_secret: String){
+ self.consumer_key = consumer_key
+ self.consumer_secret = consumer_secret
+ }
+ public init(oauth_token: String, oauth_token_secret: String){
+ self.oauth_token = oauth_token
+ self.oauth_token_secret = oauth_token_secret
+ }
+
+ private struct CodingKeys {
+ static let base = NSBundle.mainBundle().bundleIdentifier! + "."
+ static let consumerKey = base + "comsumer_key"
+ static let consumerSecret = base + "consumer_secret"
+ static let oauthToken = base + "oauth_token"
+ static let oauthTokenSecret = base + "oauth_token_secret"
+ static let oauthVerifier = base + "oauth_verifier"
+ }
+
+ // Cannot declare a required initializer within an extension.
+ // extension OAuthSwiftCredential: NSCoding {
+ public required convenience init?(coder decoder: NSCoder) {
+ self.init()
+ self.consumer_key = (decoder.decodeObjectForKey(CodingKeys.consumerKey) as? String) ?? String()
+ self.consumer_secret = (decoder.decodeObjectForKey(CodingKeys.consumerSecret) as? String) ?? String()
+ self.oauth_token = (decoder.decodeObjectForKey(CodingKeys.oauthToken) as? String) ?? String()
+ self.oauth_token_secret = (decoder.decodeObjectForKey(CodingKeys.oauthTokenSecret) as? String) ?? String()
+ self.oauth_verifier = (decoder.decodeObjectForKey(CodingKeys.oauthVerifier) as? String) ?? String()
+ }
+
+ public func encodeWithCoder(coder: NSCoder) {
+ coder.encodeObject(self.consumer_key, forKey: CodingKeys.consumerKey)
+ coder.encodeObject(self.consumer_secret, forKey: CodingKeys.consumerSecret)
+ coder.encodeObject(self.oauth_token, forKey: CodingKeys.oauthToken)
+ coder.encodeObject(self.oauth_token_secret, forKey: CodingKeys.oauthTokenSecret)
+ coder.encodeObject(self.oauth_verifier, forKey: CodingKeys.oauthVerifier)
+ }
+ // } // End NSCoding extension
+
+ public func makeHeaders(url:NSURL, method: String, parameters: Dictionary) -> Dictionary {
+ if self.oauth_header_type == "oauth1" {
+ return ["Authorization": self.authorizationHeaderForMethod(method, url: url, parameters: parameters)]
+ }
+ if self.oauth_header_type == "oauth2" {
+ return ["Authorization": "Bearer \(self.oauth_token)"]
+ }
+ return [:]
+ }
+
+ public func authorizationHeaderForMethod(method: String, url: NSURL, parameters: Dictionary) -> String {
+ var authorizationParameters = Dictionary()
+ authorizationParameters["oauth_version"] = OAuth.version
+ authorizationParameters["oauth_signature_method"] = OAuth.signatureMethod
+ authorizationParameters["oauth_consumer_key"] = self.consumer_key
+ authorizationParameters["oauth_timestamp"] = String(Int64(NSDate().timeIntervalSince1970))
+ authorizationParameters["oauth_nonce"] = (NSUUID().UUIDString as NSString).substringToIndex(8)
+
+ if (self.oauth_token != ""){
+ authorizationParameters["oauth_token"] = self.oauth_token
+ }
+
+ for (key, value) in parameters {
+ if key.hasPrefix("oauth_") {
+ authorizationParameters.updateValue(value, forKey: key)
+ }
+ }
+
+ let combinedParameters = authorizationParameters.join(parameters)
+
+ let finalParameters = combinedParameters
+
+ authorizationParameters["oauth_signature"] = self.signatureForMethod(method, url: url, parameters: finalParameters)
+
+ var parameterComponents = authorizationParameters.urlEncodedQueryStringWithEncoding(dataEncoding).componentsSeparatedByString("&") as [String]
+ parameterComponents.sortInPlace { $0 < $1 }
+
+ var headerComponents = [String]()
+ for component in parameterComponents {
+ let subcomponent = component.componentsSeparatedByString("=") as [String]
+ if subcomponent.count == 2 {
+ headerComponents.append("\(subcomponent[0])=\"\(subcomponent[1])\"")
+ }
+ }
+
+ return "OAuth " + headerComponents.joinWithSeparator(", ")
+ }
+
+ public func signatureForMethod(method: String, url: NSURL, parameters: Dictionary) -> String {
+ var tokenSecret: NSString = ""
+ tokenSecret = self.oauth_token_secret.urlEncodedStringWithEncoding(dataEncoding)
+
+ let encodedConsumerSecret = self.consumer_secret.urlEncodedStringWithEncoding(dataEncoding)
+
+ let signingKey = "\(encodedConsumerSecret)&\(tokenSecret)"
+
+ var parameterComponents = parameters.urlEncodedQueryStringWithEncoding(dataEncoding).componentsSeparatedByString("&") as [String]
+ parameterComponents.sortInPlace { $0 < $1 }
+
+ let parameterString = parameterComponents.joinWithSeparator("&")
+ let encodedParameterString = parameterString.urlEncodedStringWithEncoding(dataEncoding)
+
+ let encodedURL = url.absoluteString.urlEncodedStringWithEncoding(dataEncoding)
+
+ let signatureBaseString = "\(method)&\(encodedURL)&\(encodedParameterString)"
+
+ let key = signingKey.dataUsingEncoding(NSUTF8StringEncoding)!
+ let msg = signatureBaseString.dataUsingEncoding(NSUTF8StringEncoding)!
+ let sha1 = HMAC.sha1(key: key, message: msg)!
+ return sha1.base64EncodedStringWithOptions([])
+ }
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuthSwiftHTTPRequest.swift b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftHTTPRequest.swift
new file mode 100644
index 0000000..d778de5
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftHTTPRequest.swift
@@ -0,0 +1,250 @@
+//
+// OAuthSwiftHTTPRequest.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/21/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+public class OAuthSwiftHTTPRequest: NSObject, NSURLSessionDelegate {
+
+ public typealias SuccessHandler = (data: NSData, response: NSHTTPURLResponse) -> Void
+ public typealias FailureHandler = (error: NSError) -> Void
+
+ var URL: NSURL
+ var HTTPMethod: String
+ var HTTPBodyMultipart: NSData?
+ var contentTypeMultipart: String?
+
+ var request: NSMutableURLRequest?
+ var session: NSURLSession!
+
+ var headers: Dictionary
+ var parameters: Dictionary
+ var encodeParameters: Bool
+
+ var dataEncoding: NSStringEncoding
+
+ var timeoutInterval: NSTimeInterval
+
+ var HTTPShouldHandleCookies: Bool
+
+ var response: NSHTTPURLResponse!
+ var responseData: NSMutableData
+
+ var successHandler: SuccessHandler?
+ var failureHandler: FailureHandler?
+
+ convenience init(URL: NSURL) {
+ self.init(URL: URL, method: "GET", parameters: [:])
+ }
+
+ init(URL: NSURL, method: String, parameters: Dictionary) {
+ self.URL = URL
+ self.HTTPMethod = method
+ self.headers = [:]
+ self.parameters = parameters
+ self.encodeParameters = false
+ self.dataEncoding = NSUTF8StringEncoding
+ self.timeoutInterval = 60
+ self.HTTPShouldHandleCookies = false
+ self.responseData = NSMutableData()
+ }
+
+ init(request: NSURLRequest) {
+ self.request = request as? NSMutableURLRequest
+ self.URL = request.URL!
+ self.HTTPMethod = request.HTTPMethod!
+ self.headers = [:]
+ self.parameters = [:]
+ self.encodeParameters = false
+ self.dataEncoding = NSUTF8StringEncoding
+ self.timeoutInterval = 60
+ self.HTTPShouldHandleCookies = false
+ self.responseData = NSMutableData()
+ }
+
+ func start() {
+ if (request == nil) {
+ var error: NSError?
+
+ do {
+ self.request = try self.makeRequest()
+ } catch let error1 as NSError {
+ error = error1
+ self.request = nil
+ }
+
+ if ((error) != nil) {
+ print(error!.localizedDescription)
+ }
+ }
+
+ dispatch_async(dispatch_get_main_queue(), {
+ self.session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
+ delegate: self,
+ delegateQueue: NSOperationQueue.mainQueue())
+ let task: NSURLSessionDataTask = self.session.dataTaskWithRequest(self.request!) { data, response, error -> Void in
+ #if os(iOS)
+ UIApplication.sharedApplication().networkActivityIndicatorVisible = false
+ #endif
+
+ self.response = response as? NSHTTPURLResponse
+ self.responseData.length = 0
+ self.responseData.appendData(data!)
+
+ if self.response.statusCode >= 400 {
+ let responseString = NSString(data: self.responseData, encoding: self.dataEncoding)
+ let localizedDescription = OAuthSwiftHTTPRequest.descriptionForHTTPStatus(self.response.statusCode, responseString: responseString! as String)
+ let userInfo : [NSObject : AnyObject] = [NSLocalizedDescriptionKey: localizedDescription, "Response-Headers": self.response.allHeaderFields]
+ let error = NSError(domain: NSURLErrorDomain, code: self.response.statusCode, userInfo: userInfo)
+ self.failureHandler?(error: error)
+ return
+ }
+
+ self.successHandler?(data: self.responseData, response: self.response)
+ }
+ task.resume()
+
+ #if os(iOS)
+ UIApplication.sharedApplication().networkActivityIndicatorVisible = true
+ #endif
+ })
+ }
+
+ public func makeRequest() throws -> NSMutableURLRequest {
+ return try OAuthSwiftHTTPRequest.makeRequest(self.URL, method: self.HTTPMethod, headers: self.headers, parameters: self.parameters, dataEncoding: self.dataEncoding, encodeParameters: self.encodeParameters, body: self.HTTPBodyMultipart, contentType: self.contentTypeMultipart)
+ }
+
+ public class func makeRequest(
+ URL: NSURL,
+ method: String,
+ headers: [String : String],
+ parameters: Dictionary,
+ dataEncoding: NSStringEncoding,
+ encodeParameters: Bool,
+ body: NSData? = nil,
+ contentType: String? = nil) throws -> NSMutableURLRequest {
+ var error: NSError! = NSError(domain: "Migrator", code: 0, userInfo: nil)
+ let request = NSMutableURLRequest(URL: URL)
+ request.HTTPMethod = method
+
+ for (key, value) in headers {
+ request.setValue(value, forHTTPHeaderField: key)
+ }
+
+ let charset = CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(dataEncoding))
+
+ let nonOAuthParameters = parameters.filter { key, _ in !key.hasPrefix("oauth_") }
+
+ if (body != nil && contentType != nil) {
+ request.setValue(contentType!, forHTTPHeaderField: "Content-Type")
+ //request!.setValue(self.HTTPBodyMultipart!.length.description, forHTTPHeaderField: "Content-Length")
+ request.HTTPBody = body!
+ } else {
+ if nonOAuthParameters.count > 0 {
+ if request.HTTPMethod == "GET" || request.HTTPMethod == "HEAD" || request.HTTPMethod == "DELETE" {
+ let queryString = nonOAuthParameters.urlEncodedQueryStringWithEncoding(dataEncoding)
+ request.URL = URL.URLByAppendingQueryString(queryString)
+ request.setValue("application/x-www-form-urlencoded; charset=\(charset)", forHTTPHeaderField: "Content-Type")
+ }
+ else {
+ if (encodeParameters) {
+ let queryString = nonOAuthParameters.urlEncodedQueryStringWithEncoding(dataEncoding)
+ //self.request!.URL = self.URL.URLByAppendingQueryString(queryString)
+ request.setValue("application/x-www-form-urlencoded; charset=\(charset)", forHTTPHeaderField: "Content-Type")
+ request.HTTPBody = queryString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
+ }
+ else {
+ var jsonError: NSError?
+ do {
+ let jsonData: NSData = try NSJSONSerialization.dataWithJSONObject(nonOAuthParameters, options: [])
+ request.setValue("application/json; charset=\(charset)", forHTTPHeaderField: "Content-Type")
+ request.HTTPBody = jsonData
+ } catch let error1 as NSError {
+ jsonError = error1
+ if (true) {
+ //println(jsonError!.localizedDescription)
+ error = jsonError
+ }
+ throw error
+ }
+ }
+ }
+ }
+ }
+ return request
+ }
+
+ class func stringWithData(data: NSData, encodingName: String?) -> String {
+ var encoding: UInt = NSUTF8StringEncoding
+
+ if (encodingName != nil) {
+ let encodingNameString = encodingName! as NSString
+ encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding(encodingNameString))
+
+ if encoding == UInt(kCFStringEncodingInvalidId) {
+ encoding = NSUTF8StringEncoding // by default
+ }
+ }
+
+ return NSString(data: data, encoding: encoding)! as String
+ }
+
+ class func descriptionForHTTPStatus(status: Int, responseString: String) -> String {
+ var s = "HTTP Status \(status)"
+
+ var description: String?
+ // http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ if status == 400 { description = "Bad Request" }
+ if status == 401 { description = "Unauthorized" }
+ if status == 402 { description = "Payment Required" }
+ if status == 403 { description = "Forbidden" }
+ if status == 404 { description = "Not Found" }
+ if status == 405 { description = "Method Not Allowed" }
+ if status == 406 { description = "Not Acceptable" }
+ if status == 407 { description = "Proxy Authentication Required" }
+ if status == 408 { description = "Request Timeout" }
+ if status == 409 { description = "Conflict" }
+ if status == 410 { description = "Gone" }
+ if status == 411 { description = "Length Required" }
+ if status == 412 { description = "Precondition Failed" }
+ if status == 413 { description = "Payload Too Large" }
+ if status == 414 { description = "URI Too Long" }
+ if status == 415 { description = "Unsupported Media Type" }
+ if status == 416 { description = "Requested Range Not Satisfiable" }
+ if status == 417 { description = "Expectation Failed" }
+ if status == 422 { description = "Unprocessable Entity" }
+ if status == 423 { description = "Locked" }
+ if status == 424 { description = "Failed Dependency" }
+ if status == 425 { description = "Unassigned" }
+ if status == 426 { description = "Upgrade Required" }
+ if status == 427 { description = "Unassigned" }
+ if status == 428 { description = "Precondition Required" }
+ if status == 429 { description = "Too Many Requests" }
+ if status == 430 { description = "Unassigned" }
+ if status == 431 { description = "Request Header Fields Too Large" }
+ if status == 432 { description = "Unassigned" }
+ if status == 500 { description = "Internal Server Error" }
+ if status == 501 { description = "Not Implemented" }
+ if status == 502 { description = "Bad Gateway" }
+ if status == 503 { description = "Service Unavailable" }
+ if status == 504 { description = "Gateway Timeout" }
+ if status == 505 { description = "HTTP Version Not Supported" }
+ if status == 506 { description = "Variant Also Negotiates" }
+ if status == 507 { description = "Insufficient Storage" }
+ if status == 508 { description = "Loop Detected" }
+ if status == 509 { description = "Unassigned" }
+ if status == 510 { description = "Not Extended" }
+ if status == 511 { description = "Network Authentication Required" }
+
+ if (description != nil) {
+ s = s + ": " + description! + ", Response: " + responseString
+ }
+
+ return s
+ }
+
+}
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuthSwiftURLHandlerType.swift b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftURLHandlerType.swift
new file mode 100644
index 0000000..036aee5
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuthSwiftURLHandlerType.swift
@@ -0,0 +1,40 @@
+//
+// OAuthSwiftURLHandlerType.swift
+// OAuthSwift
+//
+// Created by phimage on 11/05/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+#if os(iOS)
+ import UIKit
+#elseif os(OSX)
+ import AppKit
+#endif
+
+@objc public protocol OAuthSwiftURLHandlerType {
+ func handle(url: NSURL)
+}
+
+public class OAuthSwiftOpenURLExternally: OAuthSwiftURLHandlerType {
+ class var sharedInstance : OAuthSwiftOpenURLExternally {
+ struct Static {
+ static var onceToken : dispatch_once_t = 0
+ static var instance : OAuthSwiftOpenURLExternally? = nil
+ }
+ dispatch_once(&Static.onceToken) {
+ Static.instance = OAuthSwiftOpenURLExternally()
+ }
+ return Static.instance!
+ }
+
+ @objc public func handle(url: NSURL) {
+ #if os(iOS)
+ UIApplication.sharedApplication().openURL(url)
+ #elseif os(OSX)
+ NSWorkspace.sharedWorkspace().openURL(url)
+ #endif
+ }
+}
\ No newline at end of file
diff --git a/Pods/OAuthSwift/OAuthSwift/OAuthWebViewController.swift b/Pods/OAuthSwift/OAuthSwift/OAuthWebViewController.swift
new file mode 100644
index 0000000..9960341
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/OAuthWebViewController.swift
@@ -0,0 +1,50 @@
+//
+// OAuthWebViewController.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 2/11/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+#if os(iOS)
+ import UIKit
+ public typealias OAuthViewController = UIViewController
+#elseif os(OSX)
+ import AppKit
+ public typealias OAuthViewController = NSViewController
+#endif
+
+public class OAuthWebViewController: OAuthViewController, OAuthSwiftURLHandlerType {
+
+ public func handle(url: NSURL){
+ #if os(iOS)
+ UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(
+ self, animated: true, completion: nil)
+ #elseif os(OSX)
+ if let p = self.parentViewController { // default behaviour if this controller affected as child controller
+ p.presentViewControllerAsModalWindow(self)
+ } else if let window = self.view.window {
+ window.makeKeyAndOrderFront(nil)
+ }
+ // or create an NSWindow or NSWindowController (/!\ keep a strong reference on it)
+ #endif
+ }
+
+ public func dismissWebViewController() {
+ #if os(iOS)
+ self.dismissViewControllerAnimated(true, completion: nil)
+ #elseif os(OSX)
+ if self.presentingViewController != nil { // if presentViewControllerAsModalWindow
+ self.dismissController(nil)
+ if self.parentViewController != nil {
+ self.removeFromParentViewController()
+ }
+ }
+ else if let window = self.view.window {
+ window.performClose(nil)
+ }
+ #endif
+ }
+}
\ No newline at end of file
diff --git a/Pods/OAuthSwift/OAuthSwift/SHA1.swift b/Pods/OAuthSwift/OAuthSwift/SHA1.swift
new file mode 100644
index 0000000..79880c5
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/SHA1.swift
@@ -0,0 +1,134 @@
+//
+// SHA1.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 1/28/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+class SHA1 {
+
+ var message: NSData
+
+ init(_ message: NSData) {
+ self.message = message
+ }
+
+ /** Common part for hash calculation. Prepare header data. */
+ func prepare(len:Int = 64) -> NSMutableData {
+ let tmpMessage: NSMutableData = NSMutableData(data: self.message)
+
+ // Step 1. Append Padding Bits
+ tmpMessage.appendBytes([0x80]) // append one bit (Byte with one bit) to message
+
+ // append "0" bit until message length in bits ≡ 448 (mod 512)
+ while tmpMessage.length % len != (len - 8) {
+ tmpMessage.appendBytes([0x00])
+ }
+
+ return tmpMessage
+ }
+
+ func calculate() -> NSData {
+
+ //var tmpMessage = self.prepare()
+ let len = 64
+ let h:[UInt32] = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
+
+ let tmpMessage: NSMutableData = NSMutableData(data: self.message)
+
+ // Step 1. Append Padding Bits
+ tmpMessage.appendBytes([0x80]) // append one bit (Byte with one bit) to message
+
+ // append "0" bit until message length in bits ≡ 448 (mod 512)
+ while tmpMessage.length % len != (len - 8) {
+ tmpMessage.appendBytes([0x00])
+ }
+
+ // hash values
+ var hh = h
+
+ // append message length, in a 64-bit big-endian integer. So now the message length is a multiple of 512 bits.
+ tmpMessage.appendBytes((self.message.length * 8).bytes(64 / 8))
+
+ // Process the message in successive 512-bit chunks:
+ let chunkSizeBytes = 512 / 8 // 64
+ var leftMessageBytes = tmpMessage.length
+ for var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes {
+ let chunk = tmpMessage.subdataWithRange(NSRange(location: i, length: min(chunkSizeBytes,leftMessageBytes)))
+ // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15, big-endian
+ // Extend the sixteen 32-bit words into eighty 32-bit words:
+ var M:[UInt32] = [UInt32](count: 80, repeatedValue: 0)
+ for x in 0.. () in
+ var i:UInt32 = item.bigEndian
+ buf.appendBytes(&i, length: sizeofValue(i))
+ })
+
+ return buf.copy() as! NSData
+ }
+}
\ No newline at end of file
diff --git a/Pods/OAuthSwift/OAuthSwift/String+OAuthSwift.swift b/Pods/OAuthSwift/OAuthSwift/String+OAuthSwift.swift
new file mode 100755
index 0000000..6165692
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/String+OAuthSwift.swift
@@ -0,0 +1,134 @@
+//
+// String+OAuthSwift.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 6/21/14.
+// Copyright (c) 2014 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+extension String {
+
+ internal func indexOf(sub: String) -> Int? {
+ var pos: Int?
+
+ if let range = self.rangeOfString(sub) {
+ if !range.isEmpty {
+ pos = self.startIndex.distanceTo(range.startIndex)
+ }
+ }
+
+ return pos
+ }
+
+ internal subscript (r: Range) -> String {
+ get {
+ let startIndex = self.startIndex.advancedBy(r.startIndex)
+ let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex)
+
+ return self[Range(start: startIndex, end: endIndex)]
+ }
+ }
+
+ func urlEncodedStringWithEncoding(encoding: NSStringEncoding) -> String {
+ let charactersToBeEscaped = ":/?&=;+!@#$()',*" as CFStringRef
+ let charactersToLeaveUnescaped = "[]." as CFStringRef
+
+ let raw: NSString = self
+
+ let result = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, raw, charactersToLeaveUnescaped, charactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding))
+
+ return result as String
+ }
+
+ func parametersFromQueryString() -> Dictionary {
+ var parameters = Dictionary()
+
+ let scanner = NSScanner(string: self)
+
+ var key: NSString?
+ var value: NSString?
+
+ while !scanner.atEnd {
+ key = nil
+ scanner.scanUpToString("=", intoString: &key)
+ scanner.scanString("=", intoString: nil)
+
+ value = nil
+ scanner.scanUpToString("&", intoString: &value)
+ scanner.scanString("&", intoString: nil)
+
+ if (key != nil && value != nil) {
+ parameters.updateValue(value! as String, forKey: key! as String)
+ }
+ }
+
+ return parameters
+ }
+ //分割字符
+ func split(s:String)->[String]{
+ if s.isEmpty{
+ var x=[String]()
+ for y in self.characters{
+ x.append(String(y))
+ }
+ return x
+ }
+ return self.componentsSeparatedByString(s)
+ }
+ //去掉左右空格
+ func trim()->String{
+ return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
+ }
+ //是否包含字符串
+ func has(s:String)->Bool{
+ if (self.rangeOfString(s) != nil) {
+ return true
+ }else{
+ return false
+ }
+ }
+ //是否包含前缀
+ func hasBegin(s:String)->Bool{
+ if self.hasPrefix(s) {
+ return true
+ }else{
+ return false
+ }
+ }
+ //是否包含后缀
+ func hasEnd(s:String)->Bool{
+ if self.hasSuffix(s) {
+ return true
+ }else{
+ return false
+ }
+ }
+ //统计长度
+ func length()->Int{
+ return self.utf16.count
+ }
+ //统计长度(别名)
+ func size()->Int{
+ return self.utf16.count
+ }
+ //重复字符串
+ func `repeat`(times: Int) -> String{
+ var result = ""
+ for _ in 0.. String{
+ let s=Array(self.split("").reverse())
+ var x=""
+ for y in s{
+ x+=y
+ }
+ return x
+ }
+}
+
diff --git a/Pods/OAuthSwift/OAuthSwift/Utils.swift b/Pods/OAuthSwift/OAuthSwift/Utils.swift
new file mode 100644
index 0000000..5a4aec8
--- /dev/null
+++ b/Pods/OAuthSwift/OAuthSwift/Utils.swift
@@ -0,0 +1,50 @@
+//
+// Utils.swift
+// OAuthSwift
+//
+// Created by Dongri Jin on 1/28/15.
+// Copyright (c) 2015 Dongri Jin. All rights reserved.
+//
+
+import Foundation
+
+func rotateLeft(v:UInt16, n:UInt16) -> UInt16 {
+ return ((v << n) & 0xFFFF) | (v >> (16 - n))
+}
+
+func rotateLeft(v:UInt32, n:UInt32) -> UInt32 {
+ return ((v << n) & 0xFFFFFFFF) | (v >> (32 - n))
+}
+
+func rotateLeft(x:UInt64, n:UInt64) -> UInt64 {
+ return (x << n) | (x >> (64 - n))
+}
+
+func rotateRight(x:UInt16, n:UInt16) -> UInt16 {
+ return (x >> n) | (x << (16 - n))
+}
+
+func rotateRight(x:UInt32, n:UInt32) -> UInt32 {
+ return (x >> n) | (x << (32 - n))
+}
+
+func rotateRight(x:UInt64, n:UInt64) -> UInt64 {
+ return ((x >> n) | (x << (64 - n)))
+}
+
+func reverseBytes(value: UInt32) -> UInt32 {
+ let tmp1 = ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8)
+ let tmp2 = ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24)
+ return tmp1 | tmp2
+}
+
+public func generateStateWithLength (len : Int) -> NSString {
+ let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ let randomString : NSMutableString = NSMutableString(capacity: len)
+ for (var i=0; i < len; i++){
+ let length = UInt32 (letters.length)
+ let rand = arc4random_uniform(length)
+ randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
+ }
+ return randomString
+}
diff --git a/Pods/OAuthSwift/README.md b/Pods/OAuthSwift/README.md
new file mode 100644
index 0000000..49e3d0b
--- /dev/null
+++ b/Pods/OAuthSwift/README.md
@@ -0,0 +1,120 @@
+
+
+
+
+## OAuthSwift
+
+Swift based OAuth library for iOS and OSX.
+
+### Support OAuth1.0, OAuth2.0
+
+Twitter, Flickr, Github, Instagram, Foursquare. Fitbit, Withings, Linkedin, Dropbox, Dribbble, Salesforce, BitBucket, GoogleDrive, Smugmug, Intuit, Zaim, Tumblr, Slack, Uber etc
+
+### Installation
+
+OAuthSwift is packaged as a Swift framework. Currently this is the simplest way to add it to your app:
+
+* Drag OAuthSwift.xcodeproj to your project in the Project Navigator.
+* Select your project and then your app target. Open the Build Phases panel.
+* Expand the Target Dependencies group, and add OAuthSwift framework.
+* import OAuthSwift whenever you want to use OAuthSwift.
+
+### Support Carthage
+
+* Install Carthage (https://github.com/Carthage/Carthage)
+* Create Cartfile file
+```
+github "dongri/OAuthSwift" ~> 0.4.5
+```
+* Run `carthage update`.
+* On your application targets’ “General” settings tab, in the “Embedded Binaries” section, drag and drop OAuthSwift.framework from the Carthage/Build/iOS folder on disk.
+
+### Support CocoaPods
+
+* Podfile
+```
+platform :ios, '8.0'
+use_frameworks!
+
+pod "OAuthSwift", "~> 0.4.5"
+```
+
+### Setting URL Schemes
+
+
+
+### Examples
+
+```swift
+// AppDelegate
+func application(application: UIApplication!, openURL url: NSURL!, sourceApplication: String!, annotation: AnyObject!) -> Bool {
+ if (url.host == "oauth-callback") {
+ if (url.path!.hasPrefix("/twitter")){
+ OAuth1Swift.handleOpenURL(url)
+ }
+ if ( url.path!.hasPrefix("/github" )){
+ OAuth2Swift.handleOpenURL(url)
+ }
+ }
+ return true
+}
+
+// OAuth1.0
+let oauthswift = OAuth1Swift(
+ consumerKey: "********",
+ consumerSecret: "********",
+ requestTokenUrl: "https://api.twitter.com/oauth/request_token",
+ authorizeUrl: "https://api.twitter.com/oauth/authorize",
+ accessTokenUrl: "https://api.twitter.com/oauth/access_token"
+)
+oauthswift.authorizeWithCallbackURL( NSURL(string: "oauth-swift://oauth-callback/twitter"), success: {
+ credential, response in
+ println(credential.oauth_token)
+ println(credential.oauth_token_secret)
+}, failure: failureHandler)
+
+// OAuth2.0
+let oauthswift = OAuth2Swift(
+ consumerKey: "********",
+ consumerSecret: "********",
+ authorizeUrl: "https://api.instagram.com/oauth/authorize",
+ responseType: "token"
+)
+oauthswift.authorizeWithCallbackURL( NSURL(string: "oauth-swift://oauth-callback/instagram"), scope: "likes+comments", state:"INSTAGRAM", success: {
+ credential, response in
+ println(credential.oauth_token)
+}, failure: failureHandler)
+
+```
+
+### OAuth pages
+
+* [Twitter](https://dev.twitter.com/docs/auth/oauth)
+* [Flickr](https://www.flickr.com/services/api/auth.oauth.html)
+* [Github](https://developer.github.com/v3/oauth)
+* [Instagram](http://instagram.com/developer/authentication)
+* [Foursquare](https://developer.foursquare.com/overview/auth)
+* [Fitbit](https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API)
+* [Withings](http://oauth.withings.com/api)
+* [Linkedin](https://developer.linkedin.com/documents/authentication)
+* [Dropbox](https://www.dropbox.com/developers/core/docs)
+* [Dribbble](http://developer.dribbble.com/v1/oauth/)
+* [Salesforce](https://www.salesforce.com/us/developer/docs/api_rest/)
+* [BitBucket](https://confluence.atlassian.com/display/BITBUCKET/OAuth+on+Bitbucket)
+* [GoogleDrive](https://developers.google.com/drive/v2/reference/)
+* [Smugmug](https://smugmug.atlassian.net/wiki/display/API/OAuth)
+* [Intuit](https://developer.intuit.com/docs/0100_accounting/0060_authentication_and_authorization/oauth_management_api)
+* [Zaim](https://dev.zaim.net/home/api/authorize)
+* [Tumblr](https://www.tumblr.com/docs/en/api/v2#auth)
+* [Slack](https://api.slack.com/docs/oauth)
+* [Uber](https://developer.uber.com/v1/auth/)
+
+### Images
+
+
+
+
+
+## License
+
+OAuthSwift is available under the MIT license. See the LICENSE file for more info.
diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5500fc0
--- /dev/null
+++ b/Pods/Pods.xcodeproj/project.pbxproj
@@ -0,0 +1,1151 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 0103D8ADC957C070E1BFED518DDD6900 /* FirebaseApp.h in Headers */ = {isa = PBXBuildFile; fileRef = ABB38D22888780562B262D11932C78F0 /* FirebaseApp.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 01AC11A36A221FC1F0CE70876A1A7586 /* FQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 977AA135061BAADD0E97425779426F39 /* FQuery.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 01D9804232F3A658600E6651F4ADEF3F /* OAuthSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 26025C55A2A6320F12FB8874A7419C24 /* OAuthSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 01DC315B8E4A5DA6216FE8033489CCF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A02ECAC7E8BB25866EDEDE9E00EADB /* Security.framework */; };
+ 02318F60A80AC6CCE01EABB52C2A051F /* NSURL+OAuthSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ECBB90E0EC66D38F6A567A1BE920B73 /* NSURL+OAuthSwift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 043798CB0DE84D7DF08B7FA25B4CA398 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4EC4B75BAE91861986227C1BE7B931E /* Foundation.framework */; };
+ 043ACF4069829331FCC81B76F1AC52E8 /* Firebase-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F91EE57841886DC1D2F09E2F64F895E7 /* Firebase-dummy.m */; };
+ 0AF8775E2C1FD7CD6010AFB1F89E00D5 /* Pods-comblie-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 48472FB72C109D9D81EE0E9344F704B5 /* Pods-comblie-dummy.m */; };
+ 0BE383DCC29A6485B10DDFCC2A5C8C54 /* OAuthWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4686C6F5BDE76A75455220951A19C757 /* OAuthWebViewController.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 0CA09F60F6B4EB0C8290D0D294651872 /* FAuthData.h in Headers */ = {isa = PBXBuildFile; fileRef = 009B15AAF7D867F2E7AA8313AC1E54B2 /* FAuthData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 12A5BBB95CF5F3371D60F62D7410BB8C /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 01695C7AA532F1BA38C83390AD2A0260 /* Alamofire-dummy.m */; };
+ 1B29CDCC5D007ED85EDF1FCB2F7D9672 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991709335D7C876885ED1CBCF1C678AF /* Validation.swift */; };
+ 1F80999603FA40AD9B651FBA250AB22B /* FDataSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FE8E6A2E92B01F8ADBC7D4348F963C6 /* FDataSnapshot.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 202058A665BE8CA72F108E2713EC287F /* FEventType.h in Headers */ = {isa = PBXBuildFile; fileRef = EA5EADFD10CABCB031973E143D629E12 /* FEventType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2213EADDD7605C183FEFEA84D89AA1EB /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36A7D1DB78C0DF86B60CEFF30D80B68 /* HMAC.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 23F5940A08DB5F0B129F9DFF7CCC3452 /* SwiftyJSON-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 85E62DA073C367ACFC8C77B0B6180FD1 /* SwiftyJSON-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 286A2B1D7C1032A64D7E83353BC993A6 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A96F7E4D90F73AB23A0E393600A0B384 /* SystemConfiguration.framework */; };
+ 3312AAE06F014BF5531DDD056C2186BB /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19925FCC32D2AC1B8B451E6F49AFBA8C /* ParameterEncoding.swift */; };
+ 3769B9433B301E32A9DC200E73038AF3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4EC4B75BAE91861986227C1BE7B931E /* Foundation.framework */; };
+ 39A8A7DB3537BDC61EF618B1737C1EB5 /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F861572AEF58AF8E8738463397C601 /* SwiftyJSON.swift */; };
+ 3C39C20F909555BD7AD05BCE12D85E64 /* FTransactionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = D59B74DF870630BD94CFDE291FA81394 /* FTransactionResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 3F59C23EEDEECACC0F3DD3F461CA386D /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 12E2E56CB6AF65496CD3028C8FE1569A /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 486940176BB4B652E72D16FA36901F39 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4EC4B75BAE91861986227C1BE7B931E /* Foundation.framework */; };
+ 4F3B7E8FA25233305FAA50CE157913FA /* Firebase.h in Headers */ = {isa = PBXBuildFile; fileRef = 792F1691BBA2C4B2F808D440CDEFE659 /* Firebase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 4FFC0C6DB0D09D9E4BEB396E8ACF3786 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4EC4B75BAE91861986227C1BE7B931E /* Foundation.framework */; };
+ 5A5CD1EFDE3D7A89643275861DBF333E /* Upload.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD3C31F541FBA6C801CE2CCC5AAE5C6A /* Upload.swift */; };
+ 5DB655EC4F9707E7C094121F98AAE0E7 /* Empty.m in Sources */ = {isa = PBXBuildFile; fileRef = 4361A13198C5C4E0D73FAA805BE3E16A /* Empty.m */; };
+ 5F1CC5C657D904F75061C727BD6E66BD /* FConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F52191E7503950603319B91A50E74C /* FConfig.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 65A14AF2292C741A22A7BC8984651855 /* Pods-comblie-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F8A0FF889493AA1F9FE2B2F671C08DF /* Pods-comblie-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 66FA73AD89C0B485780F41988D44E923 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AC3E9F145A3A859B867E06E3DCD61C8F /* CFNetwork.framework */; };
+ 6D8D0CBBE0C5FE01A1F9C37F2E081991 /* String+OAuthSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 094D2B6860F9B5CA9C6AAB2B82F76EE7 /* String+OAuthSwift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 6E3BD9070780888A7295661633EF5D40 /* OAuthSwiftCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FBF44922D8622A3618D37B6D8A6728E /* OAuthSwiftCredential.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 719C18DFDDE60570EB6E923E35F6032E /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6090F9AD0C02A0D59DC0CE8042B98B /* SHA1.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 7C09C45429B6F5A90DB192A244DD515E /* Download.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA21B09D9611B09E1A37D5A9647F0EB5 /* Download.swift */; };
+ 82C2E7A0ED4D045F8FBEED5C61AA680E /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 701EFD0B515E117F302CB155EABE3084 /* Request.swift */; };
+ 8A5D53198CFD14FFDC5E4EE766EF7893 /* FirebaseServerValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E0A9B8455C5698BAF20658B659F99B6 /* FirebaseServerValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 8BF5150718B77DAD527B94D0F0FF0F10 /* Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8493E9098F7C797FD21609BC9AE7E1E5 /* Manager.swift */; };
+ 90EF20BB8DC0A183A97CEE5D4BE375EE /* SwiftyJSON-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A0D3575B7F9DE11C652ED4F55D4D976B /* SwiftyJSON-dummy.m */; };
+ 93BFC6876A031FC86A2B3623693565C0 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3836F7F0603DB4A9C59DC4F73AE1DFB2 /* Result.swift */; };
+ 97960DC89864E88E39ADCDE233FC097B /* Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF6B78E27D2BACC2EF7E6B7E176DC23 /* Stream.swift */; };
+ 99E33802005F524735BA8FAAB881CC3C /* Dictionary+OAuthSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C49981A9F94EA6AA9FF8AE1FC4D7ABC /* Dictionary+OAuthSwift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ 9BA3EA6830EA4D0B8AFFD867140A0211 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC0680E3B78041FDC9F0BC518FDB71C9 /* Error.swift */; };
+ A02B2D342B323AD116B9546B74CBCC3F /* Int+OAuthSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC7A35ACC545884E04AF217173E37F0B /* Int+OAuthSwift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ A7C69A4D06FF14710AADB3CD114628A3 /* OAuthSwiftHTTPRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D115C5D1B90C6293F94A6795FC89791 /* OAuthSwiftHTTPRequest.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ AC1C33AE02B5EAB9B0EC2C0E4253D9B2 /* FAuthType.h in Headers */ = {isa = PBXBuildFile; fileRef = A74F6EFA890B28426D901B560290B026 /* FAuthType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ AEFFB7733138366A0E2E27C4EBE20F5C /* OAuth2Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A10B34CDC47C8BAF8AC7C7275DAD79 /* OAuth2Swift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ B385D6839DA724C1DA457E79B1D9C547 /* Firebase-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 629B84A4FE970BE566C46F39495F3006 /* Firebase-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ B63520B33B9D2B5FCF6370FE89024923 /* NSData+OAuthSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 267B5EDA018E34D9E7C6F14974F269AF /* NSData+OAuthSwift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ C504C0BFADE77993BACC45B0ED4EC761 /* OAuthSwiftURLHandlerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80241F16119A39EB51A168CA5C769608 /* OAuthSwiftURLHandlerType.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ C56AD3C3C4A0EE00434DC1DCA799AF78 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4EC4B75BAE91861986227C1BE7B931E /* Foundation.framework */; };
+ CB5AC02BE39708AB9A7E3601B6EC97D7 /* OAuthSwiftClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D082E608259330265B0E4CDF04D387 /* OAuthSwiftClient.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ CDC54AEF580D67F9D8D67D57EADEEFD2 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9F7C97E8874BD8604AC24C14175E88 /* ResponseSerialization.swift */; };
+ CE794890A3FBE1FE6F46125CB5A1F088 /* OAuthSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388DA150FADDE8E83474737C5A2AC3 /* OAuthSwift-dummy.m */; };
+ CFFE8DEA60E3068C58E1B9CBA07C1B97 /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BA20233F1BEC833FC6E3D263F5BB683 /* ServerTrustPolicy.swift */; };
+ EB35FAC38EB920620E8365DBE14EDEE0 /* OAuth1Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B0EE6C827479BF66A2BC67421DCBB2E /* OAuth1Swift.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ ED2CF3BF11D6D20A6AE317E7A66DC05D /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF8078A8C9B4CD73363E9653E4187E1 /* MultipartFormData.swift */; };
+ F004D6B0FCD1111C03CB85AB1F836856 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2138DEFE934152A21A6E20B0C92C3D30 /* Utils.swift */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
+ F5EFEA9410F95C9DA0D077AB6F721AA2 /* FMutableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 287278401E1824A746D1DCB658E77CA1 /* FMutableData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F763EB470CB69131B3B95A14E0014C02 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 254DFF1266651829D1DA13273D81A53B /* Alamofire.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 429953472B93397FA1437677712AE8E1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 0450C045C8EC2F1E697DCFCFE157596C;
+ remoteInfo = Alamofire;
+ };
+ 6C14C2B93CF0E5DED03B42D78398B16B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B9A04D3C9B208813656510FDA8ADAE02;
+ remoteInfo = SwiftyJSON;
+ };
+ D2E610142D0BF15113FF7C5642F4DE94 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 486EE5935B8DBF81B1B8E6C117CF5250;
+ remoteInfo = Firebase;
+ };
+ DA1CD79910792654A11230291DFB37F6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 87643FB293F2706D7B7C15B1271B7A32;
+ remoteInfo = OAuthSwift;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 009B15AAF7D867F2E7AA8313AC1E54B2 /* FAuthData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FAuthData.h; sourceTree = ""; };
+ 00B4E3583731341090CAA62EA2BE287C /* Firebase-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Firebase-prefix.pch"; sourceTree = ""; };
+ 01695C7AA532F1BA38C83390AD2A0260 /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; };
+ 02D082E608259330265B0E4CDF04D387 /* OAuthSwiftClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuthSwiftClient.swift; path = OAuthSwift/OAuthSwiftClient.swift; sourceTree = ""; };
+ 03B4502D425103257E8746E7BB91A521 /* Alamofire-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Alamofire-Private.xcconfig"; sourceTree = ""; };
+ 094D2B6860F9B5CA9C6AAB2B82F76EE7 /* String+OAuthSwift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+OAuthSwift.swift"; path = "OAuthSwift/String+OAuthSwift.swift"; sourceTree = ""; };
+ 0CB90F8FAAEFBF644E26169827C66366 /* Firebase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.xcconfig; sourceTree = ""; };
+ 0D115C5D1B90C6293F94A6795FC89791 /* OAuthSwiftHTTPRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuthSwiftHTTPRequest.swift; path = OAuthSwift/OAuthSwiftHTTPRequest.swift; sourceTree = ""; };
+ 0D9706D2D2713980FDDF6F259703300B /* Firebase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Firebase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0DF6B78E27D2BACC2EF7E6B7E176DC23 /* Stream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Stream.swift; path = Source/Stream.swift; sourceTree = ""; };
+ 12E2E56CB6AF65496CD3028C8FE1569A /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; };
+ 14EAE12DA19598E66F93EECD456C7D91 /* SwiftyJSON-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "SwiftyJSON-Private.xcconfig"; sourceTree = ""; };
+ 154CADC8C2D981A30E2D386CFB84F89B /* SwiftyJSON-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-prefix.pch"; sourceTree = ""; };
+ 15A6F99A3C8BAFFE897FEE63D3882899 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 1605E7748BA74F4B74153924DAA88122 /* libFirebaseStatic.a */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = archive.ar; path = libFirebaseStatic.a; sourceTree = ""; };
+ 18E6FFAE4855C465A88254FD76FF768D /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 19925FCC32D2AC1B8B451E6F49AFBA8C /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; };
+ 1BF8078A8C9B4CD73363E9653E4187E1 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; };
+ 2138DEFE934152A21A6E20B0C92C3D30 /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = OAuthSwift/Utils.swift; sourceTree = ""; };
+ 24388DA150FADDE8E83474737C5A2AC3 /* OAuthSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "OAuthSwift-dummy.m"; sourceTree = ""; };
+ 254DFF1266651829D1DA13273D81A53B /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; };
+ 26025C55A2A6320F12FB8874A7419C24 /* OAuthSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OAuthSwift-umbrella.h"; sourceTree = ""; };
+ 267B5EDA018E34D9E7C6F14974F269AF /* NSData+OAuthSwift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSData+OAuthSwift.swift"; path = "OAuthSwift/NSData+OAuthSwift.swift"; sourceTree = ""; };
+ 2747548514DB259F9AAC58468EDAA0EF /* Firebase-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Firebase-Private.xcconfig"; sourceTree = ""; };
+ 280F0E52C7FBA3C38B0E5B89CAEDCF84 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 287278401E1824A746D1DCB658E77CA1 /* FMutableData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FMutableData.h; sourceTree = ""; };
+ 2F8A0FF889493AA1F9FE2B2F671C08DF /* Pods-comblie-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-comblie-umbrella.h"; sourceTree = ""; };
+ 31F861572AEF58AF8E8738463397C601 /* SwiftyJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftyJSON.swift; path = Source/SwiftyJSON.swift; sourceTree = ""; };
+ 3836F7F0603DB4A9C59DC4F73AE1DFB2 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Source/Result.swift; sourceTree = ""; };
+ 388B38D06B1E0F6E6CF21392D854A86B /* OAuthSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = OAuthSwift.modulemap; sourceTree = ""; };
+ 3AF3803E2A79F4B307857DF277749BA6 /* SwiftyJSON.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.xcconfig; sourceTree = ""; };
+ 3E0A9B8455C5698BAF20658B659F99B6 /* FirebaseServerValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FirebaseServerValue.h; sourceTree = ""; };
+ 4361A13198C5C4E0D73FAA805BE3E16A /* Empty.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = Empty.m; sourceTree = ""; };
+ 4686C6F5BDE76A75455220951A19C757 /* OAuthWebViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuthWebViewController.swift; path = OAuthSwift/OAuthWebViewController.swift; sourceTree = ""; };
+ 48472FB72C109D9D81EE0E9344F704B5 /* Pods-comblie-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-comblie-dummy.m"; sourceTree = ""; };
+ 493022CA7EF92D0D91D4E7FFFCF792B9 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4A45348CE55A2083D4A97647E6623E22 /* SwiftyJSON.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SwiftyJSON.modulemap; sourceTree = ""; };
+ 4C49981A9F94EA6AA9FF8AE1FC4D7ABC /* Dictionary+OAuthSwift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Dictionary+OAuthSwift.swift"; path = "OAuthSwift/Dictionary+OAuthSwift.swift"; sourceTree = ""; };
+ 4FBF44922D8622A3618D37B6D8A6728E /* OAuthSwiftCredential.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuthSwiftCredential.swift; path = OAuthSwift/OAuthSwiftCredential.swift; sourceTree = ""; };
+ 53655465C728EFE252DF4064A85573DA /* Pods-comblie.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-comblie.release.xcconfig"; sourceTree = ""; };
+ 5606521C8BDFCAC7F0844381A732BE8F /* Pods-comblie-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-comblie-frameworks.sh"; sourceTree = ""; };
+ 5D7F41E0EA4F2498211329CDC42D77C2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 5ECBB90E0EC66D38F6A567A1BE920B73 /* NSURL+OAuthSwift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSURL+OAuthSwift.swift"; path = "OAuthSwift/NSURL+OAuthSwift.swift"; sourceTree = ""; };
+ 629B84A4FE970BE566C46F39495F3006 /* Firebase-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Firebase-umbrella.h"; sourceTree = ""; };
+ 6B0EE6C827479BF66A2BC67421DCBB2E /* OAuth1Swift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuth1Swift.swift; path = OAuthSwift/OAuth1Swift.swift; sourceTree = ""; };
+ 701EFD0B515E117F302CB155EABE3084 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; };
+ 708A11767483ADC41DD248CFA3A5D204 /* OAuthSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OAuthSwift-prefix.pch"; sourceTree = ""; };
+ 7237BB2BB4A6149B799C1DDE96AB8E4D /* Pods_comblie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_comblie.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 792F1691BBA2C4B2F808D440CDEFE659 /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = Firebase.h; sourceTree = ""; };
+ 7B5B353AB52D65782F32FBE3E4A653F2 /* Pods-comblie-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-comblie-acknowledgements.markdown"; sourceTree = ""; };
+ 80241F16119A39EB51A168CA5C769608 /* OAuthSwiftURLHandlerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OAuthSwiftURLHandlerType.swift; path = OAuthSwift/OAuthSwiftURLHandlerType.swift; sourceTree = ""; };
+ 8432F164D8777AE30B46B06B8FC2D722 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = "