diff --git a/Example/Parse.framework/Headers b/Example/Parse.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/Example/Parse.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Example/Parse.framework/Parse b/Example/Parse.framework/Parse new file mode 120000 index 0000000..1354084 --- /dev/null +++ b/Example/Parse.framework/Parse @@ -0,0 +1 @@ +Versions/Current/Parse \ No newline at end of file diff --git a/Example/Parse.framework/Resources b/Example/Parse.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/Example/Parse.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFACL.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFACL.h new file mode 100644 index 0000000..217eb0e --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFACL.h @@ -0,0 +1,198 @@ +// PFACL.h +// Copyright 2011 Parse, Inc. All rights reserved. + +#import + +@class PFUser; +@class PFRole; + +/*! + A PFACL is used to control which users can access or modify a particular + object. Each PFObject can have its own PFACL. You can grant + read and write permissions separately to specific users, to groups of users + that belong to roles, or you can grant permissions to "the public" so that, + for example, any user could read a particular object but only a particular + set of users could write to that object. + */ +@interface PFACL : NSObject + +/** @name Creating an ACL */ + +/*! + Creates an ACL with no permissions granted. + */ ++ (PFACL *)ACL; + +/*! + Creates an ACL where only the provided user has access. + */ ++ (PFACL *)ACLWithUser:(PFUser *)user; + +/** @name Controlling Public Access */ + +/*! + Set whether the public is allowed to read this object. + */ +- (void)setPublicReadAccess:(BOOL)allowed; + +/*! + Gets whether the public is allowed to read this object. + */ +- (BOOL)getPublicReadAccess; + +/*! + Set whether the public is allowed to write this object. + */ +- (void)setPublicWriteAccess:(BOOL)allowed; + +/*! + Gets whether the public is allowed to write this object. + */ +- (BOOL)getPublicWriteAccess; + +/** @name Controlling Access Per-User */ + +/*! + Set whether the given user id is allowed to read this object. + */ +- (void)setReadAccess:(BOOL)allowed forUserId:(NSString *)userId; + +/*! + Gets whether the given user id is *explicitly* allowed to read this object. + Even if this returns NO, the user may still be able to access it if getPublicReadAccess returns YES + or if the user belongs to a role that has access. + */ +- (BOOL)getReadAccessForUserId:(NSString *)userId; + +/*! + Set whether the given user id is allowed to write this object. + */ +- (void)setWriteAccess:(BOOL)allowed forUserId:(NSString *)userId; + +/*! + Gets whether the given user id is *explicitly* allowed to write this object. + Even if this returns NO, the user may still be able to write it if getPublicWriteAccess returns YES + or if the user belongs to a role that has access. + */ +- (BOOL)getWriteAccessForUserId:(NSString *)userId; + +/*! + Set whether the given user is allowed to read this object. + */ +- (void)setReadAccess:(BOOL)allowed forUser:(PFUser *)user; + +/*! + Gets whether the given user is *explicitly* allowed to read this object. + Even if this returns NO, the user may still be able to access it if getPublicReadAccess returns YES + or if the user belongs to a role that has access. + */ +- (BOOL)getReadAccessForUser:(PFUser *)user; + +/*! + Set whether the given user is allowed to write this object. + */ +- (void)setWriteAccess:(BOOL)allowed forUser:(PFUser *)user; + +/*! + Gets whether the given user is *explicitly* allowed to write this object. + Even if this returns NO, the user may still be able to write it if getPublicWriteAccess returns YES + or if the user belongs to a role that has access. + */ +- (BOOL)getWriteAccessForUser:(PFUser *)user; + +/** @name Controlling Access Per-Role */ + +/*! + Get whether users belonging to the role with the given name are allowed + to read this object. Even if this returns false, the role may still + be able to read it if a parent role has read access. + + @param name The name of the role. + @return YES if the role has read access. NO otherwise. + */ +- (BOOL)getReadAccessForRoleWithName:(NSString *)name; + +/*! + Set whether users belonging to the role with the given name are allowed + to read this object. + + @param name The name of the role. + @param allowed Whether the given role can read this object. + */ +- (void)setReadAccess:(BOOL)allowed forRoleWithName:(NSString *)name; + +/*! + Get whether users belonging to the role with the given name are allowed + to write this object. Even if this returns false, the role may still + be able to write it if a parent role has write access. + + @param name The name of the role. + @return YES if the role has read access. NO otherwise. + */ +- (BOOL)getWriteAccessForRoleWithName:(NSString *)name; + +/*! + Set whether users belonging to the role with the given name are allowed + to write this object. + + @param name The name of the role. + @param allowed Whether the given role can write this object. + */ +- (void)setWriteAccess:(BOOL)allowed forRoleWithName:(NSString *)name; + +/*! + Get whether users belonging to the given role are allowed to read this + object. Even if this returns NO, the role may still be able to + read it if a parent role has read access. The role must already be saved on + the server and its data must have been fetched in order to use this method. + + @param role The name of the role. + @return YES if the role has read access. NO otherwise. + */ +- (BOOL)getReadAccessForRole:(PFRole *)role; + +/*! + Set whether users belonging to the given role are allowed to read this + object. The role must already be saved on the server and its data must have + been fetched in order to use this method. + + @param role The role to assign access. + @param allowed Whether the given role can read this object. + */ +- (void)setReadAccess:(BOOL)allowed forRole:(PFRole *)role; + +/*! + Get whether users belonging to the given role are allowed to write this + object. Even if this returns NO, the role may still be able to + write it if a parent role has write access. The role must already be saved on + the server and its data must have been fetched in order to use this method. + + @param role The name of the role. + @return YES if the role has write access. NO otherwise. + */ +- (BOOL)getWriteAccessForRole:(PFRole *)role; + +/*! + Set whether users belonging to the given role are allowed to write this + object. The role must already be saved on the server and its data must have + been fetched in order to use this method. + + @param role The role to assign access. + @param allowed Whether the given role can write this object. + */ +- (void)setWriteAccess:(BOOL)allowed forRole:(PFRole *)role; + +/** @name Setting Access Defaults */ + +/*! + Sets a default ACL that will be applied to all PFObjects when they are created. + @param acl The ACL to use as a template for all PFObjects created after setDefaultACL has been called. + This value will be copied and used as a template for the creation of new ACLs, so changes to the + instance after setDefaultACL has been called will not be reflected in new PFObjects. + @param currentUserAccess If true, the PFACL that is applied to newly-created PFObjects will + provide read and write access to the currentUser at the time of creation. If false, + the provided ACL will be used without modification. If acl is nil, this value is ignored. + */ ++ (void)setDefaultACL:(PFACL *)acl withAccessForCurrentUser:(BOOL)currentUserAccess; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFAnalytics.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFAnalytics.h new file mode 100644 index 0000000..3a19941 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFAnalytics.h @@ -0,0 +1,73 @@ +// +// PFAnalytics.h +// Parse +// +// Created by Christine Yen on 1/29/13. +// Copyright (c) 2013 Parse Inc. All rights reserved. +// + +#import + +/*! + PFAnalytics provides an interface to Parse's logging and analytics backend. + + Methods will return immediately and cache the request (+ timestamp) to be + handled "eventually." That is, the request will be sent immediately if possible + or the next time a network connection is available otherwise. + */ +@interface PFAnalytics : NSObject + +/*! + Tracks this application being launched. If this happened as the result of the + user opening a push notification, this method sends along information to + correlate this open with that push. + + Pass in nil to track a standard "application opened" event. + + @param launchOptions The dictionary indicating the reason the application was + launched, if any. This value can be found as a parameter to various + UIApplicationDelegate methods, and can be empty or nil. + */ ++ (void)trackAppOpenedWithLaunchOptions:(NSDictionary *)launchOptions; + +/*! + Tracks this application being launched. If this happened as the result of the + user opening a push notification, this method sends along information to + correlate this open with that push. + + @param userInfo The Remote Notification payload, if any. This value can be + found either under UIApplicationLaunchOptionsRemoteNotificationKey on + launchOptions, or as a parameter to application:didReceiveRemoteNotification:. + This can be empty or nil. + */ ++ (void)trackAppOpenedWithRemoteNotificationPayload:(NSDictionary *)userInfo; + +/*! + Tracks the occurrence of a custom event. Parse will store a data point at the + time of invocation with the given event name. + + @param name The name of the custom event to report to Parse as having happened. + */ ++ (void)trackEvent:(NSString *)name; + +/*! + Tracks the occurrence of a custom event with additional dimensions. Parse will + store a data point at the time of invocation with the given event name. + + Dimensions will allow segmentation of the occurrences of this custom event. + Keys and values should be NSStrings, and will throw otherwise. + + To track a user signup along with additional metadata, consider the following: + NSDictionary *dimensions = @{ @"gender": @"m", + @"source": @"web", + @"dayType": @"weekend" }; + [PFAnalytics trackEvent:@"signup" dimensions:dimensions]; + + There is a default limit of 4 dimensions per event tracked. + + @param name The name of the custom event to report to Parse as having happened. + @param dimensions The dictionary of information by which to segment this event. + */ ++ (void)trackEvent:(NSString *)name dimensions:(NSDictionary *)dimensions; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFAnonymousUtils.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFAnonymousUtils.h new file mode 100644 index 0000000..179fb43 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFAnonymousUtils.h @@ -0,0 +1,57 @@ +// +// PFAnonymousUtils.h +// Parse +// +// Created by David Poll on 3/20/12. +// Copyright (c) 2012 Parse, Inc. All rights reserved. +// + +#import +#import "PFUser.h" +#import "PFConstants.h" + +/*! + Provides utility functions for working with Anonymously logged-in users. Anonymous users have some unique characteristics: +
    +
  • Anonymous users don't need a user name or password.
  • +
  • Once logged out, an anonymous user cannot be recovered.
  • +
  • When the current user is anonymous, the following methods can be used to switch to a different user or convert the + anonymous user into a regular one: +
      +
    • signUp converts an anonymous user to a standard user with the given username and password. + Data associated with the anonymous user is retained.
    • +
    • logIn switches users without converting the anonymous user. Data associated with the anonymous user will be lost.
    • +
    • Service logIn (e.g. Facebook, Twitter) will attempt to convert the anonymous user into a standard user by linking it to the service. + If a user already exists that is linked to the service, it will instead switch to the existing user.
    • +
    • Service linking (e.g. Facebook, Twitter) will convert the anonymous user into a standard user by linking it to the service.
    • +
    +
+ */ +@interface PFAnonymousUtils : NSObject + +/*! @name Creating an Anonymous User */ + +/*! + Creates an anonymous user. + @param block The block to execute when anonymous user creation is complete. The block should have the following argument signature: + (PFUser *user, NSError *error) + */ ++ (void)logInWithBlock:(PFUserResultBlock)block; + +/*! + Creates an anonymous user. The selector for the callback should look like: (PFUser *)user error:(NSError *)error + @param target Target object for the selector. + @param selector The selector that will be called when the asynchronous request is complete. + */ ++ (void)logInWithTarget:(id)target selector:(SEL)selector; + +/*! @name Determining Whether a PFUser is Anonymous */ + +/*! + Whether the user is logged in anonymously. + @param user User to check for anonymity. The user must be logged in on this device. + @result True if the user is anonymous. False if the user is not the current user or is not anonymous. + */ ++ (BOOL)isLinkedWithUser:(PFUser *)user; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFCloud.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFCloud.h new file mode 100644 index 0000000..45f2421 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFCloud.h @@ -0,0 +1,47 @@ +// +// PFCloud.h +// Parse +// +// Created by Shyam Jayaraman on 8/20/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import "PFConstants.h" + +@interface PFCloud : NSObject + +/*! + Calls the given cloud function with the parameters passed in. + @param function The function name to call. + @param parameters The parameters to send to the function. + @result The response from the cloud function. + */ ++ (id)callFunction:(NSString *)function withParameters:(NSDictionary *)parameters; + +/*! + Calls the given cloud function with the parameters passed in and sets the error if there is one. + @param function The function name to call. + @param parameters The parameters to send to the function. + @param error Pointer to an NSError that will be set if necessary. + @result The response from the cloud function. This result could be a NSDictionary, an NSArray, NSInteger or NSString. + */ ++ (id)callFunction:(NSString *)function withParameters:(NSDictionary *)parameters error:(NSError **)error; + +/*! + Calls the given cloud function with the parameters provided asynchronously and calls the given block when it is done. + @param function The function name to call. + @param parameters The parameters to send to the function. + @param block The block to execute. The block should have the following argument signature:(id result, NSError *error). + */ ++ (void)callFunctionInBackground:(NSString *)function withParameters:(NSDictionary *)parameters block:(PFIdResultBlock)block; + +/*! + Calls the given cloud function with the parameters provided asynchronously and runs the callback when it is done. + @param function The function name to call. + @param parameters The parameters to send to the function. + @param target The object to call the selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(id) result error:(NSError *)error. result will be nil if error is set and vice versa. + */ ++ (void)callFunctionInBackground:(NSString *)function withParameters:(NSDictionary *)parameters target:(id)target selector:(SEL)selector; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFConstants.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFConstants.h new file mode 100644 index 0000000..f61b82b --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFConstants.h @@ -0,0 +1,160 @@ +// PFConstants.h +// Copyright 2011 Parse, Inc. All rights reserved. + +#import +@class PFObject; +@class PFUser; + +// Version +#define PARSE_VERSION @"1.2.18" + +extern NSInteger const PARSE_API_VERSION; + +// Platform +#define PARSE_IOS_ONLY (TARGET_OS_IPHONE) +#define PARSE_OSX_ONLY (TARGET_OS_MAC && !(TARGET_OS_IPHONE)) + +extern NSString *const kPFDeviceType; + +#if PARSE_IOS_ONLY +#import +#else +#import +@compatibility_alias UIImage NSImage; +@compatibility_alias UIColor NSColor; +@compatibility_alias UIView NSView; +#endif + +// Server +extern NSString *const kPFParseServer; + +// Cache policies +typedef enum { + kPFCachePolicyIgnoreCache = 0, + kPFCachePolicyCacheOnly, + kPFCachePolicyNetworkOnly, + kPFCachePolicyCacheElseNetwork, + kPFCachePolicyNetworkElseCache, + kPFCachePolicyCacheThenNetwork +} PFCachePolicy; + +// Errors + +/*! @abstract 1: Internal server error. No information available. */ +extern NSInteger const kPFErrorInternalServer; + +/*! @abstract 100: The connection to the Parse servers failed. */ +extern NSInteger const kPFErrorConnectionFailed; +/*! @abstract 101: Object doesn't exist, or has an incorrect password. */ +extern NSInteger const kPFErrorObjectNotFound; +/*! @abstract 102: You tried to find values matching a datatype that doesn't support exact database matching, like an array or a dictionary. */ +extern NSInteger const kPFErrorInvalidQuery; +/*! @abstract 103: Missing or invalid classname. Classnames are case-sensitive. They must start with a letter, and a-zA-Z0-9_ are the only valid characters. */ +extern NSInteger const kPFErrorInvalidClassName; +/*! @abstract 104: Missing object id. */ +extern NSInteger const kPFErrorMissingObjectId; +/*! @abstract 105: Invalid key name. Keys are case-sensitive. They must start with a letter, and a-zA-Z0-9_ are the only valid characters. */ +extern NSInteger const kPFErrorInvalidKeyName; +/*! @abstract 106: Malformed pointer. Pointers must be arrays of a classname and an object id. */ +extern NSInteger const kPFErrorInvalidPointer; +/*! @abstract 107: Malformed json object. A json dictionary is expected. */ +extern NSInteger const kPFErrorInvalidJSON; +/*! @abstract 108: Tried to access a feature only available internally. */ +extern NSInteger const kPFErrorCommandUnavailable; +/*! @abstract 111: Field set to incorrect type. */ +extern NSInteger const kPFErrorIncorrectType; +/*! @abstract 112: Invalid channel name. A channel name is either an empty string (the broadcast channel) or contains only a-zA-Z0-9_ characters and starts with a letter. */ +extern NSInteger const kPFErrorInvalidChannelName; +/*! @abstract 114: Invalid device token. */ +extern NSInteger const kPFErrorInvalidDeviceToken; +/*! @abstract 115: Push is misconfigured. See details to find out how. */ +extern NSInteger const kPFErrorPushMisconfigured; +/*! @abstract 116: The object is too large. */ +extern NSInteger const kPFErrorObjectTooLarge; +/*! @abstract 119: That operation isn't allowed for clients. */ +extern NSInteger const kPFErrorOperationForbidden; +/*! @abstract 120: The results were not found in the cache. */ +extern NSInteger const kPFErrorCacheMiss; +/*! @abstract 121: Keys in NSDictionary values may not include '$' or '.'. */ +extern NSInteger const kPFErrorInvalidNestedKey; +/*! @abstract 122: Invalid file name. A file name contains only a-zA-Z0-9_. characters and is between 1 and 36 characters. */ +extern NSInteger const kPFErrorInvalidFileName; +/*! @abstract 123: Invalid ACL. An ACL with an invalid format was saved. This should not happen if you use PFACL. */ +extern NSInteger const kPFErrorInvalidACL; +/*! @abstract 124: The request timed out on the server. Typically this indicates the request is too expensive. */ +extern NSInteger const kPFErrorTimeout; +/*! @abstract 125: The email address was invalid. */ +extern NSInteger const kPFErrorInvalidEmailAddress; +/*! @abstract 137: A unique field was given a value that is already taken. */ +extern NSInteger const kPFErrorDuplicateValue; +/*! @abstract 139: Role's name is invalid. */ +extern NSInteger const kPFErrorInvalidRoleName; +/*! @abstract 140: Exceeded an application quota. Upgrade to resolve. */ +extern NSInteger const kPFErrorExceededQuota; +/*! @abstract 141: Cloud Code script had an error. */ +extern NSInteger const kPFScriptError; +/*! @abstract 142: Cloud Code validation failed. */ +extern NSInteger const kPFValidationError; +/*! @abstract 143: Product purchase receipt is missing */ +extern NSInteger const kPFErrorReceiptMissing; +/*! @abstract 144: Product purchase receipt is invalid */ +extern NSInteger const kPFErrorInvalidPurchaseReceipt; +/*! @abstract 145: Payment is disabled on this device */ +extern NSInteger const kPFErrorPaymentDisabled; +/*! @abstract 146: The product identifier is invalid */ +extern NSInteger const kPFErrorInvalidProductIdentifier; +/*! @abstract 147: The product is not found in the App Store */ +extern NSInteger const kPFErrorProductNotFoundInAppStore; +/*! @abstract 148: The Apple server response is not valid */ +extern NSInteger const kPFErrorInvalidServerResponse; +/*! @abstract 149: Product fails to download due to file system error */ +extern NSInteger const kPFErrorProductDownloadFileSystemFailure; +/*! @abstract 150: Fail to convert data to image. */ +extern NSInteger const kPFErrorInvalidImageData; +/*! @abstract 151: Unsaved file. */ +extern NSInteger const kPFErrorUnsavedFile; +/*! @abstract 153: Fail to delete file. */ +extern NSInteger const kPFErrorFileDeleteFailure; + +/*! @abstract 200: Username is missing or empty */ +extern NSInteger const kPFErrorUsernameMissing; +/*! @abstract 201: Password is missing or empty */ +extern NSInteger const kPFErrorUserPasswordMissing; +/*! @abstract 202: Username has already been taken */ +extern NSInteger const kPFErrorUsernameTaken; +/*! @abstract 203: Email has already been taken */ +extern NSInteger const kPFErrorUserEmailTaken; +/*! @abstract 204: The email is missing, and must be specified */ +extern NSInteger const kPFErrorUserEmailMissing; +/*! @abstract 205: A user with the specified email was not found */ +extern NSInteger const kPFErrorUserWithEmailNotFound; +/*! @abstract 206: The user cannot be altered by a client without the session. */ +extern NSInteger const kPFErrorUserCannotBeAlteredWithoutSession; +/*! @abstract 207: Users can only be created through sign up */ +extern NSInteger const kPFErrorUserCanOnlyBeCreatedThroughSignUp; +/*! @abstract 208: An existing Facebook account already linked to another user. */ +extern NSInteger const kPFErrorFacebookAccountAlreadyLinked; +/*! @abstract 208: An existing account already linked to another user. */ +extern NSInteger const kPFErrorAccountAlreadyLinked; +/*! @abstract 209: User ID mismatch */ +extern NSInteger const kPFErrorUserIdMismatch; +/*! @abstract 250: Facebook id missing from request */ +extern NSInteger const kPFErrorFacebookIdMissing; +/*! @abstract 250: Linked id missing from request */ +extern NSInteger const kPFErrorLinkedIdMissing; +/*! @abstract 251: Invalid Facebook session */ +extern NSInteger const kPFErrorFacebookInvalidSession; +/*! @abstract 251: Invalid linked session */ +extern NSInteger const kPFErrorInvalidLinkedSession; + +typedef void (^PFBooleanResultBlock)(BOOL succeeded, NSError *error); +typedef void (^PFIntegerResultBlock)(int number, NSError *error); +typedef void (^PFArrayResultBlock)(NSArray *objects, NSError *error); +typedef void (^PFObjectResultBlock)(PFObject *object, NSError *error); +typedef void (^PFSetResultBlock)(NSSet *channels, NSError *error); +typedef void (^PFUserResultBlock)(PFUser *user, NSError *error); +typedef void (^PFDataResultBlock)(NSData *data, NSError *error); +typedef void (^PFDataStreamResultBlock)(NSInputStream *stream, NSError *error); +typedef void (^PFStringResultBlock)(NSString *string, NSError *error); +typedef void (^PFIdResultBlock)(id object, NSError *error); +typedef void (^PFProgressBlock)(int percentDone); diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFFacebookUtils.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFFacebookUtils.h new file mode 100644 index 0000000..1c10993 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFFacebookUtils.h @@ -0,0 +1,260 @@ +// +// PFFacebookUtils.h +// Copyright (c) 2012 Parse, Inc. All rights reserved. +// + +#import +#import + +#import "PFUser.h" +#import "PFConstants.h" + +/*! + Provides utility functions for working with Facebook in a Parse application. + + This class is currently for iOS only. + */ +@interface PFFacebookUtils : NSObject + +/** @name Interacting With Facebook */ + +/*! + Gets the Facebook session for the current user. + */ ++ (FBSession *)session; + +/*! + Deprecated. Please call [PFFacebookUtils initializeFacebook] instead. + */ ++ (void)initializeWithApplicationId:(NSString *)appId __attribute__ ((deprecated)); + +/*! + Deprecated. Please call [PFFacebookUtils initializeFacebookWithUrlSchemeSuffix:] instead. + */ ++ (void)initializeWithApplicationId:(NSString *)appId + urlSchemeSuffix:(NSString *)urlSchemeSuffix __attribute__ ((deprecated)); + +/*! + Initializes the Facebook singleton. You must invoke this in order to use the Facebook functionality in Parse. + You must provide your Facebook application ID as the value for FacebookAppID in your bundle's plist file as + described here: https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/ + */ ++ (void)initializeFacebook; + +/*! + Initializes the Facebook singleton. You must invoke this in order to use the Facebook functionality in Parse. + You must provide your Facebook application ID as the value for FacebookAppID in your bundle's plist file as + described here: https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/ + @param urlSchemeSuffix The URL suffix for this application - used when multiple applications with the same + Facebook application ID may be on the same device. + */ ++ (void)initializeFacebookWithUrlShemeSuffix:(NSString *)urlSchemeSuffix; + +/*! + Whether the user has their account linked to Facebook. + @param user User to check for a facebook link. The user must be logged in on this device. + @result True if the user has their account linked to Facebook. + */ ++ (BOOL)isLinkedWithUser:(PFUser *)user; + +/** @name Logging In & Creating Facebook-Linked Users */ + +/*! + Logs in a user using Facebook. This method delegates to the Facebook SDK to authenticate + the user, and then automatically logs in (or creates, in the case where it is a new user) + a PFUser. + @param permissions The permissions required for Facebook log in. This passed to the authorize method on + the Facebook instance. + @param block The block to execute. The block should have the following argument signature: + (PFUser *user, NSError *error) + */ ++ (void)logInWithPermissions:(NSArray *)permissions block:(PFUserResultBlock)block; + +/*! + Logs in a user using Facebook. This method delegates to the Facebook SDK to authenticate + the user, and then automatically logs in (or creates, in the case where it is a new user) + a PFUser. The selector for the callback should look like: (PFUser *)user error:(NSError **)error + @param permissions The permissions required for Facebook log in. This passed to the authorize method on + the Facebook instance. + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete. + */ ++ (void)logInWithPermissions:(NSArray *)permissions target:(id)target selector:(SEL)selector; + +/*! + Logs in a user using Facebook. Allows you to handle user login to Facebook, then provide authentication + data to log in (or create, in the case where it is a new user) the PFUser. + @param facebookId The id of the Facebook user being linked + @param accessToken The access token for the user's session + @param expirationDate The expiration date for the access token + @param block The block to execute. The block should have the following argument signature: + (PFUser *user, NSError *error) + */ ++ (void)logInWithFacebookId:(NSString *)facebookId + accessToken:(NSString *)accessToken + expirationDate:(NSDate *)expirationDate + block:(PFUserResultBlock)block; + +/*! + Logs in a user using Facebook. Allows you to handle user login to Facebook, then provide authentication + data to log in (or create, in the case where it is a new user) the PFUser. + The selector for the callback should look like: (PFUser *)user error:(NSError *)error + @param facebookId The id of the Facebook user being linked + @param accessToken The access token for the user's session + @param expirationDate The expiration date for the access token + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete + */ ++ (void)logInWithFacebookId:(NSString *)facebookId + accessToken:(NSString *)accessToken + expirationDate:(NSDate *)expirationDate + target:(id)target + selector:(SEL)selector; + +/** @name Linking Users with Facebook */ + +/*! + Links Facebook to an existing PFUser. This method delegates to the Facebook SDK to authenticate + the user, and then automatically links the account to the PFUser. + @param user User to link to Facebook. + @param permissions The permissions required for Facebook log in. This passed to the authorize method on + the Facebook instance. + */ ++ (void)linkUser:(PFUser *)user permissions:(NSArray *)permissions; + +/*! + Links Facebook to an existing PFUser. This method delegates to the Facebook SDK to authenticate + the user, and then automatically links the account to the PFUser. + @param user User to link to Facebook. + @param permissions The permissions required for Facebook log in. This passed to the authorize method on + the Facebook instance. + @param block The block to execute. The block should have the following argument signature: + (BOOL *success, NSError *error) + */ ++ (void)linkUser:(PFUser *)user permissions:(NSArray *)permissions block:(PFBooleanResultBlock)block; + +/*! + Links Facebook to an existing PFUser. This method delegates to the Facebook SDK to authenticate + the user, and then automatically links the account to the PFUser. + The selector for the callback should look like: (NSNumber *)result error:(NSError *)error + @param user User to link to Facebook. + @param permissions The permissions required for Facebook log in. This passed to the authorize method on + the Facebook instance. + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete. + */ ++ (void)linkUser:(PFUser *)user permissions:(NSArray *)permissions target:(id)target selector:(SEL)selector; + +/*! + Links Facebook to an existing PFUser. Allows you to handle user login to Facebook, then provide authentication + data to link the account to the PFUser. + @param user User to link to Facebook. + @param facebookId The id of the Facebook user being linked + @param accessToken The access token for the user's session + @param expirationDate The expiration date for the access token + @param block The block to execute. The block should have the following argument signature: + (BOOL *success, NSError *error) + */ ++ (void)linkUser:(PFUser *)user + facebookId:(NSString *)facebookId + accessToken:(NSString *)accessToken + expirationDate:(NSDate *)expirationDate + block:(PFBooleanResultBlock)block; + +/*! + Links Facebook to an existing PFUser. Allows you to handle user login to Facebook, then provide authentication + data to link the account to the PFUser. + The selector for the callback should look like: (NSNumber *)result error:(NSError *)error + @param user User to link to Facebook. + @param facebookId The id of the Facebook user being linked + @param accessToken The access token for the user's session + @param expirationDate The expiration date for the access token + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete + */ ++ (void)linkUser:(PFUser *)user + facebookId:(NSString *)facebookId + accessToken:(NSString *)accessToken + expirationDate:(NSDate *)expirationDate + target:(id)target + selector:(SEL)selector; + +/** @name Unlinking Users from Facebook */ + +/*! + Unlinks the PFUser from a Facebook account. + @param user User to unlink from Facebook. + @result Returns true if the unlink was successful. + */ ++ (BOOL)unlinkUser:(PFUser *)user; + +/*! + Unlinks the PFUser from a Facebook account. + @param user User to unlink from Facebook. + @param error Error object to set on error. + @result Returns true if the unlink was successful. + */ ++ (BOOL)unlinkUser:(PFUser *)user error:(NSError **)error; + +/*! + Makes an asynchronous request to unlink a user from a Facebook account. + @param user User to unlink from Facebook. + */ ++ (void)unlinkUserInBackground:(PFUser *)user; + +/*! + Makes an asynchronous request to unlink a user from a Facebook account. + @param user User to unlink from Facebook. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)unlinkUserInBackground:(PFUser *)user block:(PFBooleanResultBlock)block; + +/*! + Makes an asynchronous request to unlink a user from a Facebook account. + @param user User to unlink from Facebook + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete. + */ ++ (void)unlinkUserInBackground:(PFUser *)user target:(id)target selector:(SEL)selector; + +/** @name Obtaining new permissions */ + +/*! + Requests new Facebook publish permissions for the given user. This may prompt the user to + reauthorize the application. The user will be saved as part of this operation. + @param user User to request new permissions for. The user must be linked to Facebook. + @param permissions The new publishing permissions to request. + @param audience The default audience for publishing permissions to request. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)reauthorizeUser:(PFUser *)user + withPublishPermissions:(NSArray *)permissions + audience:(FBSessionDefaultAudience)audience + block:(PFBooleanResultBlock)block; + +/*! + Requests new Facebook publish permissions for the given user. This may prompt the user to + reauthorize the application. The user will be saved as part of this operation. + @param user User to request new permissions for. The user must be linked to Facebook. + @param permissions The new publishing permissions to request. + @param audience The default audience for publishing permissions to request. + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete. + */ ++ (void)reauthorizeUser:(PFUser *)user + withPublishPermissions:(NSArray *)permissions + audience:(FBSessionDefaultAudience)audience + target:(id)target + selector:(SEL)selector; + +/** @name Delegating URL Actions */ + +/*! + Deprecated. Instead, please use: + [FBAppCall handleOpenUrl:url + sourceApplication:sourceApplication + withSession:[PFFacebookUtils session]]; + */ ++ (BOOL)handleOpenURL:(NSURL *)url __attribute__ ((deprecated)); + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFFile.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFFile.h new file mode 100644 index 0000000..b579393 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFFile.h @@ -0,0 +1,197 @@ +// +// PFFile.h +// Parse +// +// Created by Ilya Sukhar on 10/11/11. +// Copyright 2011 Ping Labs, Inc. All rights reserved. +// + +#import +#import "PFConstants.h" + +/*! + A file of binary data stored on the Parse servers. This can be a image, video, or anything else + that an application needs to reference in a non-relational way. + */ +@interface PFFile : NSObject + +/** @name Creating a PFFile */ + +/*! + Creates a file with given data. A name will be assigned to it by the server. + @param data The contents of the new PFFile. + @result A PFFile. + */ ++ (id)fileWithData:(NSData *)data; + +/*! + Creates a file with given data and name. + @param name The name of the new PFFile. The file name must begin with and + alphanumeric character, and consist of alphanumeric characters, periods, + spaces, underscores, or dashes. + @param data The contents of hte new PFFile. + @result A PFFile. + */ ++ (id)fileWithName:(NSString *)name data:(NSData *)data; + +/*! + Creates a file with the contents of another file. + @param name The name of the new PFFile. The file name must begin with and + alphanumeric character, and consist of alphanumeric characters, periods, + spaces, underscores, or dashes. + @param path The path to the file that will be uploaded to Parse + */ ++ (id)fileWithName:(NSString *)name + contentsAtPath:(NSString *)path; + +/*! + The name of the file. Before save is called, this is the filename given by + the user. After save is called, that name gets prefixed with a unique + identifier. + */ +@property (assign, readonly) NSString *name; + +/*! + The url of the file. + */ +@property (assign, readonly) NSString *url; + +/** @name Storing Data with Parse */ + +/*! + Whether the file has been uploaded for the first time. + */ +@property (readonly) BOOL isDirty; + +/*! + Saves the file. + @result Returns whether the save succeeded. + */ +- (BOOL)save; + +/*! + Saves the file and sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the save succeeded. + */ +- (BOOL)save:(NSError **)error; + +/*! + Saves the file asynchronously. + */ +- (void)saveInBackground; + +/*! + Saves the file asynchronously and executes the given block. + @param block The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ +- (void)saveInBackgroundWithBlock:(PFBooleanResultBlock)block; + +/*! + Saves the file asynchronously and executes the given resultBlock. Executes the progressBlock periodically with the percent + progress. progressBlock will get called with 100 before resultBlock is called. + @param block The block should have the following argument signature: (BOOL succeeded, NSError *error) + @param progressBlock The block should have the following argument signature: (int percentDone) + */ +- (void)saveInBackgroundWithBlock:(PFBooleanResultBlock)block + progressBlock:(PFProgressBlock)progressBlock; + +/*! + Saves the file asynchronously and calls the given callback. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ +- (void)saveInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/** @name Getting Data from Parse */ + +/*! + Whether the data is available in memory or needs to be downloaded. + */ +@property (readonly) BOOL isDataAvailable; + +/*! + Gets the data from cache if available or fetches its contents from the Parse + servers. + @result The data. Returns nil if there was an error in fetching. + */ +- (NSData *)getData; + +/*! + This method is like getData but avoids ever holding the entire PFFile's + contents in memory at once. This can help applications with many large PFFiles + avoid memory warnings. + @result A stream containing the data. Returns nil if there was an error in + fetching. + */ +- (NSInputStream *)getDataStream; + +/*! + Gets the data from cache if available or fetches its contents from the Parse + servers. Sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + @result The data. Returns nil if there was an error in fetching. + */ +- (NSData *)getData:(NSError **)error; + +/*! + This method is like getData: but avoids ever holding the entire PFFile's + contents in memory at once. This can help applications with many large PFFiles + avoid memory warnings. Sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + @result A stream containing the data. Returns nil if there was an error in + fetching. + */ +- (NSInputStream *)getDataStream:(NSError **)error; + +/*! + Asynchronously gets the data from cache if available or fetches its contents + from the Parse servers. Executes the given block. + @param block The block should have the following argument signature: (NSData *result, NSError *error) + */ +- (void)getDataInBackgroundWithBlock:(PFDataResultBlock)block; + +/*! + This method is like getDataInBackgroundWithBlock: but avoids ever holding the + entire PFFile's contents in memory at once. This can help applications with + many large PFFiles avoid memory warnings. + @param block The block should have the following argument signature: (NSInputStream *result, NSError *error) + */ +- (void)getDataStreamInBackgroundWithBlock:(PFDataStreamResultBlock)block; + +/*! + Asynchronously gets the data from cache if available or fetches its contents + from the Parse servers. Executes the resultBlock upon + completion or error. Executes the progressBlock periodically with the percent progress. progressBlock will get called with 100 before resultBlock is called. + @param resultBlock The block should have the following argument signature: (NSData *result, NSError *error) + @param progressBlock The block should have the following argument signature: (int percentDone) + */ +- (void)getDataInBackgroundWithBlock:(PFDataResultBlock)resultBlock + progressBlock:(PFProgressBlock)progressBlock; + +/*! + This method is like getDataInBackgroundWithBlock:progressBlock: but avoids ever + holding the entire PFFile's contents in memory at once. This can help + applications with many large PFFiles avoid memory warnings. + @param resultBlock The block should have the following argument signature: (NSInputStream *result, NSError *error) + @param progressBlock The block should have the following argument signature: (int percentDone) + */ +- (void)getDataStreamInBackgroundWithBlock:(PFDataStreamResultBlock)resultBlock + progressBlock:(PFProgressBlock)progressBlock; + +/*! + Asynchronously gets the data from cache if available or fetches its contents + from the Parse servers. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSData *)result error:(NSError *)error. error will be nil on success and set if there was an error. + */ +- (void)getDataInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/** @name Interrupting a Transfer */ + +/*! + Cancels the current request (whether upload or download of file data). + */ +- (void)cancel; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFGeoPoint.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFGeoPoint.h new file mode 100644 index 0000000..f3ed279 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFGeoPoint.h @@ -0,0 +1,85 @@ +// +// PFGeoPoint.h +// Parse +// +// Created by Henele Adams on 12/1/11. +// Copyright (c) 2011 Parse, Inc. All rights reserved. +// + +#import +#import + +/*! + Object which may be used to embed a latitude / longitude point as the value for a key in a PFObject. + PFObjects with a PFGeoPoint field may be queried in a geospatial manner using PFQuery's whereKey:nearGeoPoint:. + + This is also used as a point specifier for whereKey:nearGeoPoint: queries. + + Currently, object classes may only have one key associated with a GeoPoint type. + */ + +@interface PFGeoPoint : NSObject + +/** @name Creating a PFGeoPoint */ +/*! + Create a PFGeoPoint object. Latitude and longitude are set to 0.0. + @result Returns a new PFGeoPoint. + */ ++ (PFGeoPoint *)geoPoint; + +/*! + Creates a new PFGeoPoint object for the given CLLocation, set to the location's + coordinates. + @param location CLLocation object, with set latitude and longitude. + @result Returns a new PFGeoPoint at specified location. + */ ++ (PFGeoPoint *)geoPointWithLocation:(CLLocation *)location; + +/*! + Creates a new PFGeoPoint object with the specified latitude and longitude. + @param latitude Latitude of point in degrees. + @param longitude Longitude of point in degrees. + @result New point object with specified latitude and longitude. + */ ++ (PFGeoPoint *)geoPointWithLatitude:(double)latitude longitude:(double)longitude; + +/*! + Fetches the user's current location and returns a new PFGeoPoint object via the + provided block. + @param geoPointHandler A block which takes the newly created PFGeoPoint as an + argument. + */ ++ (void)geoPointForCurrentLocationInBackground:(void(^)(PFGeoPoint *geoPoint, NSError *error))geoPointHandler; + +/** @name Controlling Position */ + +/// Latitude of point in degrees. Valid range (-90.0, 90.0). +@property (nonatomic) double latitude; +/// Longitude of point in degrees. Valid range (-180.0, 180.0). +@property (nonatomic) double longitude; + +/** @name Calculating Distance */ + +/*! + Get distance in radians from this point to specified point. + @param point PFGeoPoint location of other point. + @result distance in radians + */ +- (double)distanceInRadiansTo:(PFGeoPoint*)point; + +/*! + Get distance in miles from this point to specified point. + @param point PFGeoPoint location of other point. + @result distance in miles + */ +- (double)distanceInMilesTo:(PFGeoPoint*)point; + +/*! + Get distance in kilometers from this point to specified point. + @param point PFGeoPoint location of other point. + @result distance in kilometers + */ +- (double)distanceInKilometersTo:(PFGeoPoint*)point; + + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFImageView.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFImageView.h new file mode 100644 index 0000000..18881f6 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFImageView.h @@ -0,0 +1,32 @@ +// +// PFImageView.h +// Parse +// +// Created by Qian Wang on 5/16/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import "PFFile.h" + +/*! + An image view that downloads and displays remote image stored on Parse's server. + */ +@interface PFImageView : UIImageView + +/// The remote file on Parse's server that stores the image. +/// Note that the download does not start until loadInBackground: is called. +@property (nonatomic, retain) PFFile *file; + +/*! + Initiate downloading of the remote image. Once the download completes, the remote image will be displayed. + */ +- (void)loadInBackground; + +/*! + Initiate downloading of the remote image. Once the download completes, the remote image will be displayed. + @param completion the completion block. + */ +- (void)loadInBackground:(void (^)(UIImage *image, NSError *error))completion; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFInstallation.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFInstallation.h new file mode 100644 index 0000000..0726222 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFInstallation.h @@ -0,0 +1,86 @@ +// +// PFInstallation.h +// Parse +// +// Created by Brian Jacokes on 6/4/12. +// Copyright (c) 2012 Parse, Inc. All rights reserved. +// + +#import +#import "PFObject.h" +#import "PFSubclassing.h" + +/*! + A Parse Framework Installation Object that is a local representation of an + installation persisted to the Parse cloud. This class is a subclass of a + PFObject, and retains the same functionality of a PFObject, but also extends + it with installation-specific fields and related immutability and validity + checks. + + A valid PFInstallation can only be instantiated via + [PFInstallation currentInstallation] because the required identifier fields + are readonly. The timeZone and badge fields are also readonly properties which + are automatically updated to match the device's time zone and application badge + when the PFInstallation is saved, thus these fields might not reflect the + latest device state if the installation has not recently been saved. + + PFInstallation objects which have a valid deviceToken and are saved to + the Parse cloud can be used to target push notifications. + + This class is currently for iOS only. There is no PFInstallation for Parse + applications running on OS X, because they cannot receive push notifications. + */ + +@interface PFInstallation : PFObject + +/*! The name of the Installation class in the REST API. This is a required + * PFSubclassing method */ ++ (NSString *)parseClassName; + +/** @name Targeting Installations */ + +/*! + Creates a query for PFInstallation objects. The resulting query can only + be used for targeting a PFPush. Calling find methods on the resulting query + will raise an exception. + */ ++ (PFQuery *)query; + +/** @name Accessing the Current Installation */ + +/*! + Gets the currently-running installation from disk and returns an instance of + it. If this installation is not stored on disk, returns a PFInstallation + with deviceType and installationId fields set to those of the + current installation. + @result Returns a PFInstallation that represents the currently-running + installation. + */ ++ (instancetype)currentInstallation; + +/*! + Sets the device token string property from an NSData-encoded token. + */ +- (void)setDeviceTokenFromData:(NSData *)deviceTokenData; + +/** @name Properties */ + +/// The device type for the PFInstallation. +@property (nonatomic, readonly, retain) NSString *deviceType; + +/// The installationId for the PFInstallation. +@property (nonatomic, readonly, retain) NSString *installationId; + +/// The device token for the PFInstallation. +@property (nonatomic, retain) NSString *deviceToken; + +/// The badge for the PFInstallation. +@property (nonatomic, assign) NSInteger badge; + +/// The timeZone for the PFInstallation. +@property (nonatomic, readonly, retain) NSString *timeZone; + +/// The channels for the PFInstallation. +@property (nonatomic, retain) NSArray *channels; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInView.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInView.h new file mode 100644 index 0000000..2de2ee7 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInView.h @@ -0,0 +1,82 @@ +// +// PFLogInView.h +// Parse +// +// Created by Qian Wang on 3/9/12. +// Copyright (c) 2012. All rights reserved. +// + +#import + +typedef enum { + PFLogInFieldsNone = 0, + PFLogInFieldsUsernameAndPassword = 1 << 0, + PFLogInFieldsPasswordForgotten = 1 << 1, + PFLogInFieldsLogInButton = 1 << 2, + PFLogInFieldsFacebook = 1 << 3, + PFLogInFieldsTwitter = 1 << 4, + PFLogInFieldsSignUpButton = 1 << 5, + PFLogInFieldsDismissButton = 1 << 6, + + PFLogInFieldsDefault = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsPasswordForgotten | PFLogInFieldsDismissButton +} PFLogInFields; + +/*! + The class provides a standard log in interface for authenticating a PFUser. + */ +@interface PFLogInView : UIView + +/*! @name Creating Log In View */ +/*! + Initializes the view with the specified log in elements. + @param fields A bitmask specifying the log in elements which are enabled in the view + */ +- (id)initWithFields:(PFLogInFields) fields; + +/// The view controller that will present this view. +/// Used to lay out elements correctly when the presenting view controller has translucent elements. +@property (nonatomic, retain) UIViewController *presentingViewController; + +/*! @name Customizing the Logo */ + +/// The logo. By default, it is the Parse logo. +@property (nonatomic, retain) UIView *logo; + +/*! @name Accessing Log In Elements */ + +/// The bitmask which specifies the enabled log in elements in the view +@property (nonatomic, readonly, assign) PFLogInFields fields; + +/// The username text field. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UITextField *usernameField; + +/// The password text field. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UITextField *passwordField; + +/// The password forgotten button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *passwordForgottenButton; + +/// The log in button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *logInButton; + +/// The Facebook button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *facebookButton; + +/// The Twitter button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *twitterButton; + +/// The sign up button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *signUpButton; + +/// The dismiss button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *dismissButton; + +/// The facebook/twitter login label. It is only shown if the external login is enabled. +@property (nonatomic, readonly, retain) UILabel *externalLogInLabel; + +/// The sign up label. It is only shown if sign up button is enabled. +@property (nonatomic, readonly, retain) UILabel *signUpLabel; + +@end + + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInViewController.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInViewController.h new file mode 100644 index 0000000..2f6a3b1 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFLogInViewController.h @@ -0,0 +1,95 @@ +// +// PFLogInViewController.h +// Parse +// +// Created by Andrew Wang on 3/8/12. +// Copyright (c) 2012. All rights reserved. +// + +#import +#import "PFLogInView.h" +#import "PFSignUpViewController.h" +#import "PFUser.h" + +@protocol PFLogInViewControllerDelegate; + +/*! + The class that presents and manages a standard authentication interface for logging in a PFUser. + */ +@interface PFLogInViewController : UIViewController + +/*! @name Configuring Log In Elements */ + +/*! + A bitmask specifying the log in elements which are enabled in the view. + enum { + PFLogInFieldsNone = 0, + PFLogInFieldsUsernameAndPassword = 1 << 0, + PFLogInFieldsPasswordForgotten = 1 << 1, + PFLogInFieldsLogInButton = 1 << 2, + PFLogInFieldsFacebook = 1 << 3, + PFLogInFieldsTwitter = 1 << 4, + PFLogInFieldsSignUpButton = 1 << 5, + PFLogInFieldsDismissButton = 1 << 6, + PFLogInFieldsDefault = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsPasswordForgotten | PFLogInFieldsDismissButton + }; + */ +@property (nonatomic) PFLogInFields fields; + +/// The log in view. It contains all the enabled log in elements. +@property (nonatomic, readonly, retain) PFLogInView *logInView; + +/*! @name Configuring Log In Behaviors */ +/// The delegate that responds to the control events of PFLogInViewController. +@property (nonatomic, assign) id delegate; + +/// The facebook permissions that Facebook log in requests for. +/// If unspecified, the default is basic facebook permissions. +@property (nonatomic, retain) NSArray *facebookPermissions; + +/// The sign up controller if sign up is enabled. +/// Use this to configure the sign up view, and the transition animation to the sign up view. +/// The default is a sign up view with a username, a password, a dismiss button and a sign up button. +@property (nonatomic, retain) PFSignUpViewController *signUpController; + +@end + +/*! @name Notifications */ +/// The notification is posted immediately after the log in succeeds. +extern NSString *const PFLogInSuccessNotification; + +/// The notification is posted immediately after the log in fails. +/// If the delegate prevents the log in from starting, the notification is not sent. +extern NSString *const PFLogInFailureNotification; + +/// The notification is posted immediately after the log in is cancelled. +extern NSString *const PFLogInCancelNotification; + +/*! + The protocol defines methods a delegate of a PFLogInViewController should implement. + All methods of the protocol are optional. + */ +@protocol PFLogInViewControllerDelegate +@optional + +/*! @name Customizing Behavior */ + +/*! + Sent to the delegate to determine whether the log in request should be submitted to the server. + @param username the username the user tries to log in with. + @param password the password the user tries to log in with. + @result a boolean indicating whether the log in should proceed. + */ +- (BOOL)logInViewController:(PFLogInViewController *)logInController shouldBeginLogInWithUsername:(NSString *)username password:(NSString *)password; + +/*! @name Responding to Actions */ +/// Sent to the delegate when a PFUser is logged in. +- (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user; + +/// Sent to the delegate when the log in attempt fails. +- (void)logInViewController:(PFLogInViewController *)logInController didFailToLogInWithError:(NSError *)error; + +/// Sent to the delegate when the log in screen is dismissed. +- (void)logInViewControllerDidCancelLogIn:(PFLogInViewController *)logInController; +@end + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFObject+Subclass.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFObject+Subclass.h new file mode 100644 index 0000000..6b99490 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFObject+Subclass.h @@ -0,0 +1,85 @@ +// +// PFObject+Subclass.h +// Parse +// +// Created by Thomas Bouldin on 2/17/13. +// Copyright (c) 2013 Parse Inc. All rights reserved. +// + +#import "PFObject.h" + +@class PFQuery; + +/*! +

Subclassing Notes

+ + Developers can subclass PFObject for a more native object-oriented class structure. Strongly-typed subclasses of PFObject must conform to the PFSubclassing protocol and must call registerSubclass to be returned by PFQuery and other PFObject factories. All methods in PFSubclassing except for [PFSubclassing parseClassName] are already implemented in the PFObject(Subclass) category. Inculding PFObject+Subclass.h in your implementation file provides these implementations automatically. + + Subclasses support simpler initializers, query syntax, and dynamic synthesizers. The following shows an example subclass: + + @interface MYGame : PFObject< PFSubclassing > + // Accessing this property is the same as objectForKey:@"title" + @property (retain) NSString *title; + + (NSString *)parseClassName; + @end + + @implementation MYGame + @dynamic title; + + (NSString *)parseClassName { + return @"Game"; + } + @end + + MYGame *game = [[MYGame alloc] init]; + game.title = @"Bughouse"; + [game saveInBackground]; + + */ +@interface PFObject(Subclass) + +/*! @name Methods for Subclasses */ + +/*! + Designated initializer for subclasses. + This method can only be called on subclasses which conform to PFSubclassing. + This method should not be overridden. + */ +- (id)init; + +/*! + Creates an instance of the registered subclass with this class's parseClassName. + This helps a subclass ensure that it can be subclassed itself. For example, [PFUser object] will + return a MyUser object if MyUser is a registered subclass of PFUser. For this reason, [MyClass object] is + preferred to [[MyClass alloc] init]. + This method can only be called on subclasses which conform to PFSubclassing. + A default implementation is provided by PFObject which should always be sufficient. + */ ++ (instancetype)object; + +/*! + Creates a reference to an existing PFObject for use in creating associations between PFObjects. Calling isDataAvailable on this + object will return NO until fetchIfNeeded or refresh has been called. No network request will be made. + This method can only be called on subclasses which conform to PFSubclassing. + A default implementation is provided by PFObject which should always be sufficient. + @param objectId The object id for the referenced object. + @result A PFObject without data. + */ ++ (id)objectWithoutDataWithObjectId:(NSString *)objectId; + +/*! + Registers an Objective-C class for Parse to use for representing a given Parse class. + Once this is called on a PFObject subclass, any PFObject Parse creates with a class + name matching [self parseClassName] will be an instance of subclass. + This method can only be called on subclasses which conform to PFSubclassing. + A default implementation is provided by PFObject which should always be sufficient. + */ ++ (void)registerSubclass; + +/*! + Returns a query for objects of type +parseClassName. + This method can only be called on subclasses which conform to PFSubclassing. + A default implementation is provided by PFObject which should always be sufficient. + */ ++ (PFQuery *)query; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFObject.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFObject.h new file mode 100644 index 0000000..d6e9004 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFObject.h @@ -0,0 +1,588 @@ +// PFObject.h +// Copyright 2011 Parse, Inc. All rights reserved. + +#import +#import "PFACL.h" +#import "PFConstants.h" + +@protocol PFSubclassing; + +/*! + A Parse Framework Object that is a local representation of data persisted to the Parse cloud. + This is the main class that is used to interact with objects in your app. +*/ +@class PFRelation; +@class PFTask; + +NS_REQUIRES_PROPERTY_DEFINITIONS +@interface PFObject : NSObject { + BOOL dirty; + + // An array of NSDictionary of NSString -> PFFieldOperation. + // Each dictionary has a subset of the object's keys as keys, and the + // changes to the value for that key as its value. + // There is always at least one dictionary of pending operations. + // Every time a save is started, a new dictionary is added to the end. + // Whenever a save completes, the new data is put into fetchedData, and + // a dictionary is removed from the start. + NSMutableArray *operationSetQueue; + + // Our best estimate as to what the current data is, based on + // the last fetch from the server, and the set of pending operations. + NSMutableDictionary *estimatedData; +} + +#pragma mark Constructors + +/*! @name Creating a PFObject */ + +/*! + Creates a new PFObject with a class name. + @param className A class name can be any alphanumeric string that begins with a letter. It represents an object in your app, like a User of a Document. + @result Returns the object that is instantiated with the given class name. + */ ++ (instancetype)objectWithClassName:(NSString *)className; + +/*! + Creates a reference to an existing PFObject for use in creating associations between PFObjects. Calling isDataAvailable on this + object will return NO until fetchIfNeeded or refresh has been called. No network request will be made. + + @param className The object's class. + @param objectId The object id for the referenced object. + @result A PFObject without data. + */ ++ (instancetype)objectWithoutDataWithClassName:(NSString *)className + objectId:(NSString *)objectId; + +/*! + Creates a new PFObject with a class name, initialized with data constructed from the specified set of objects and keys. + @param className The object's class. + @param dictionary An NSDictionary of keys and objects to set on the new PFObject. + @result A PFObject with the given class name and set with the given data. + */ ++ (PFObject *)objectWithClassName:(NSString *)className dictionary:(NSDictionary *)dictionary; + +/*! + Initializes a new PFObject with a class name. + @param newClassName A class name can be any alphanumeric string that begins with a letter. It represents an object in your app, like a User or a Document. + @result Returns the object that is instantiated with the given class name. + */ +- (id)initWithClassName:(NSString *)newClassName; + +#pragma mark - +#pragma mark Properties + +/*! @name Managing Object Properties */ + +/*! + The class name of the object. + */ +@property (readonly) NSString *parseClassName; + +/*! + The id of the object. + */ +@property (nonatomic, retain) NSString *objectId; + +/*! + When the object was last updated. + */ +@property (nonatomic, retain, readonly) NSDate *updatedAt; + +/*! + When the object was created. + */ +@property (nonatomic, retain, readonly) NSDate *createdAt; + +/*! + The ACL for this object. + */ +@property (nonatomic, retain) PFACL *ACL; + +/*! + Returns an array of the keys contained in this object. This does not include + createdAt, updatedAt, authData, or objectId. It does include things like username + and ACL. + */ +- (NSArray *)allKeys; + +#pragma mark - +#pragma mark Get and set + +/*! + Returns the object associated with a given key. + @param key The key that the object is associated with. + @result The value associated with the given key, or nil if no value is associated with key. + */ +- (id)objectForKey:(NSString *)key; + +/*! + Sets the object associated with a given key. + @param object The object. + @param key The key. + */ +- (void)setObject:(id)object forKey:(NSString *)key; + +/*! + Unsets a key on the object. + @param key The key. + */ +- (void)removeObjectForKey:(NSString *)key; + +/*! + * In LLVM 4.0 (XCode 4.5) or higher allows myPFObject[key]. + @param key The key. + */ +- (id)objectForKeyedSubscript:(NSString *)key; + +/*! + * In LLVM 4.0 (XCode 4.5) or higher allows myObject[key] = value + @param object The object. + @param key The key. + */ +- (void)setObject:(id)object forKeyedSubscript:(NSString *)key; + +/*! + Returns the relation object associated with the given key + @param key The key that the relation is associated with. + */ +- (PFRelation *)relationForKey:(NSString *)key; + +/*! + Use relationForKey instead. This method exists only for backward compatibility. + */ +- (PFRelation *)relationforKey:(NSString *)key; + +#pragma mark - +#pragma mark Array add and remove + +/*! + Adds an object to the end of the array associated with a given key. + @param object The object to add. + @param key The key. + */ +- (void)addObject:(id)object forKey:(NSString *)key; + +/*! + Adds the objects contained in another array to the end of the array associated + with a given key. + @param objects The array of objects to add. + @param key The key. + */ +- (void)addObjectsFromArray:(NSArray *)objects forKey:(NSString *)key; + +/*! + Adds an object to the array associated with a given key, only if it is not + already present in the array. The position of the insert is not guaranteed. + @param object The object to add. + @param key The key. + */ +- (void)addUniqueObject:(id)object forKey:(NSString *)key; + +/*! + Adds the objects contained in another array to the array associated with + a given key, only adding elements which are not already present in the array. + The position of the insert is not guaranteed. + @param objects The array of objects to add. + @param key The key. + */ +- (void)addUniqueObjectsFromArray:(NSArray *)objects forKey:(NSString *)key; + +/*! + Removes all occurrences of an object from the array associated with a given + key. + @param object The object to remove. + @param key The key. + */ +- (void)removeObject:(id)object forKey:(NSString *)key; + +/*! + Removes all occurrences of the objects contained in another array from the + array associated with a given key. + @param objects The array of objects to remove. + @param key The key. + */ +- (void)removeObjectsInArray:(NSArray *)objects forKey:(NSString *)key; + +#pragma mark - +#pragma mark Increment + +/*! + Increments the given key by 1. + @param key The key. + */ +- (void)incrementKey:(NSString *)key; + +/*! + Increments the given key by a number. + @param key The key. + @param amount The amount to increment. + */ +- (void)incrementKey:(NSString *)key byAmount:(NSNumber *)amount; + +#pragma mark - +#pragma mark Save + +/*! @name Saving an Object to Parse */ + +/*! + Saves the PFObject. + @result Returns whether the save succeeded. + */ +- (BOOL)save; + +/*! + Saves the PFObject and sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the save succeeded. + */ +- (BOOL)save:(NSError **)error; + +/*! + Saves the PFObject asynchronously. + */ +- (void)saveInBackground; + +/*! + Saves the PFObject asynchronously and executes the given callback block. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ +- (void)saveInBackgroundWithBlock:(PFBooleanResultBlock)block; + +/*! + Saves the PFObject asynchronously and calls the given callback. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ +- (void)saveInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/*! + @see saveEventually: + */ +- (void)saveEventually; + +/*! + Saves this object to the server at some unspecified time in the future, even if Parse is currently inaccessible. + Use this when you may not have a solid network connection, and don't need to know when the save completes. + If there is some problem with the object such that it can't be saved, it will be silently discarded. If the save + completes successfully while the object is still in memory, then callback will be called. + + Objects saved with this method will be stored locally in an on-disk cache until they can be delivered to Parse. + They will be sent immediately if possible. Otherwise, they will be sent the next time a network connection is + available. Objects saved this way will persist even after the app is closed, in which case they will be sent the + next time the app is opened. If more than 10MB of data is waiting to be sent, subsequent calls to saveEventually + will cause old saves to be silently discarded until the connection can be re-established, and the queued objects + can be saved. + */ +- (void)saveEventually:(PFBooleanResultBlock)callback; + +#pragma mark - +#pragma mark Save All + +/*! @name Saving Many Objects to Parse */ + +/*! + Saves a collection of objects all at once. + @param objects The array of objects to save. + @result Returns whether the save succeeded. + */ ++ (BOOL)saveAll:(NSArray *)objects; + +/*! + Saves a collection of objects all at once and sets an error if necessary. + @param objects The array of objects to save. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the save succeeded. + */ ++ (BOOL)saveAll:(NSArray *)objects error:(NSError **)error; + +/*! + Saves a collection of objects all at once asynchronously. + @param objects The array of objects to save. + */ ++ (void)saveAllInBackground:(NSArray *)objects; + +/*! + Saves a collection of objects all at once asynchronously and the block when done. + @param objects The array of objects to save. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)saveAllInBackground:(NSArray *)objects + block:(PFBooleanResultBlock)block; + +/*! + Saves a collection of objects all at once asynchronously and calls a callback when done. + @param objects The array of objects to save. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithError:(NSError *)error. error will be nil on success and set if there was an error. + */ ++ (void)saveAllInBackground:(NSArray *)objects + target:(id)target + selector:(SEL)selector; + +#pragma mark - +#pragma mark Delete All + +/*! @name Delete Many Objects from Parse */ + +/*! + Deletes a collection of objects all at once. + @param objects The array of objects to delete. + @result Returns whether the delete succeeded. + */ ++ (BOOL)deleteAll:(NSArray *)objects; + +/*! + Deletes a collection of objects all at once and sets an error if necessary. + @param objects The array of objects to delete. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the delete succeeded. + */ ++ (BOOL)deleteAll:(NSArray *)objects error:(NSError **)error; + +/*! + Deletes a collection of objects all at once asynchronously. + @param objects The array of objects to delete. + */ ++ (void)deleteAllInBackground:(NSArray *)objects; + +/*! + Deletes a collection of objects all at once asynchronously and the block when done. + @param objects The array of objects to delete. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)deleteAllInBackground:(NSArray *)objects + block:(PFBooleanResultBlock)block; + +/*! + Deletes a collection of objects all at once asynchronously and calls a callback when done. + @param objects The array of objects to delete. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithError:(NSError *)error. error will be nil on success and set if there was an error. + */ ++ (void)deleteAllInBackground:(NSArray *)objects + target:(id)target + selector:(SEL)selector; + +#pragma mark - +#pragma mark Refresh + +/*! @name Getting an Object from Parse */ + +/*! + Gets whether the PFObject has been fetched. + @result YES if the PFObject is new or has been fetched or refreshed. NO otherwise. + */ +- (BOOL)isDataAvailable; + +#if PARSE_IOS_ONLY +// Deprecated and intentionally not available on the new OS X SDK + +/*! + Refreshes the PFObject with the current data from the server. + */ +- (void)refresh; + +/*! + Refreshes the PFObject with the current data from the server and sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + */ +- (void)refresh:(NSError **)error; + +/*! + Refreshes the PFObject asynchronously and executes the given callback block. + @param block The block to execute. The block should have the following argument signature: (PFObject *object, NSError *error) + */ +- (void)refreshInBackgroundWithBlock:(PFObjectResultBlock)block; + +/*! + Refreshes the PFObject asynchronously and calls the given callback. + @param target The target on which the selector will be called. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(PFObject *)refreshedObject error:(NSError *)error. error will be nil on success and set if there was an error. refreshedObject will be the PFObject with the refreshed data. + */ +- (void)refreshInBackgroundWithTarget:(id)target selector:(SEL)selector; +#endif + +/*! + Fetches the PFObject with the current data from the server. + */ +- (void)fetch; +/*! + Fetches the PFObject with the current data from the server and sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + */ +- (void)fetch:(NSError **)error; + +/*! + Fetches the PFObject's data from the server if isDataAvailable is false. + */ +- (PFObject *)fetchIfNeeded; + +/*! + Fetches the PFObject's data from the server if isDataAvailable is false. + @param error Pointer to an NSError that will be set if necessary. + */ +- (PFObject *)fetchIfNeeded:(NSError **)error; + +/*! + Fetches the PFObject asynchronously and executes the given callback block. + @param block The block to execute. The block should have the following argument signature: (PFObject *object, NSError *error) + */ +- (void)fetchInBackgroundWithBlock:(PFObjectResultBlock)block; + +/*! + Fetches the PFObject asynchronously and calls the given callback. + @param target The target on which the selector will be called. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(PFObject *)refreshedObject error:(NSError *)error. error will be nil on success and set if there was an error. refreshedObject will be the PFObject with the refreshed data. + */ +- (void)fetchInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/*! + Fetches the PFObject's data asynchronously if isDataAvailable is false, then calls the callback block. + @param block The block to execute. The block should have the following argument signature: (PFObject *object, NSError *error) + */ +- (void)fetchIfNeededInBackgroundWithBlock:(PFObjectResultBlock)block; + +/*! + Fetches the PFObject's data asynchronously if isDataAvailable is false, then calls the callback. + @param target The target on which the selector will be called. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(PFObject *)fetchedObject error:(NSError *)error. error will be nil on success and set if there was an error. + */ +- (void)fetchIfNeededInBackgroundWithTarget:(id)target + selector:(SEL)selector; + +/*! @name Getting Many Objects from Parse */ + +/*! + Fetches all of the PFObjects with the current data from the server + @param objects The list of objects to fetch. + */ ++ (void)fetchAll:(NSArray *)objects; + +/*! + Fetches all of the PFObjects with the current data from the server and sets an error if it occurs. + @param objects The list of objects to fetch. + @param error Pointer to an NSError that will be set if necessary + */ ++ (void)fetchAll:(NSArray *)objects error:(NSError **)error; + +/*! + Fetches all of the PFObjects with the current data from the server + @param objects The list of objects to fetch. + */ ++ (void)fetchAllIfNeeded:(NSArray *)objects; + +/*! + Fetches all of the PFObjects with the current data from the server and sets an error if it occurs. + @param objects The list of objects to fetch. + @param error Pointer to an NSError that will be set if necessary + */ ++ (void)fetchAllIfNeeded:(NSArray *)objects error:(NSError **)error; + +/*! + Fetches all of the PFObjects with the current data from the server asynchronously and calls the given block. + @param objects The list of objects to fetch. + @param block The block to execute. The block should have the following argument signature: (NSArray *objects, NSError *error) + */ ++ (void)fetchAllInBackground:(NSArray *)objects + block:(PFArrayResultBlock)block; + +/*! + Fetches all of the PFObjects with the current data from the server asynchronously and calls the given callback. + @param objects The list of objects to fetch. + @param target The target on which the selector will be called. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSArray *)fetchedObjects error:(NSError *)error. error will be nil on success and set if there was an error. fetchedObjects will the array of PFObjects that were fetched. + */ ++ (void)fetchAllInBackground:(NSArray *)objects + target:(id)target + selector:(SEL)selector; + +/*! + Fetches all of the PFObjects with the current data from the server asynchronously and calls the given block. + @param objects The list of objects to fetch. + @param block The block to execute. The block should have the following argument signature: (NSArray *objects, NSError *error) + */ ++ (void)fetchAllIfNeededInBackground:(NSArray *)objects + block:(PFArrayResultBlock)block; + +/*! + Fetches all of the PFObjects with the current data from the server asynchronously and calls the given callback. + @param objects The list of objects to fetch. + @param target The target on which the selector will be called. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSArray *)fetchedObjects error:(NSError *)error. error will be nil on success and set if there was an error. fetchedObjects will the array of PFObjects + that were fetched. + */ ++ (void)fetchAllIfNeededInBackground:(NSArray *)objects + target:(id)target + selector:(SEL)selector; + +#pragma mark - +#pragma mark Delete + +/*! @name Removing an Object from Parse */ + +/*! + Deletes the PFObject. + @result Returns whether the delete succeeded. + */ +- (BOOL)delete; + +/*! + Deletes the PFObject and sets an error if it occurs. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the delete succeeded. + */ +- (BOOL)delete:(NSError **)error; + +/*! + Deletes the PFObject asynchronously. + */ +- (void)deleteInBackground; + +/*! + Deletes the PFObject asynchronously and executes the given callback block. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ +- (void)deleteInBackgroundWithBlock:(PFBooleanResultBlock)block; + +/*! + Deletes the PFObject asynchronously and calls the given callback. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ +- (void)deleteInBackgroundWithTarget:(id)target + selector:(SEL)selector; + +/*! + Deletes this object from the server at some unspecified time in the future, even if Parse is currently inaccessible. + Use this when you may not have a solid network connection, and don't need to know when the delete completes. + If there is some problem with the object such that it can't be deleted, the request will be silently discarded. + + Delete instructions made with this method will be stored locally in an on-disk cache until they can be transmitted + to Parse. They will be sent immediately if possible. Otherwise, they will be sent the next time a network connection + is available. Delete requests will persist even after the app is closed, in which case they will be sent the + next time the app is opened. If more than 10MB of saveEventually or deleteEventually commands are waiting to be sent, + subsequent calls to saveEventually or deleteEventually will cause old requests to be silently discarded until the + connection can be re-established, and the queued requests can go through. + */ +- (void)deleteEventually; + +#pragma mark - +#pragma Dirtiness + +/*! + Gets whether any key-value pair in this object (or its children) has been added/updated/removed and not saved yet. + @result Returns whether this object has been altered and not saved yet. + */ +- (BOOL)isDirty; + +/*! + Get whether a value associated with a key has been added/updated/removed and not saved yet. + @param key The key to check for + @result Returns whether this key has been altered and not saved yet. + */ +- (BOOL)isDirtyForKey:(NSString *)key; + +#pragma mark - + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFProduct.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFProduct.h new file mode 100644 index 0000000..a74cded --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFProduct.h @@ -0,0 +1,67 @@ +// +// PFProduct.h +// Parse +// +// Created by Qian Wang on 6/7/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import "PFObject.h" +#import "PFSubclassing.h" +#import "PFFile.h" + +/*! + Represents an in-app purchase product on the Parse server. + By default, products can only be created via the data browser; saving a PFProduct + will result in error. However, the products' metadata information can be queried + and viewed. + + This class is currently for iOS only. + */ +@interface PFProduct : PFObject + +/*! The name of the Product class in the REST API. This is a required + * PFSubclassing method */ ++ (NSString *)parseClassName; + +/** @name Querying for Products */ +/*! + A query that fetches all product instances registered on Parse's server. + */ ++ (PFQuery *)query; + +/** @name Accessing Product-specific Properties */ +/*! + The product identifier of the product. + This should match the product identifier in iTunes Connect exactly. + */ +@property (nonatomic, retain) NSString *productIdentifier; + +/*! + The icon of the product. + */ +@property (nonatomic, retain) PFFile *icon; + +/*! + The title of the product. + */ +@property (nonatomic, retain) NSString *title; + +/*! + The subtitle of the product. + */ +@property (nonatomic, retain) NSString *subtitle; + +/*! + The order in which the product information is displayed in PFProductTableViewController. + The product with a smaller order is displayed earlier in the PFProductTableViewController. + */ +@property (nonatomic, retain) NSNumber *order; + +/*! + The name of the associated download. If there is no downloadable asset, it should be nil. + */ +@property (nonatomic, readonly) NSString *downloadName; + + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFProductTableViewController.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFProductTableViewController.h new file mode 100644 index 0000000..3170e52 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFProductTableViewController.h @@ -0,0 +1,22 @@ +// +// PFProductsTableViewController.h +// Parse +// +// Created by Qian Wang on 5/15/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import "PFQueryTableViewController.h" + +/*! + PFProductTableViewController displays in-app purchase products stored on Parse. + In addition to setting up in-app purchases in iTunesConnect, the app developer needs + to register product information on Parse, in the Product class. + */ +@interface PFProductTableViewController : PFQueryTableViewController + +/*! + Initializes a product table view controller. + */ +- (id)init; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchase.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchase.h new file mode 100644 index 0000000..5397a09 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchase.h @@ -0,0 +1,63 @@ +// +// PFPurchase.h +// Parse +// +// Created by Qian Wang on 5/2/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import +#import "PFConstants.h" + +/*! + PFPurchase provides a set of APIs for working with in-app purchases. + + This class is currently for iOS only. + */ +@interface PFPurchase : NSObject + +/*! + Use this method to add application logic block which is run when buying a product. + This method should be called once for each product, and should be called before + calling buyProduct:block. All invocations to addObserverForProduct:block: should happen within + the same method, and on the main thread. It is recommended to place all invocations of this method + in application:didFinishLaunchingWithOptions:. + @param productIdentifier the product identifier + @param completion the completion block + */ ++ (void)addObserverForProduct:(NSString *)productIdentifier block:(void(^)(SKPaymentTransaction *transaction))block; + +/*! + Asynchronously initiates the purchase for the product. + @param productIdentifier the product identifier + @param block the completion block. + */ ++ (void)buyProduct:(NSString *)productIdentifier block:(void(^)(NSError *error))block; + +/*! + Asynchronously download the purchased asset, which is stored on Parse's server. + Parse verifies the receipt with Apple and delivers the content only if the receipt is valid. + @param transaction the transaction, which contains the receipt. + @param completion the completion block. + */ ++ (void)downloadAssetForTransaction:(SKPaymentTransaction *)transaction completion:(void(^)(NSString *filePath, NSError *error))completion; + +/*! + Asynchronously download the purchased asset, which is stored on Parse's server. + Parse verifies the receipt with Apple and delivers the content only if the receipt is valid. + @param transaction the transaction, which contains the receipt. + @param completion the completion block. + @param progress the progress block, which is called multiple times to reveal progress of the download. + */ ++ (void)downloadAssetForTransaction:(SKPaymentTransaction *)transaction completion:(void(^)(NSString *filePath, NSError *error))completion progress:(PFProgressBlock)progress; + +/*! + Asynchronously restore completed transactions for the current user. + Note: This method is only important to developers who want to preserve purchase states across + different installations of the same app. + Only nonconsumable purchases are restored. If observers for the products have been added before + calling this method, invoking the method reruns the application logic associated with the purchase. + */ ++ (void)restore; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchaseTableViewCell.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchaseTableViewCell.h new file mode 100644 index 0000000..3f702c6 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFPurchaseTableViewCell.h @@ -0,0 +1,22 @@ +// +// PFPurchaseTableViewCell.h +// Parse +// +// Created by Qian Wang on 5/21/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import "PFTableViewCell.h" + +typedef enum { + PFPurchaseTableViewCellStateNormal, + PFPurchaseTableViewCellStateDownloading, + PFPurchaseTableViewCellStateDownloaded +} PFPurchaseTableViewCellState; + +@interface PFPurchaseTableViewCell : PFTableViewCell +@property (nonatomic, assign) PFPurchaseTableViewCellState state; +@property (nonatomic, retain, readonly) UILabel *priceLabel; +@property (nonatomic, retain, readonly) UIProgressView *progressView; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFPush.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFPush.h new file mode 100644 index 0000000..d124a42 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFPush.h @@ -0,0 +1,396 @@ +// +// PFPush.h +// Parse +// +// Created by Ilya Sukhar on 7/4/11. +// Copyright 2011 Parse, Inc. All rights reserved. +// + +#import +#import +#import "PFConstants.h" +#import "PFQuery.h" + +/*! + A class which defines a push notification that can be sent from + a client device. + + The preferred way of modifying or retrieving channel subscriptions is to use + the PFInstallation class, instead of the class methods in PFPush. + + This class is currently for iOS only. Parse does not handle Push Notifications + to Parse applications running on OS X. Push Notifications can be sent from OS X + applications via Cloud Code or the REST API to push-enabled devices (e.g. iOS + or Android). + */ +@interface PFPush : NSObject + +/*! @name Creating a Push Notification */ ++ (PFPush *)push; + +/*! @name Configuring a Push Notification */ + +/*! + Sets the channel on which this push notification will be sent. + @param channel The channel to set for this push. The channel name must start + with a letter and contain only letters, numbers, dashes, and underscores. + */ +- (void)setChannel:(NSString *)channel; + +/*! + Sets the array of channels on which this push notification will + be sent. + @param channels The array of channels to set for this push. Each channel name + must start with a letter and contain only letters, numbers, dashes, and underscores. + */ +- (void)setChannels:(NSArray *)channels; + +/*! + Sets an installation query to which this push notification will be sent. The + query should be created via [PFInstallation query] and should not specify a + skip, limit, or order. + @param query The installation query to set for this push. + */ +- (void)setQuery:(PFQuery *)query; + +/*! + Sets an alert message for this push notification. This will overwrite + any data specified in setData. + @param message The message to send in this push. + */ +- (void)setMessage:(NSString *)message; + +/*! + Sets an arbitrary data payload for this push notification. See the guide + for information about the dictionary structure. This will overwrite any + data specified in setMessage. + @param data The data to send in this push. + */ +- (void)setData:(NSDictionary *)data; + +/*! + Deprecated. Please use a PFInstallation.query with a constraint on deviceType. + */ +- (void)setPushToAndroid:(BOOL)pushToAndroid __attribute__ ((deprecated)); + +/*! + Deprecated. Please use a PFInstallation.query with a constraint on deviceType. + */ +- (void)setPushToIOS:(BOOL)pushToIOS __attribute__ ((deprecated)); + +/*! + Sets the expiration time for this notification. The notification will be + sent to devices which are either online at the time the notification + is sent, or which come online before the expiration time is reached. + Because device clocks are not guaranteed to be accurate, most applications + should instead use expireAfterTimeInterval. + @param time The time at which the notification should expire. + */ +- (void)expireAtDate:(NSDate *)date; + +/*! + Sets the time interval after which this notification should expire. + This notification will be sent to devices which are either online at + the time the notification is sent, or which come online within the given + time interval of the notification being received by Parse's server. + An interval which is less than or equal to zero indicates that the + message should only be sent to devices which are currently online. + @param interval The interval after which the notification should expire. + */ +- (void)expireAfterTimeInterval:(NSTimeInterval)timeInterval; + +/*! + Clears both expiration values, indicating that the notification should + never expire. + */ +- (void)clearExpiration; + +/*! @name Sending Push Notifications */ + +/*! + Send a push message to a channel. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param message The message to send. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the send succeeded. + */ ++ (BOOL)sendPushMessageToChannel:(NSString *)channel + withMessage:(NSString *)message + error:(NSError **)error; + +/*! + Asynchronously send a push message to a channel. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param message The message to send. + */ ++ (void)sendPushMessageToChannelInBackground:(NSString *)channel + withMessage:(NSString *)message; + +/*! + Asynchronously sends a push message to a channel and calls the given block. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param message The message to send. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)sendPushMessageToChannelInBackground:(NSString *)channel + withMessage:(NSString *)message + block:(PFBooleanResultBlock)block; + +/*! + Asynchronously send a push message to a channel. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param message The message to send. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ ++ (void)sendPushMessageToChannelInBackground:(NSString *)channel + withMessage:(NSString *)message + target:(id)target + selector:(SEL)selector; + +/*! + Send a push message to a query. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param message The message to send. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the send succeeded. + */ ++ (BOOL)sendPushMessageToQuery:(PFQuery *)query + withMessage:(NSString *)message + error:(NSError **)error; + +/*! + Asynchronously send a push message to a query. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param message The message to send. + */ ++ (void)sendPushMessageToQueryInBackground:(PFQuery *)query + withMessage:(NSString *)message; + +/*! + Asynchronously sends a push message to a query and calls the given block. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param message The message to send. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)sendPushMessageToQueryInBackground:(PFQuery *)query + withMessage:(NSString *)message + block:(PFBooleanResultBlock)block; + +/*! + Send this push message. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the send succeeded. + */ +- (BOOL)sendPush:(NSError **)error; + +/*! + Asynchronously send this push message. + */ +- (void)sendPushInBackground; + +/*! + Asynchronously send this push message and executes the given callback block. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ +- (void)sendPushInBackgroundWithBlock:(PFBooleanResultBlock)block; + +/*! + Asynchronously send this push message and calls the given callback. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ +- (void)sendPushInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/*! + Send a push message with arbitrary data to a channel. See the guide for information about the dictionary structure. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param data The data to send. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the send succeeded. + */ ++ (BOOL)sendPushDataToChannel:(NSString *)channel + withData:(NSDictionary *)data + error:(NSError **)error; + +/*! + Asynchronously send a push message with arbitrary data to a channel. See the guide for information about the dictionary structure. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param data The data to send. + */ ++ (void)sendPushDataToChannelInBackground:(NSString *)channel + withData:(NSDictionary *)data; + +/*! + Asynchronously sends a push message with arbitrary data to a channel and calls the given block. See the guide for information about the dictionary structure. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param data The data to send. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)sendPushDataToChannelInBackground:(NSString *)channel + withData:(NSDictionary *)data + block:(PFBooleanResultBlock)block; + +/*! + Asynchronously send a push message with arbitrary data to a channel. See the guide for information about the dictionary structure. + @param channel The channel to send to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param data The data to send. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ ++ (void)sendPushDataToChannelInBackground:(NSString *)channel + withData:(NSDictionary *)data + target:(id)target + selector:(SEL)selector; + +/*! + Send a push message with arbitrary data to a query. See the guide for information about the dictionary structure. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param data The data to send. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the send succeeded. + */ ++ (BOOL)sendPushDataToQuery:(PFQuery *)query + withData:(NSDictionary *)data + error:(NSError **)error; + +/*! + Asynchronously send a push message with arbitrary data to a query. See the guide for information about the dictionary structure. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param data The data to send. + */ ++ (void)sendPushDataToQueryInBackground:(PFQuery *)query + withData:(NSDictionary *)data; + +/*! + Asynchronously sends a push message with arbitrary data to a query and calls the given block. See the guide for information about the dictionary structure. + @param query The query to send to. The query must be a PFInstallation query + created with [PFInstallation query]. + @param data The data to send. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)sendPushDataToQueryInBackground:(PFQuery *)query + withData:(NSDictionary *)data + block:(PFBooleanResultBlock)block; + +/*! @name Handling Notifications */ + +/*! + A default handler for push notifications while the app is active to mimic the behavior of iOS push notifications while the app is backgrounded or not running. Call this from didReceiveRemoteNotification. + @param userInfo The userInfo dictionary you get in didReceiveRemoteNotification. + */ ++ (void)handlePush:(NSDictionary *)userInfo; + +/*! @name Managing Channel Subscriptions */ + +/*! + Store the device token locally for push notifications. Usually called from you main app delegate's didRegisterForRemoteNotificationsWithDeviceToken. + @param deviceToken Either as an NSData straight from didRegisterForRemoteNotificationsWithDeviceToken or as an NSString if you converted it yourself. + */ ++ (void)storeDeviceToken:(id)deviceToken; + +/*! + Get all the channels that this device is subscribed to. + @param error Pointer to an NSError that will be set if necessary. + @result Returns an NSSet containing all the channel names this device is subscribed to. + */ ++ (NSSet *)getSubscribedChannels:(NSError **)error; + +/*! + Get all the channels that this device is subscribed to. + @param block The block to execute. The block should have the following argument signature: (NSSet *channels, NSError *error) + */ ++ (void)getSubscribedChannelsInBackgroundWithBlock:(PFSetResultBlock)block; + +/*! + Asynchronously get all the channels that this device is subscribed to. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSSet *)result error:(NSError *)error. error will be nil on success and set if there was an error. + @result Returns an NSSet containing all the channel names this device is subscribed to. + */ ++ (void)getSubscribedChannelsInBackgroundWithTarget:(id)target + selector:(SEL)selector; + +/*! + Subscribes the device to a channel of push notifications. + @param channel The channel to subscribe to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the subscribe succeeded. + */ ++ (BOOL)subscribeToChannel:(NSString *)channel error:(NSError **)error; + +/*! + Asynchronously subscribes the device to a channel of push notifications. + @param channel The channel to subscribe to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + */ ++ (void)subscribeToChannelInBackground:(NSString *)channel; + +/*! + Asynchronously subscribes the device to a channel of push notifications and calls the given block. + @param channel The channel to subscribe to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)subscribeToChannelInBackground:(NSString *)channel + block:(PFBooleanResultBlock)block; + +/*! + Asynchronously subscribes the device to a channel of push notifications and calls the given callback. + @param channel The channel to subscribe to. The channel name must start with + a letter and contain only letters, numbers, dashes, and underscores. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ ++ (void)subscribeToChannelInBackground:(NSString *)channel + target:(id)target + selector:(SEL)selector; + +/*! + Unsubscribes the device to a channel of push notifications. + @param channel The channel to unsubscribe from. + @param error Pointer to an NSError that will be set if necessary. + @result Returns whether the unsubscribe succeeded. + */ ++ (BOOL)unsubscribeFromChannel:(NSString *)channel error:(NSError **)error; + +/*! + Asynchronously unsubscribes the device from a channel of push notifications. + @param channel The channel to unsubscribe from. + */ ++ (void)unsubscribeFromChannelInBackground:(NSString *)channel; + + +/*! + Asynchronously unsubscribes the device from a channel of push notifications and calls the given block. + @param channel The channel to unsubscribe from. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)unsubscribeFromChannelInBackground:(NSString *)channel + block:(PFBooleanResultBlock)block; + +/*! + Asynchronously unsubscribes the device from a channel of push notifications and calls the given callback. + @param channel The channel to unsubscribe from. + @param target The object to call selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ ++ (void)unsubscribeFromChannelInBackground:(NSString *)channel + target:(id)target + selector:(SEL)selector; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFQuery.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFQuery.h new file mode 100644 index 0000000..b18fe16 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFQuery.h @@ -0,0 +1,588 @@ +// PFQuery.m +// Copyright 2011 Parse, Inc. All rights reserved. + +#import +#import "PFGeoPoint.h" +#import "PFObject.h" +#import "PFUser.h" + +/*! + A class that defines a query that is used to query for PFObjects. + */ +@interface PFQuery : NSObject + +#pragma mark Query options + +/** @name Creating a Query for a Class */ + +/*! + Returns a PFQuery for a given class. + @param className The class to query on. + @return A PFQuery object. + */ ++ (PFQuery *)queryWithClassName:(NSString *)className; + +/*! + Creates a PFQuery with the constraints given by predicate. + + The following types of predicates are supported: + * Simple comparisons such as =, !=, <, >, <=, >=, and BETWEEN with a key and a constant. + * Containment predicates, such as "x IN {1, 2, 3}". + * Key-existence predicates, such as "x IN SELF". + * BEGINSWITH expressions. + * Compound predicates with AND, OR, and NOT. + * SubQueries with "key IN %@", subquery. + + The following types of predicates are NOT supported: + * Aggregate operations, such as ANY, SOME, ALL, or NONE. + * Regular expressions, such as LIKE, MATCHES, CONTAINS, or ENDSWITH. + * Predicates comparing one key to another. + * Complex predicates with many ORed clauses. + + */ ++ (PFQuery *)queryWithClassName:(NSString *)className predicate:(NSPredicate *)predicate; + +/*! + Initializes the query with a class name. + @param newClassName The class name. + */ +- (id)initWithClassName:(NSString *)newClassName; + +/*! + The class name to query for + */ +@property (nonatomic, retain) NSString *parseClassName; + +/** @name Adding Basic Constraints */ + +/*! + Make the query include PFObjects that have a reference stored at the provided key. + This has an effect similar to a join. You can use dot notation to specify which fields in + the included object are also fetch. + @param key The key to load child PFObjects for. + */ +- (void)includeKey:(NSString *)key; + +/*! + Make the query restrict the fields of the returned PFObjects to include only the provided keys. + If this is called multiple times, then all of the keys specified in each of the calls will be included. + @param keys The keys to include in the result. + */ +- (void)selectKeys:(NSArray *)keys; + +/*! + Add a constraint that requires a particular key exists. + @param key The key that should exist. + */ +- (void)whereKeyExists:(NSString *)key; + +/*! + Add a constraint that requires a key not exist. + @param key The key that should not exist. + */ +- (void)whereKeyDoesNotExist:(NSString *)key; + +/*! + Add a constraint to the query that requires a particular key's object to be equal to the provided object. + @param key The key to be constrained. + @param object The object that must be equalled. + */ +- (void)whereKey:(NSString *)key equalTo:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be less than the provided object. + @param key The key to be constrained. + @param object The object that provides an upper bound. + */ +- (void)whereKey:(NSString *)key lessThan:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be less than or equal to the provided object. + @param key The key to be constrained. + @param object The object that must be equalled. + */ +- (void)whereKey:(NSString *)key lessThanOrEqualTo:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be greater than the provided object. + @param key The key to be constrained. + @param object The object that must be equalled. + */ +- (void)whereKey:(NSString *)key greaterThan:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be greater than or equal to the provided object. + @param key The key to be constrained. + @param object The object that must be equalled. + */ +- (void)whereKey:(NSString *)key greaterThanOrEqualTo:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be not equal to the provided object. + @param key The key to be constrained. + @param object The object that must not be equalled. + */ +- (void)whereKey:(NSString *)key notEqualTo:(id)object; + +/*! + Add a constraint to the query that requires a particular key's object to be contained in the provided array. + @param key The key to be constrained. + @param array The possible values for the key's object. + */ +- (void)whereKey:(NSString *)key containedIn:(NSArray *)array; + +/*! + Add a constraint to the query that requires a particular key's object not be contained in the provided array. + @param key The key to be constrained. + @param array The list of values the key's object should not be. + */ +- (void)whereKey:(NSString *)key notContainedIn:(NSArray *)array; + +/*! + Add a constraint to the query that requires a particular key's array contains every element of the provided array. + @param key The key to be constrained. + @param array The array of values to search for. + */ +- (void)whereKey:(NSString *)key containsAllObjectsInArray:(NSArray *)array; + +/** @name Adding Location Constraints */ + +/*! + Add a constraint to the query that requires a particular key's coordinates (specified via PFGeoPoint) be near + a reference point. Distance is calculated based on angular distance on a sphere. Results will be sorted by distance + from reference point. + @param key The key to be constrained. + @param geopoint The reference point. A PFGeoPoint. + */ +- (void)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint; + +/*! + Add a constraint to the query that requires a particular key's coordinates (specified via PFGeoPoint) be near + a reference point and within the maximum distance specified (in miles). Distance is calculated based on + a spherical coordinate system. Results will be sorted by distance (nearest to farthest) from the reference point. + @param key The key to be constrained. + @param geopoint The reference point. A PFGeoPoint. + @param maxDistance Maximum distance in miles. + */ +- (void)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint withinMiles:(double)maxDistance; + +/*! + Add a constraint to the query that requires a particular key's coordinates (specified via PFGeoPoint) be near + a reference point and within the maximum distance specified (in kilometers). Distance is calculated based on + a spherical coordinate system. Results will be sorted by distance (nearest to farthest) from the reference point. + @param key The key to be constrained. + @param geopoint The reference point. A PFGeoPoint. + @param maxDistance Maximum distance in kilometers. + */ +- (void)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint withinKilometers:(double)maxDistance; + +/*! + Add a constraint to the query that requires a particular key's coordinates (specified via PFGeoPoint) be near + a reference point and within the maximum distance specified (in radians). Distance is calculated based on + angular distance on a sphere. Results will be sorted by distance (nearest to farthest) from the reference point. + @param key The key to be constrained. + @param geopoint The reference point. A PFGeoPoint. + @param maxDistance Maximum distance in radians. + */ +- (void)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint withinRadians:(double)maxDistance; + +/*! + Add a constraint to the query that requires a particular key's coordinates (specified via PFGeoPoint) be + contained within a given rectangular geographic bounding box. + @param key The key to be constrained. + @param southwest The lower-left inclusive corner of the box. + @param northeast The upper-right inclusive corner of the box. + */ +- (void)whereKey:(NSString *)key withinGeoBoxFromSouthwest:(PFGeoPoint *)southwest toNortheast:(PFGeoPoint *)northeast; + +/** @name Adding String Constraints */ + +/*! + Add a regular expression constraint for finding string values that match the provided regular expression. + This may be slow for large datasets. + @param key The key that the string to match is stored in. + @param regex The regular expression pattern to match. + */ +- (void)whereKey:(NSString *)key matchesRegex:(NSString *)regex; + +/*! + Add a regular expression constraint for finding string values that match the provided regular expression. + This may be slow for large datasets. + @param key The key that the string to match is stored in. + @param regex The regular expression pattern to match. + @param modifiers Any of the following supported PCRE modifiers:
i - Case insensitive search
m - Search across multiple lines of input + */ +- (void)whereKey:(NSString *)key matchesRegex:(NSString *)regex modifiers:(NSString *)modifiers; + +/*! + Add a constraint for finding string values that contain a provided substring. + This will be slow for large datasets. + @param key The key that the string to match is stored in. + @param substring The substring that the value must contain. + */ +- (void)whereKey:(NSString *)key containsString:(NSString *)substring; + +/*! + Add a constraint for finding string values that start with a provided prefix. + This will use smart indexing, so it will be fast for large datasets. + @param key The key that the string to match is stored in. + @param prefix The substring that the value must start with. + */ +- (void)whereKey:(NSString *)key hasPrefix:(NSString *)prefix; + +/*! + Add a constraint for finding string values that end with a provided suffix. + This will be slow for large datasets. + @param key The key that the string to match is stored in. + @param suffix The substring that the value must end with. + */ +- (void)whereKey:(NSString *)key hasSuffix:(NSString *)suffix; + +/** @name Adding Subqueries */ + +/*! + Returns a PFQuery that is the or of the passed in PFQuerys. + @param queries The list of queries to or together. + @result a PFQuery that is the or of the passed in PFQuerys. + */ ++ (PFQuery *)orQueryWithSubqueries:(NSArray *)queries; + +/*! + Adds a constraint that requires that a key's value matches a value in another key + in objects returned by a sub query. + @param key The key that the value is stored + @param otherKey The key in objects in the returned by the sub query whose value should match + @param query The query to run. + */ +- (void)whereKey:(NSString *)key matchesKey:(NSString *)otherKey inQuery:(PFQuery *)query; + +/*! + Adds a constraint that requires that a key's value NOT match a value in another key + in objects returned by a sub query. + @param key The key that the value is stored + @param otherKey The key in objects in the returned by the sub query whose value should match + @param query The query to run. + */ +- (void)whereKey:(NSString *)key doesNotMatchKey:(NSString *)otherKey inQuery:(PFQuery *)query; + +/*! + Add a constraint that requires that a key's value matches a PFQuery constraint. + This only works where the key's values are PFObjects or arrays of PFObjects. + @param key The key that the value is stored in + @param query The query the value should match + */ +- (void)whereKey:(NSString *)key matchesQuery:(PFQuery *)query; + +/*! + Add a constraint that requires that a key's value to not match a PFQuery constraint. + This only works where the key's values are PFObjects or arrays of PFObjects. + @param key The key that the value is stored in + @param query The query the value should not match + */ +- (void)whereKey:(NSString *)key doesNotMatchQuery:(PFQuery *)query; + +#pragma mark - +#pragma mark Sorting + +/** @name Sorting */ + +/*! + Sort the results in ascending order with the given key. + @param key The key to order by. + */ +- (void)orderByAscending:(NSString *)key; + +/*! + Also sort in ascending order by the given key. The previous keys provided will + precedence over this key. + @param key The key to order bye + */ +- (void)addAscendingOrder:(NSString *)key; + +/*! + Sort the results in descending order with the given key. + @param key The key to order by. + */ +- (void)orderByDescending:(NSString *)key; +/*! + Also sort in descending order by the given key. The previous keys provided will + precedence over this key. + @param key The key to order bye + */ +- (void)addDescendingOrder:(NSString *)key; + +/*! + Sort the results in descending order with the given descriptor. + @param sortDescriptor The NSSortDescriptor to order by. + */ +- (void)orderBySortDescriptor:(NSSortDescriptor *)sortDescriptor; + +/*! + Sort the results in descending order with the given descriptors. + @param sortDescriptors An NSArray of NSSortDescriptor instances to order by. + */ +- (void)orderBySortDescriptors:(NSArray *)sortDescriptors; + +#pragma mark - +#pragma mark Get methods + +/** @name Getting Objects by ID */ + +/*! + Returns a PFObject with a given class and id. + @param objectClass The class name for the object that is being requested. + @param objectId The id of the object that is being requested. + @result The PFObject if found. Returns nil if the object isn't found, or if there was an error. + */ ++ (PFObject *)getObjectOfClass:(NSString *)objectClass + objectId:(NSString *)objectId; + +/*! + Returns a PFObject with a given class and id and sets an error if necessary. + @param error Pointer to an NSError that will be set if necessary. + @result The PFObject if found. Returns nil if the object isn't found, or if there was an error. + */ ++ (PFObject *)getObjectOfClass:(NSString *)objectClass + objectId:(NSString *)objectId + error:(NSError **)error; + +/*! + Returns a PFObject with the given id. + + This mutates the PFQuery. + + @param objectId The id of the object that is being requested. + @result The PFObject if found. Returns nil if the object isn't found, or if there was an error. + */ +- (PFObject *)getObjectWithId:(NSString *)objectId; + +/*! + Returns a PFObject with the given id and sets an error if necessary. + + This mutates the PFQuery + + @param error Pointer to an NSError that will be set if necessary. + @result The PFObject if found. Returns nil if the object isn't found, or if there was an error. + */ +- (PFObject *)getObjectWithId:(NSString *)objectId error:(NSError **)error; + +/*! + Gets a PFObject asynchronously and calls the given block with the result. + + This mutates the PFQuery + + @param block The block to execute. The block should have the following argument signature: (NSArray *object, NSError *error) + */ +- (void)getObjectInBackgroundWithId:(NSString *)objectId + block:(PFObjectResultBlock)block; + +/*! + Gets a PFObject asynchronously. + + This mutates the PFQuery + + @param objectId The id of the object being requested. + @param target The target for the callback selector. + @param selector The selector for the callback. It should have the following signature: (void)callbackWithResult:(PFObject *)result error:(NSError *)error. result will be nil if error is set and vice versa. + */ +- (void)getObjectInBackgroundWithId:(NSString *)objectId + target:(id)target + selector:(SEL)selector; + +#pragma mark - +#pragma mark Getting Users + +/*! @name Getting User Objects */ + +/*! + Returns a PFUser with a given id. + @param objectId The id of the object that is being requested. + @result The PFUser if found. Returns nil if the object isn't found, or if there was an error. + */ ++ (PFUser *)getUserObjectWithId:(NSString *)objectId; + +/*! + Returns a PFUser with a given class and id and sets an error if necessary. + @param error Pointer to an NSError that will be set if necessary. + @result The PFUser if found. Returns nil if the object isn't found, or if there was an error. + */ ++ (PFUser *)getUserObjectWithId:(NSString *)objectId + error:(NSError **)error; + +/*! + Deprecated. Please use [PFUser query] instead. + */ ++ (PFQuery *)queryForUser __attribute__ ((deprecated)); + +#pragma mark - +#pragma mark Find methods + +/** @name Getting all Matches for a Query */ + +/*! + Finds objects based on the constructed query. + @result Returns an array of PFObjects that were found. + */ +- (NSArray *)findObjects; + +/*! + Finds objects based on the constructed query and sets an error if there was one. + @param error Pointer to an NSError that will be set if necessary. + @result Returns an array of PFObjects that were found. + */ +- (NSArray *)findObjects:(NSError **)error; + +/*! + Finds objects asynchronously and calls the given block with the results. + @param block The block to execute. The block should have the following argument signature:(NSArray *objects, NSError *error) + */ +- (void)findObjectsInBackgroundWithBlock:(PFArrayResultBlock)block; + +/*! + Finds objects asynchronously and calls the given callback with the results. + @param target The object to call the selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSArray *)result error:(NSError *)error. result will be nil if error is set and vice versa. + */ +- (void)findObjectsInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/** @name Getting the First Match in a Query */ + +/*! + Gets an object based on the constructed query. + + This mutates the PFQuery. + + @result Returns a PFObject, or nil if none was found. + */ +- (PFObject *)getFirstObject; + +/*! + Gets an object based on the constructed query and sets an error if any occurred. + + This mutates the PFQuery. + + @param error Pointer to an NSError that will be set if necessary. + @result Returns a PFObject, or nil if none was found. + */ +- (PFObject *)getFirstObject:(NSError **)error; + +/*! + Gets an object asynchronously and calls the given block with the result. + + This mutates the PFQuery. + + @param block The block to execute. The block should have the following argument signature:(PFObject *object, NSError *error) result will be nil if error is set OR no object was found matching the query. error will be nil if result is set OR if the query succeeded, but found no results. + */ +- (void)getFirstObjectInBackgroundWithBlock:(PFObjectResultBlock)block; + +/*! + Gets an object asynchronously and calls the given callback with the results. + + This mutates the PFQuery. + + @param target The object to call the selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(PFObject *)result error:(NSError *)error. result will be nil if error is set OR no object was found matching the query. error will be nil if result is set OR if the query succeeded, but found no results. + */ +- (void)getFirstObjectInBackgroundWithTarget:(id)target selector:(SEL)selector; + +#pragma mark - +#pragma mark Count methods + +/** @name Counting the Matches in a Query */ + +/*! + Counts objects based on the constructed query. + @result Returns the number of PFObjects that match the query, or -1 if there is an error. + */ +- (NSInteger)countObjects; + +/*! + Counts objects based on the constructed query and sets an error if there was one. + @param error Pointer to an NSError that will be set if necessary. + @result Returns the number of PFObjects that match the query, or -1 if there is an error. + */ +- (NSInteger)countObjects:(NSError **)error; + +/*! + Counts objects asynchronously and calls the given block with the counts. + @param block The block to execute. The block should have the following argument signature: + (int count, NSError *error) + */ +- (void)countObjectsInBackgroundWithBlock:(PFIntegerResultBlock)block; + +/*! + Counts objects asynchronously and calls the given callback with the count. + @param target The object to call the selector on. + @param selector The selector to call. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError *)error. */ +- (void)countObjectsInBackgroundWithTarget:(id)target selector:(SEL)selector; + +#pragma mark - +#pragma mark Cancel methods + +/** @name Cancelling a Query */ + +/*! + Cancels the current network request (if any). Ensures that callbacks won't be called. + */ +- (void)cancel; + +#pragma mark - +#pragma mark Pagination properties + +/** @name Paginating Results */ +/*! + A limit on the number of objects to return. The default limit is 100, with a + maximum of 1000 results being returned at a time. + + Note: If you are calling findObject with limit=1, you may find it easier to use getFirst instead. + */ +@property (nonatomic) NSInteger limit; + +/*! + The number of objects to skip before returning any. + */ +@property (nonatomic) NSInteger skip; + +#pragma mark - +#pragma mark Cache methods + +/** @name Controlling Caching Behavior */ + +/*! + The cache policy to use for requests. + */ +@property (readwrite, assign) PFCachePolicy cachePolicy; + +/* ! + The age after which a cached value will be ignored + */ +@property (readwrite, assign) NSTimeInterval maxCacheAge; + +/*! + Returns whether there is a cached result for this query. + @result YES if there is a cached result for this query, and NO otherwise. + */ +- (BOOL)hasCachedResult; + +/*! + Clears the cached result for this query. If there is no cached result, this is a noop. + */ +- (void)clearCachedResult; + +/*! + Clears the cached results for all queries. + */ ++ (void)clearAllCachedResults; + +#pragma mark - Advanced Settings + +/** @name Advanced Settings */ + +/*! + Whether or not performance tracing should be done on the query. + This should not be set in most cases. + */ +@property (nonatomic, assign) BOOL trace; + + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFQueryTableViewController.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFQueryTableViewController.h new file mode 100644 index 0000000..956b97c --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFQueryTableViewController.h @@ -0,0 +1,152 @@ +// +// PFUITableViewController.h +// Posse +// +// Created by James Yu on 11/20/11. +// Copyright (c) 2011 Parse Inc. All rights reserved. +// + +#import +#import "PFQuery.h" +#import "PFTableViewCell.h" +#import "PF_EGORefreshTableHeaderView.h" + +@interface PFQueryTableViewController : UITableViewController + +/*! @name Creating a PFQueryTableViewController */ + +/*! + The designated initializer. + Initializes with a class name of the PFObjects that will be associated with this table. + @param style The UITableViewStyle for the table + @param aClassName The class name of the PFObjects that this table will display + @result The initialized PFQueryTableViewController + */ +- (id)initWithStyle:(UITableViewStyle)style className:(NSString *)aClassName; + +/*! + Initializes with a class name of the PFObjects that will be associated with this table. + @param aClassName The class name of the PFObjects that this table will display + @result The initialized PFQueryTableViewController + */ +- (id)initWithClassName:(NSString *)aClassName; + +/*! @name Configuring Behavior */ + +/// The class of the PFObject this table will use as a datasource +@property (nonatomic, retain) NSString *parseClassName; + +/// The key to use to display for the cell text label. This won't apply if you override tableView:cellForRowAtIndexPath:object: +@property (nonatomic, retain) NSString *textKey; + +/// The key to use to display for the cell image view. This won't apply if you override tableView:cellForRowAtIndexPath:object: +@property (nonatomic, retain) NSString *imageKey; + +/// The image to use as a placeholder for the cell images. This won't apply if you override tableView:cellForRowAtIndexPath:object: +@property (nonatomic, retain) UIImage *placeholderImage; + +/// Whether the table should use the default loading view (default:YES) +@property (nonatomic, assign) BOOL loadingViewEnabled; + +/// Whether the table should use the built-in pull-to-refresh feature (default:YES) +@property (nonatomic, assign) BOOL pullToRefreshEnabled; + +/// Whether the table should use the built-in pagination feature (default:YES) +@property (nonatomic, assign) BOOL paginationEnabled; + +/// The number of objects to show per page (default: 25) +@property (nonatomic, assign) NSUInteger objectsPerPage; + +/// Whether the table is actively loading new data from the server +@property (nonatomic, assign) BOOL isLoading; + +/*! @name Responding to Events */ + +/*! + Called when objects have loaded from Parse. If you override this method, you must + call [super objectsDidLoad:] in your implementation. + @param error The Parse error from running the PFQuery, if there was any. +*/ +- (void)objectsDidLoad:(NSError *)error; + +/*! + Called when objects will loaded from Parse. If you override this method, you must + call [super objectsWillLoad] in your implementation. +*/ +- (void)objectsWillLoad; + +/*! @name Accessing Results */ + +/// The array of PFObjects that is the UITableView data source +@property (nonatomic, retain, readonly) NSArray *objects; + +/*! + Returns an object at a particular indexPath. The default impementation returns + the object at indexPath.row. If you want to return objects in a different + indexPath order, like for sections, override this method. + @param indexPath The indexPath + @result The object at the specified index +*/ +- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath; + +/*! @name Querying */ + +/*! + Override to construct your own custom PFQuery to get the objects. + @result PFQuery that loadObjects will use to the objects for this table. +*/ +- (PFQuery *)queryForTable; + +/*! + Clears the table of all objects. +*/ +- (void)clear; + +/*! + Clears the table and loads the first page of objects. + */ +- (void)loadObjects; + +/*! + Loads the objects of the className at the specified page and appends it to the + objects already loaded and refreshes the table. + @param page The page of objects to load. + @param clear Whether to clear the table after receiving the objects. + */ +- (void)loadObjects:(NSInteger)page clear:(BOOL)clear; + +/*! + Loads the next page of objects, appends to table, and refreshes. + */ +- (void)loadNextPage; + +/*! @name Data Source Methods */ + +/*! + Override this method to customize each cell given a PFObject that is loaded. If you + don't override this method, it will use a default style cell and display either + the first data key from the object, or it will display the key as specified + with keyToDisplay. + + The cell should inherit from PFTableViewCell which is a subclass of UITableViewCell. + + @param tableView The table view object associated with this controller. + @param indexPath The indexPath of the cell. + @param object The PFObject that is associated with the cell. + @result The cell that represents this object. +*/ +- (PFTableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath + object:(PFObject *)object; + +/*! + Override this method to customize the cell that allows the user to load the + next page when pagination is turned on. + @param tableView The table view object associated with this controller. + @param indexPath The indexPath of the cell. + @result The cell that allows the user to paginate. + */ +- (PFTableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath; + + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFRelation.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFRelation.h new file mode 100644 index 0000000..7850026 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFRelation.h @@ -0,0 +1,44 @@ +// +// PFRelation.h +// Parse +// +// Created by Shyam Jayaraman on 5/11/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import "PFObject.h" +#import "PFQuery.h" + +/*! + A class that is used to access all of the children of a many-to-many relationship. Each instance + of PFRelation is associated with a particular parent object and key. + */ +@interface PFRelation : NSObject + +@property (nonatomic, retain) NSString *targetClass; + + +#pragma mark Accessing objects +/*! + @return A ParseQuery that can be used to get objects in this relation. + */ +- (PFQuery *)query; + + +#pragma mark Modifying relations + +/*! + Adds a relation to the passed in object. + @param object ParseObject to add relation to. + */ +- (void)addObject:(PFObject *)object; + +/*! + Removes a relation to the passed in object. + @param object ParseObject to add relation to. + */ +- (void)removeObject:(PFObject *)object; +@end + + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFRole.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFRole.h new file mode 100644 index 0000000..c6b3cad --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFRole.h @@ -0,0 +1,98 @@ +// +// PFRole.h +// Parse +// +// Created by David Poll on 5/17/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import + +#import "PFObject.h" +#import "PFSubclassing.h" + +/*! + Represents a Role on the Parse server. PFRoles represent groupings + of PFUsers for the purposes of granting permissions (e.g. specifying a + PFACL for a PFObject). Roles are specified by their sets of child users + and child roles, all of which are granted any permissions that the + parent role has.
+
+ Roles must have a name (which cannot be changed after creation of the role), + and must specify an ACL. + */ +@interface PFRole : PFObject + +#pragma mark Creating a New Role + +/** @name Creating a New Role */ + +/*! + Constructs a new PFRole with the given name. If no default ACL has been + specified, you must provide an ACL for the role. + + @param name The name of the Role to create. + */ +- (id)initWithName:(NSString *)name; + +/*! + Constructs a new PFRole with the given name. + + @param name The name of the Role to create. + @param acl The ACL for this role. Roles must have an ACL. + */ +- (id)initWithName:(NSString *)name acl:(PFACL *)acl; + +/*! + Constructs a new PFRole with the given name. If no default ACL has been + specified, you must provide an ACL for the role. + + @param name The name of the Role to create. + */ ++ (instancetype)roleWithName:(NSString *)name; + +/*! + Constructs a new PFRole with the given name. + + @param name The name of the Role to create. + @param acl The ACL for this role. Roles must have an ACL. + */ ++ (instancetype)roleWithName:(NSString *)name acl:(PFACL *)acl; + +#pragma mark - +#pragma mark Role-specific Properties + +/** @name Role-specific Properties */ + +/*! + Gets or sets the name for a role. This value must be set before the role + has been saved to the server, and cannot be set once the role has been + saved.
+
+ A role's name can only contain alphanumeric characters, _, -, and spaces. + */ +@property (nonatomic, copy) NSString *name; + +/*! + Gets the PFRelation for the PFUsers that are direct children of this role. + These users are granted any privileges that this role has been granted + (e.g. read or write access through ACLs). You can add or remove users from + the role through this relation. + */ +@property (nonatomic, readonly, retain) PFRelation *users; + +/*! + Gets the PFRelation for the PFRoles that are direct children of this role. + These roles' users are granted any privileges that this role has been granted + (e.g. read or write access through ACLs). You can add or remove child roles + from this role through this relation. + */ +@property (nonatomic, readonly, retain) PFRelation *roles; + +#pragma mark - +#pragma mark Querying for Roles + +/** @name Querying for Roles */ ++ (PFQuery *)query; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpView.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpView.h new file mode 100644 index 0000000..d7f4e9f --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpView.h @@ -0,0 +1,66 @@ +// +// PFLogInView.h +// Parse +// +// Created by Qian Wang on 3/9/12. +// Copyright (c) 2012. All rights reserved. +// + +#import + +typedef enum { + PFSignUpFieldsUsernameAndPassword = 0, + PFSignUpFieldsEmail = 1 << 0, + PFSignUpFieldsAdditional = 1 << 1, // this field can be used for something else + PFSignUpFieldsSignUpButton = 1 << 2, + PFSignUpFieldsDismissButton = 1 << 3, + PFSignUpFieldsDefault = PFSignUpFieldsUsernameAndPassword | PFSignUpFieldsEmail | PFSignUpFieldsSignUpButton | PFSignUpFieldsDismissButton +} PFSignUpFields; + +/*! + The class provides a standard sign up interface for authenticating a PFUser. + */ +@interface PFSignUpView : UIScrollView + +/*! @name Creating Sign Up View */ +/*! + Initializes the view with the specified sign up elements. + @param fields A bitmask specifying the sign up elements which are enabled in the view + */ +- (id)initWithFields:(PFSignUpFields) fields; + +/// The view controller that will present this view. +/// Used to lay out elements correctly when the presenting view controller has translucent elements. +@property (nonatomic, retain) UIViewController *presentingViewController; + +/*! @name Customizing the Logo */ + +/// The logo. By default, it is the Parse logo. +@property (nonatomic, retain) UIView *logo; + +/*! @name Accessing Sign Up Elements */ + +/// The bitmask which specifies the enabled sign up elements in the view +@property (nonatomic, readonly, assign) PFSignUpFields fields; + +/// The username text field. +@property (nonatomic, readonly, retain) UITextField *usernameField; + +/// The password text field. +@property (nonatomic, readonly, retain) UITextField *passwordField; + +/// The email text field. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UITextField *emailField; + +/// The additional text field. It is nil if the element is not enabled. +/// This field is intended to be customized. +@property (nonatomic, readonly, retain) UITextField *additionalField; + +/// The sign up button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *signUpButton; + +/// The dismiss button. It is nil if the element is not enabled. +@property (nonatomic, readonly, retain) UIButton *dismissButton; +@end + + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpViewController.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpViewController.h new file mode 100644 index 0000000..8bd5bdc --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFSignUpViewController.h @@ -0,0 +1,81 @@ +// +// PFLogInViewController.h +// Parse +// +// Created by Andrew Wang on 3/8/12. +// Copyright (c) 2012. All rights reserved. +// + +#import +#import "PFSignUpView.h" +#import "PFUser.h" + +@protocol PFSignUpViewControllerDelegate; + +/*! + The class that presents and manages a standard authentication interface for signing up a PFUser. + */ +@interface PFSignUpViewController : UIViewController + +/*! @name Configuring Sign Up Elements */ + +/// +/*! + A bitmask specifying the log in elements which are enabled in the view. + enum { + PFSignUpFieldsUsernameAndPassword = 0, + PFSignUpFieldsEmail = 1 << 0, + PFSignUpFieldsAdditional = 1 << 1, // this field can be used for something else + PFSignUpFieldsSignUpButton = 1 << 2, + PFSignUpFieldsDismissButton = 1 << 3, + PFSignUpFieldsDefault = PFSignUpFieldsUsernameAndPassword | PFSignUpFieldsEmail | PFSignUpFieldsSignUpButton | PFSignUpFieldsDismissButton + }; + */ +@property (nonatomic) PFSignUpFields fields; + +/// The sign up view. It contains all the enabled log in elements. +@property (nonatomic, readonly, retain) PFSignUpView *signUpView; + +/*! @name Configuring Sign Up Behaviors */ +/// The delegate that responds to the control events of PFSignUpViewController. +@property (nonatomic, assign) id delegate; + +@end + +/*! @name Notifications */ +/// The notification is posted immediately after the sign up succeeds. +extern NSString *const PFSignUpSuccessNotification; + +/// The notification is posted immediately after the sign up fails. +/// If the delegate prevents the sign up to start, the notification is not sent. +extern NSString *const PFSignUpFailureNotification; + +/// The notification is posted immediately after the user cancels sign up. +extern NSString *const PFSignUpCancelNotification; + +/*! + The protocol defines methods a delegate of a PFSignUpViewController should implement. + All methods of the protocol are optional. + */ +@protocol PFSignUpViewControllerDelegate +@optional + +/*! @name Customizing Behavior */ + +/*! + Sent to the delegate to determine whether the sign up request should be submitted to the server. + @param info a dictionary which contains all sign up information that the user entered. + @result a boolean indicating whether the sign up should proceed. + */ +- (BOOL)signUpViewController:(PFSignUpViewController *)signUpController shouldBeginSignUp:(NSDictionary *)info; + +/// Sent to the delegate when a PFUser is signed up. +- (void)signUpViewController:(PFSignUpViewController *)signUpController didSignUpUser:(PFUser *)user; + +/// Sent to the delegate when the sign up attempt fails. +- (void)signUpViewController:(PFSignUpViewController *)signUpController didFailToSignUpWithError:(NSError *)error; + +/// Sent to the delegate when the sign up screen is dismissed. +- (void)signUpViewControllerDidCancelSignUp:(PFSignUpViewController *)signUpController; +@end + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFSubclassing.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFSubclassing.h new file mode 100644 index 0000000..4f80b51 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFSubclassing.h @@ -0,0 +1,54 @@ +// +// PFSubclassing.h +// Parse +// +// Created by Thomas Bouldin on 3/11/13. +// Copyright (c) 2013 Parse Inc. All rights reserved. +// + +#import + +@class PFQuery; + +/*! + If a subclass of PFObject conforms to PFSubclassing and calls registerSubclass, Parse will be able to use that class as the native class for a Parse cloud object. + + Classes conforming to this protocol should subclass PFObject and include PFObject+Subclass.h in their implementation file. This ensures the methods in the Subclass category of PFObject are exposed in its subclasses only. + */ +@protocol PFSubclassing + +/*! + Constructs an object of the most specific class known to implement parseClassName. + This method takes care to help PFObject subclasses be subclassed themselves. + For example, [PFUser object] returns a PFUser by default but will return an + object of a registered subclass instead if one is known. + A default implementation is provided by PFObject which should always be sufficient. + @result Returns the object that is instantiated. + */ ++ (instancetype)object; + +/*! + Creates a reference to an existing PFObject for use in creating associations between PFObjects. Calling isDataAvailable on this + object will return NO until fetchIfNeeded or refresh has been called. No network request will be made. + A default implementation is provided by PFObject which should always be sufficient. + @param objectId The object id for the referenced object. + @result A PFObject without data. + */ ++ (instancetype)objectWithoutDataWithObjectId:(NSString *)objectId; + +/*! The name of the class as seen in the REST API. */ ++ (NSString *)parseClassName; + +/*! + Create a query which returns objects of this type. + A default implementation is provided by PFObject which should always be sufficient. + */ ++ (PFQuery *)query; + +/*! + Lets Parse know this class should be used to instantiate all objects with class type parseClassName. + This method must be called before [Parse setApplicationId:clientKey:] + */ ++ (void)registerSubclass; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFTableViewCell.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFTableViewCell.h new file mode 100644 index 0000000..5f63c1f --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFTableViewCell.h @@ -0,0 +1,19 @@ +// +// PFImageViewCell.h +// Parse +// +// Created by Qian Wang on 5/16/12. +// Copyright (c) 2012 Parse Inc. All rights reserved. +// + +#import +#import "PFImageView.h" + +/*! + The PFTableViewCell is a table view cell which can download and display remote images stored on Parse's server. When used in a PFQueryTableViewController, the downloading and displaying of the remote images are automatically managed by the PFQueryTableViewController. + */ +@interface PFTableViewCell : UITableViewCell + +/// The imageView of the table view cell. PFImageView supports remote image downloading. +@property (nonatomic, readonly, retain) PFImageView *imageView; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFTwitterUtils.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFTwitterUtils.h new file mode 100644 index 0000000..096581c --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFTwitterUtils.h @@ -0,0 +1,203 @@ +// +// PFTwitterUtils.h +// Copyright (c) 2012 Parse, Inc. All rights reserved. +// + +#import +#import "PF_Twitter.h" +#import "PFUser.h" +#import "PFConstants.h" + +/*! + Provides utility functions for working with Twitter in a Parse application. + + This class is currently for iOS only. + */ +@interface PFTwitterUtils : NSObject + +/** @name Interacting With Twitter */ + +/*! + Gets the instance of the Twitter object that Parse uses. + @result The Twitter instance. + */ ++ (PF_Twitter *)twitter; + +/*! + Initializes the Twitter singleton. You must invoke this in order to use the Twitter functionality in Parse. + @param consumerKey Your Twitter application's consumer key. + @param consumerSecret Your Twitter application's consumer secret. + */ ++ (void)initializeWithConsumerKey:(NSString *)consumerKey + consumerSecret:(NSString *)consumerSecret; + +/*! + Whether the user has their account linked to Twitter. + @param user User to check for a Twitter link. The user must be logged in on this device. + @result True if the user has their account linked to Twitter. + */ ++ (BOOL)isLinkedWithUser:(PFUser *)user; + +/** @name Logging In & Creating Twitter-Linked Users */ + +/*! + Logs in a user using Twitter. This method delegates to Twitter to authenticate + the user, and then automatically logs in (or creates, in the case where it is a new user) + a PFUser. + @param block The block to execute. The block should have the following argument signature: + (PFUser *user, NSError *error) + */ ++ (void)logInWithBlock:(PFUserResultBlock)block; + +/*! + Logs in a user using Twitter. This method delegates to Twitter to authenticate + the user, and then automatically logs in (or creates, in the case where it is a new user) + a PFUser. The selector for the callback should look like: (PFUser *)user error:(NSError **)error + @param target Target object for the selector + @param selector The selector that will be called when the asynchrounous request is complete. + */ ++ (void)logInWithTarget:(id)target selector:(SEL)selector; + +/*! + Logs in a user using Twitter. Allows you to handle user login to Twitter, then provide authentication + data to log in (or create, in the case where it is a new user) the PFUser. + @param twitterId The id of the Twitter user being linked + @param screenName The screen name of the Twitter user being linked + @param authToken The auth token for the user's session + @param authTokenSecret The auth token secret for the user's session + @param block The block to execute. The block should have the following argument signature: + (PFUser *user, NSError *error) + */ ++ (void)logInWithTwitterId:(NSString *)twitterId + screenName:(NSString *)screenName + authToken:(NSString *)authToken + authTokenSecret:(NSString *)authTokenSecret + block:(PFUserResultBlock)block; + +/*! + Logs in a user using Twitter. Allows you to handle user login to Twitter, then provide authentication + data to log in (or create, in the case where it is a new user) the PFUser. + The selector for the callback should look like: (PFUser *)user error:(NSError *)error + @param twitterId The id of the Twitter user being linked + @param screenName The screen name of the Twitter user being linked + @param authToken The auth token for the user's session + @param authTokenSecret The auth token secret for the user's session + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete + */ ++ (void)logInWithTwitterId:(NSString *)twitterId + screenName:(NSString *)screenName + authToken:(NSString *)authToken + authTokenSecret:(NSString *)authTokenSecret + target:(id)target + selector:(SEL)selector; + +/** @name Linking Users with Twitter */ + +/*! + Links Twitter to an existing PFUser. This method delegates to Twitter to authenticate + the user, and then automatically links the account to the PFUser. + @param user User to link to Twitter. + */ ++ (void)linkUser:(PFUser *)user; + +/*! + Links Twitter to an existing PFUser. This method delegates to Twitter to authenticate + the user, and then automatically links the account to the PFUser. + @param user User to link to Twitter. + @param block The block to execute. The block should have the following argument signature: + (BOOL *success, NSError *error) + */ ++ (void)linkUser:(PFUser *)user block:(PFBooleanResultBlock)block; + +/*! + Links Twitter to an existing PFUser. This method delegates to Twitter to authenticate + the user, and then automatically links the account to the PFUser. + The selector for the callback should look like: (NSNumber *)result error:(NSError *)error + @param user User to link to Twitter. + @param target Target object for the selector + @param selector The selector that will be called when the asynchrounous request is complete. + */ ++ (void)linkUser:(PFUser *)user + target:(id)target + selector:(SEL)selector; + +/*! + Links Twitter to an existing PFUser. Allows you to handle user login to Twitter, then provide authentication + data to link the account to the PFUser. + @param user User to link to Twitter. + @param twitterId The id of the Twitter user being linked + @param screenName The screen name of the Twitter user being linked + @param authToken The auth token for the user's session + @param authTokenSecret The auth token secret for the user's session + @param block The block to execute. The block should have the following argument signature: + (BOOL *success, NSError *error) + */ ++ (void)linkUser:(PFUser *)user + twitterId:(NSString *)twitterId + screenName:(NSString *)screenName + authToken:(NSString *)authToken + authTokenSecret:(NSString *)authTokenSecret + block:(PFBooleanResultBlock)block; + +/*! + Links Twitter to an existing PFUser. Allows you to handle user login to Twitter, then provide authentication + data to link the account to the PFUser. + The selector for the callback should look like: (NSNumber *)result error:(NSError *)error + @param user User to link to Twitter. + @param twitterId The id of the Twitter user being linked + @param screenName The screen name of the Twitter user being linked + @param authToken The auth token for the user's session + @param authTokenSecret The auth token secret for the user's session + @param target Target object for the selector + @param selector The selector that will be called when the asynchronous request is complete + */ ++ (void)linkUser:(PFUser *)user + twitterId:(NSString *)twitterId + screenName:(NSString *)screenName + authToken:(NSString *)authToken + authTokenSecret:(NSString *)authTokenSecret + target:(id)target + selector:(SEL)selector; + +/** @name Unlinking Users from Twitter */ + +/*! + Unlinks the PFUser from a Twitter account. + @param user User to unlink from Twitter. + @result Returns true if the unlink was successful. + */ ++ (BOOL)unlinkUser:(PFUser *)user; + +/*! + Unlinks the PFUser from a Twitter account. + @param user User to unlink from Twitter. + @param error Error object to set on error. + @result Returns true if the unlink was successful. + */ ++ (BOOL)unlinkUser:(PFUser *)user error:(NSError **)error; + +/*! + Makes an asynchronous request to unlink a user from a Twitter account. + @param user User to unlink from Twitter. + */ ++ (void)unlinkUserInBackground:(PFUser *)user; + +/*! + Makes an asynchronous request to unlink a user from a Twitter account. + @param user User to unlink from Twitter. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)unlinkUserInBackground:(PFUser *)user + block:(PFBooleanResultBlock)block; + +/*! + Makes an asynchronous request to unlink a user from a Twitter account. + @param user User to unlink from Twitter + @param target Target object for the selector + @param selector The selector that will be called when the asynchrounous request is complete. + */ ++ (void)unlinkUserInBackground:(PFUser *)user + target:(id)target selector:(SEL)selector; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PFUser.h b/Example/Parse.framework/Versions/1.2.18/Headers/PFUser.h new file mode 100644 index 0000000..af9337a --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PFUser.h @@ -0,0 +1,290 @@ +// PFUser.h +// Copyright 2011 Parse, Inc. All rights reserved. + +#import +#import "PFConstants.h" +#import "PFObject.h" +#import "PFSubclassing.h" + +@class PFQuery; + +/*! +A Parse Framework User Object that is a local representation of a user persisted to the Parse cloud. This class + is a subclass of a PFObject, and retains the same functionality of a PFObject, but also extends it with various + user specific methods, like authentication, signing up, and validation uniqueness. + + Many APIs responsible for linking a PFUser with Facebook or Twitter have been deprecated in favor of dedicated + utilities for each social network. See PFFacebookUtils and PFTwitterUtils for more information. + */ + +@interface PFUser : PFObject + +/*! The name of the PFUser class in the REST API. This is a required + * PFSubclassing method */ ++ (NSString *)parseClassName; + +/** @name Accessing the Current User */ + +/*! + Gets the currently logged in user from disk and returns an instance of it. + @result Returns a PFUser that is the currently logged in user. If there is none, returns nil. + */ ++ (instancetype)currentUser; + +/// The session token for the PFUser. This is set by the server upon successful authentication. +@property (nonatomic, retain) NSString *sessionToken; + +/// Whether the PFUser was just created from a request. This is only set after a Facebook or Twitter login. +@property (readonly, assign) BOOL isNew; + +/*! + Whether the user is an authenticated object for the device. An authenticated PFUser is one that is obtained via + a signUp or logIn method. An authenticated object is required in order to save (with altered values) or delete it. + @result Returns whether the user is authenticated. + */ +- (BOOL)isAuthenticated; + +/** @name Creating a New User */ + +/*! + Creates a new PFUser object. + @result Returns a new PFUser object. + */ ++ (PFUser *)user; + +/*! + Enables automatic creation of anonymous users. After calling this method, [PFUser currentUser] will always have a value. + The user will only be created on the server once the user has been saved, or once an object with a relation to that user or + an ACL that refers to the user has been saved. + + Note: saveEventually will not work if an item being saved has a relation to an automatic user that has never been saved. + */ ++ (void)enableAutomaticUser; + +/// The username for the PFUser. +@property (nonatomic, retain) NSString *username; + +/** + The password for the PFUser. This will not be filled in from the server with + the password. It is only meant to be set. + */ +@property (nonatomic, retain) NSString *password; + +/// The email for the PFUser. +@property (nonatomic, retain) NSString *email; + +/*! + Signs up the user. Make sure that password and username are set. This will also enforce that the username isn't already taken. + @result Returns true if the sign up was successful. + */ +- (BOOL)signUp; + +/*! + Signs up the user. Make sure that password and username are set. This will also enforce that the username isn't already taken. + @param error Error object to set on error. + @result Returns whether the sign up was successful. + */ +- (BOOL)signUp:(NSError **)error; + +/*! + Signs up the user asynchronously. Make sure that password and username are set. This will also enforce that the username isn't already taken. + */ +- (void)signUpInBackground; + +/*! + Signs up the user asynchronously. Make sure that password and username are set. This will also enforce that the username isn't already taken. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ +- (void)signUpInBackgroundWithBlock:(PFBooleanResultBlock)block; + +/*! + Signs up the user asynchronously. Make sure that password and username are set. This will also enforce that the username isn't already taken. + @param target Target object for the selector. + @param selector The selector that will be called when the asynchrounous request is complete. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError **)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ +- (void)signUpInBackgroundWithTarget:(id)target selector:(SEL)selector; + +/** @name Logging in */ + +/*! + Makes a request to login a user with specified credentials. Returns an instance + of the successfully logged in PFUser. This will also cache the user locally so + that calls to currentUser will use the latest logged in user. + @param username The username of the user. + @param password The password of the user. + @result Returns an instance of the PFUser on success. If login failed for either wrong password or wrong username, returns nil. + */ ++ (instancetype)logInWithUsername:(NSString *)username + password:(NSString *)password; + +/*! + Makes a request to login a user with specified credentials. Returns an + instance of the successfully logged in PFUser. This will also cache the user + locally so that calls to currentUser will use the latest logged in user. + @param username The username of the user. + @param password The password of the user. + @param error The error object to set on error. + @result Returns an instance of the PFUser on success. If login failed for either wrong password or wrong username, returns nil. + */ ++ (instancetype)logInWithUsername:(NSString *)username + password:(NSString *)password + error:(NSError **)error; + +/*! + Makes an asynchronous request to login a user with specified credentials. + Returns an instance of the successfully logged in PFUser. This will also cache + the user locally so that calls to currentUser will use the latest logged in user. + @param username The username of the user. + @param password The password of the user. + */ ++ (void)logInWithUsernameInBackground:(NSString *)username + password:(NSString *)password; + +/*! + Makes an asynchronous request to login a user with specified credentials. + Returns an instance of the successfully logged in PFUser. This will also cache + the user locally so that calls to currentUser will use the latest logged in user. + The selector for the callback should look like: myCallback:(PFUser *)user error:(NSError **)error + @param username The username of the user. + @param password The password of the user. + @param target Target object for the selector. + @param selector The selector that will be called when the asynchrounous request is complete. + */ ++ (void)logInWithUsernameInBackground:(NSString *)username + password:(NSString *)password + target:(id)target + selector:(SEL)selector; + +/*! + Makes an asynchronous request to log in a user with specified credentials. + Returns an instance of the successfully logged in PFUser. This will also cache + the user locally so that calls to currentUser will use the latest logged in user. + @param username The username of the user. + @param password The password of the user. + @param block The block to execute. The block should have the following argument signature: (PFUser *user, NSError *error) + */ ++ (void)logInWithUsernameInBackground:(NSString *)username + password:(NSString *)password + block:(PFUserResultBlock)block; + +/** @name Becoming a user */ + +/*! + Makes a request to become a user with the given session token. Returns an + instance of the successfully logged in PFUser. This also caches the user locally + so that calls to currentUser will use the latest logged in user. + @param sessionToken The session token for the user. + @result Returns an instance of the PFUser on success. If becoming a user fails due to incorrect token, it returns nil. + */ ++ (instancetype)become:(NSString *)sessionToken; + +/*! + Makes a request to become a user with the given session token. Returns an + instance of the successfully logged in PFUser. This will also cache the user + locally so that calls to currentUser will use the latest logged in user. + @param sessionToken The session token for the user. + @param error The error object to set on error. + @result Returns an instance of the PFUser on success. If becoming a user fails due to incorrect token, it returns nil. + */ ++ (instancetype)become:(NSString *)sessionToken + error:(NSError **)error; + +/*! + Makes an asynchronous request to become a user with the given session token. Returns an + instance of the successfully logged in PFUser. This also caches the user locally + so that calls to currentUser will use the latest logged in user. + @param sessionToken The session token for the user. + */ ++ (void)becomeInBackground:(NSString *)sessionToken; + +/*! + Makes an asynchronous request to become a user with the given session token. Returns an + instance of the successfully logged in PFUser. This also caches the user locally + so that calls to currentUser will use the latest logged in user. + The selector for the callback should look like: myCallback:(PFUser *)user error:(NSError **)error + @param sessionToken The session token for the user. + @param target Target object for the selector. + @param selector The selector that will be called when the asynchrounous request is complete. + */ ++ (void)becomeInBackground:(NSString *)sessionToken + target:(id)target + selector:(SEL)selector; + +/*! + Makes an asynchronous request to become a user with the given session token. Returns an + instance of the successfully logged in PFUser. This also caches the user locally + so that calls to currentUser will use the latest logged in user. + The selector for the callback should look like: myCallback:(PFUser *)user error:(NSError **)error + @param sessionToken The session token for the user. + @param block The block to execute. The block should have the following argument signature: (PFUser *user, NSError *error) + */ ++ (void)becomeInBackground:(NSString *)sessionToken + block:(PFUserResultBlock)block; + +/** @name Logging Out */ + +/*! + Logs out the currently logged in user on disk. + */ ++ (void)logOut; + +/** @name Requesting a Password Reset */ + +/*! + Send a password reset request for a specified email. If a user account exists with that email, + an email will be sent to that address with instructions on how to reset their password. + @param email Email of the account to send a reset password request. + @result Returns true if the reset email request is successful. False if no account was found for the email address. + */ ++ (BOOL)requestPasswordResetForEmail:(NSString *)email; + +/*! + Send a password reset request for a specified email and sets an error object. If a user + account exists with that email, an email will be sent to that address with instructions + on how to reset their password. + @param email Email of the account to send a reset password request. + @param error Error object to set on error. + @result Returns true if the reset email request is successful. False if no account was found for the email address. + */ ++ (BOOL)requestPasswordResetForEmail:(NSString *)email + error:(NSError **)error; + +/*! + Send a password reset request asynchronously for a specified email and sets an + error object. If a user account exists with that email, an email will be sent to + that address with instructions on how to reset their password. + @param email Email of the account to send a reset password request. + */ ++ (void)requestPasswordResetForEmailInBackground:(NSString *)email; + +/*! + Send a password reset request asynchronously for a specified email and sets an error object. + If a user account exists with that email, an email will be sent to that address with instructions + on how to reset their password. + @param email Email of the account to send a reset password request. + @param target Target object for the selector. + @param selector The selector that will be called when the asynchronous request is complete. It should have the following signature: (void)callbackWithResult:(NSNumber *)result error:(NSError **)error. error will be nil on success and set if there was an error. [result boolValue] will tell you whether the call succeeded or not. + */ ++ (void)requestPasswordResetForEmailInBackground:(NSString *)email + target:(id)target + selector:(SEL)selector; + +/*! + Send a password reset request asynchronously for a specified email. + If a user account exists with that email, an email will be sent to that address with instructions + on how to reset their password. + @param email Email of the account to send a reset password request. + @param block The block to execute. The block should have the following argument signature: (BOOL succeeded, NSError *error) + */ ++ (void)requestPasswordResetForEmailInBackground:(NSString *)email + block:(PFBooleanResultBlock)block; + +/** @name Querying for Users */ + +/*! + Creates a query for PFUser objects. + */ ++ (PFQuery *)query; + + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PF_EGORefreshTableHeaderView.h b/Example/Parse.framework/Versions/1.2.18/Headers/PF_EGORefreshTableHeaderView.h new file mode 100755 index 0000000..56eaa14 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PF_EGORefreshTableHeaderView.h @@ -0,0 +1,49 @@ +// +// EGORefreshTableHeaderView.h +// Demo +// +// Created by Devin Doty on 10/14/09October14. +// Copyright 2009 enormego. All rights reserved. +// +// 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 + +@protocol PF_EGORefreshTableHeaderDelegate; +@interface PF_EGORefreshTableHeaderView : UIView + +@property (nonatomic,assign) id delegate; +@property (nonatomic, retain, readonly) UILabel *lastUpdatedLabel; +@property (nonatomic, retain, readonly) UILabel *statusLabel; +@property (nonatomic, retain, readonly) UIActivityIndicatorView *activityView; + +- (void)refreshLastUpdatedDate; +- (void)egoRefreshScrollViewDidScroll:(UIScrollView *)scrollView; +- (void)egoRefreshScrollViewDidEndDragging:(UIScrollView *)scrollView; +- (void)egoRefreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView; + +@end + +@protocol PF_EGORefreshTableHeaderDelegate +- (void)egoRefreshTableHeaderDidTriggerRefresh:(PF_EGORefreshTableHeaderView*)view; +- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(PF_EGORefreshTableHeaderView*)view; +@optional +- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(PF_EGORefreshTableHeaderView*)view; +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PF_MBProgressHUD.h b/Example/Parse.framework/Versions/1.2.18/Headers/PF_MBProgressHUD.h new file mode 100755 index 0000000..93d8653 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PF_MBProgressHUD.h @@ -0,0 +1,346 @@ +// +// MBProgressHUD.h +// Version 0.4 +// Created by Matej Bukovinski on 2.4.09. +// + +// This code is distributed under the terms and conditions of the MIT license. + +// Copyright (c) 2011 Matej Bukovinski +// +// 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 + +@protocol PF_MBProgressHUDDelegate; + +///////////////////////////////////////////////////////////////////////////////////////////// + +typedef enum { + /** Progress is shown using an UIActivityIndicatorView. This is the default. */ + PF_MBProgressHUDModeIndeterminate, + /** Progress is shown using a MBRoundProgressView. */ + PF_MBProgressHUDModeDeterminate, + /** Shows a custom view */ + PF_MBProgressHUDModeCustomView +} PF_MBProgressHUDMode; + +typedef enum { + /** Opacity animation */ + PF_MBProgressHUDAnimationFade, + /** Opacity + scale animation */ + PF_MBProgressHUDAnimationZoom +} PF_MBProgressHUDAnimation; + +///////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. + * + * This is a simple drop-in class for displaying a progress HUD view similar to Apples private UIProgressHUD class. + * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all + * user input on this region, thereby preventing the user operations on components below the view. The HUD itself is + * drawn centered as a rounded semi-transparent view witch resizes depending on the user specified content. + * + * This view supports three modes of operation: + * - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView + * - MBProgressHUDModeDeterminate - shows a custom round progress indicator (MBRoundProgressView) + * - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView) + * + * All three modes can have optional labels assigned: + * - If the labelText property is set and non-empty then a label containing the provided content is placed below the + * indicator view. + * - If also the detailsLabelText property is set then another label is placed below the first label. + */ +@interface PF_MBProgressHUD : UIView { + PF_MBProgressHUDMode mode; + +#if __has_feature(objc_arc) + id __unsafe_unretained delegate; +#else + id delegate; +#endif + + SEL methodForExecution; + id targetForExecution; + id objectForExecution; + BOOL useAnimation; + + UILabel *label; + UILabel *detailsLabel; + + float progress; + + NSString *labelText; + NSString *detailsLabelText; + + BOOL isFinished; + + CGAffineTransform rotationTransform; +} + +/** + * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. + * + * @param view The view that the HUD will be added to + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @return A reference to the created HUD. + * + * @see hideHUDForView:animated: + */ ++ (PF_MBProgressHUD *)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; + +/** + * Finds a HUD sibview and hides it. The counterpart to this method is showHUDAddedTo:animated:. + * + * @param view The view that is going to be searched for a HUD subview. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @return YES if a HUD was found and removed, NO otherwise. + * + * @see hideHUDForView:animated: + */ ++ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; + +/** + * A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with + * window.bounds as the parameter. + * + * @param window The window instance that will provide the bounds for the HUD. Should probably be the same instance as + * the HUD's superview (i.e., the window that the HUD will be added to). + */ +- (id)initWithWindow:(UIWindow *)window; + +/** + * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with + * view.bounds as the parameter + * + * @param view The view instance that will provide the bounds for the HUD. Should probably be the same instance as + * the HUD's superview (i.e., the view that the HUD will be added to). + */ +- (id)initWithView:(UIView *)view; + +/** + * The UIView (i.g., a UIIMageView) to be shown when the HUD is in MBProgressHUDModeCustomView. + * For best results use a 37 by 37 pixel view (so the bounds match the build in indicator bounds). + */ +@property (retain) UIView *customView; + +/** + * MBProgressHUD operation mode. Switches between indeterminate (MBProgressHUDModeIndeterminate) and determinate + * progress (MBProgressHUDModeDeterminate). The default is MBProgressHUDModeIndeterminate. + * + * @see MBProgressHUDMode + */ +@property (assign) PF_MBProgressHUDMode mode; + +/** + * The animation type that should be used when the HUD is shown and hidden. + * + * @see MBProgressHUDAnimation + */ +@property (assign) PF_MBProgressHUDAnimation animationType; + +/** + * The HUD delegate object. If set the delegate will receive hudWasHidden callbacks when the HUD was hidden. The + * delegate should conform to the MBProgressHUDDelegate protocol and implement the hudWasHidden method. The delegate + * object will not be retained. + */ +@property (assign) id delegate; + +/** + * An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit + * the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or + * set to @"", then no message is displayed. + */ +@property (copy) NSString *labelText; + +/** + * An optional details message displayed below the labelText message. This message is displayed only if the labelText + * property is also set and is different from an empty string (@""). + */ +@property (copy) NSString *detailsLabelText; + +/** + * The opacity of the HUD window. Defaults to 0.9 (90% opacity). + */ +@property (assign) float opacity; + +/** + * The x-axis offset of the HUD relative to the centre of the superview. + */ +@property (assign) float xOffset; + +/** + * The y-ayis offset of the HUD relative to the centre of the superview. + */ +@property (assign) float yOffset; + +/** + * The amounth of space between the HUD edge and the HUD elements (labels, indicators or custom views). + * + * Defaults to 20.0 + */ +@property (assign) float margin; + +/** + * Cover the HUD background view with a radial gradient. + */ +@property (assign) BOOL dimBackground; + +/* + * Grace period is the time (in seconds) that the invoked method may be run without + * showing the HUD. If the task finishes befor the grace time runs out, the HUD will + * not be shown at all. + * This may be used to prevent HUD display for very short tasks. + * Defaults to 0 (no grace time). + * Grace time functionality is only supported when the task status is known! + * @see taskInProgress + */ +@property (assign) float graceTime; + + +/** + * The minimum time (in seconds) that the HUD is shown. + * This avoids the problem of the HUD being shown and than instantly hidden. + * Defaults to 0 (no minimum show time). + */ +@property (assign) float minShowTime; + +/** + * Indicates that the executed operation is in progress. Needed for correct graceTime operation. + * If you don't set a graceTime (different than 0.0) this does nothing. + * This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:. + * When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly), + * you need to set this property when your task starts and completes in order to have normal graceTime + * functunality. + */ +@property (assign) BOOL taskInProgress; + +/** + * Removes the HUD from it's parent view when hidden. + * Defaults to NO. + */ +@property (assign) BOOL removeFromSuperViewOnHide; + +/** + * Font to be used for the main label. Set this property if the default is not adequate. + */ +@property (retain) UIFont* labelFont; + +/** + * Font to be used for the details label. Set this property if the default is not adequate. + */ +@property (retain) UIFont* detailsLabelFont; + +/** + * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. + */ +@property (assign) float progress; + + +/** + * Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so + * the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread + * (e.g., when using something like NSOperation or calling an asynchronous call like NSUrlRequest). + * + * If you need to perform a blocking thask on the main thread, you can try spining the run loop imeidiately after calling this + * method by using: + * + * [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantPast]]; + * + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + */ +- (void)show:(BOOL)animated; + +/** + * Hide the HUD. This still calls the hudWasHidden delegate. This is the counterpart of the hide: method. Use it to + * hide the HUD when your task completes. + * + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + */ +- (void)hide:(BOOL)animated; + +/** + * Hide the HUD after a delay. This still calls the hudWasHidden delegate. This is the counterpart of the hide: method. Use it to + * hide the HUD when your task completes. + * + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @param delay Delay in secons until the HUD is hidden. + */ +- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay; + +/** + * Shows the HUD while a background task is executing in a new thread, then hides the HUD. + * + * This method also takes care of NSAutoreleasePools so your method does not have to be concerned with setting up a + * pool. + * + * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread. + * @param target The object that the target method belongs to. + * @param object An optional object to be passed to the method. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + */ +- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated; + +@end + +///////////////////////////////////////////////////////////////////////////////////////////// + +@protocol PF_MBProgressHUDDelegate + +@optional + +/** + * Called after the HUD was fully hidden from the screen. + */ +- (void)hudWasHidden:(PF_MBProgressHUD *)hud; + +/** + * @deprecated use hudWasHidden: instead + * @see hudWasHidden: + */ +- (void)hudWasHidden __attribute__ ((deprecated)); + +@end + +///////////////////////////////////////////////////////////////////////////////////////////// + +/** + * A progress view for showing definite progress by filling up a circle (pie chart). + */ +@interface PF_MBRoundProgressView : UIView { +@private + float _progress; +} + +/** + * Progress (0.0 to 1.0) + */ +@property (nonatomic, assign) float progress; + +@end + +///////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/PF_Twitter.h b/Example/Parse.framework/Versions/1.2.18/Headers/PF_Twitter.h new file mode 100644 index 0000000..4d504e8 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/PF_Twitter.h @@ -0,0 +1,43 @@ +// +// PF_Twitter.h +// Copyright (c) 2012 Parse, Inc. All rights reserved. +// + +#import + +/*! + A simple interface for interacting with the Twitter REST API, automating sign-in and OAuth signing of requests against the API. + */ +@interface PF_Twitter : NSObject { +@private + NSString *consumerKey; + NSString *consumerSecret; + NSString *authToken; + NSString *authTokenSecret; + NSString *userId; + NSString *screenName; +} + +@property (nonatomic, copy) NSString *consumerKey; +@property (nonatomic, copy) NSString *consumerSecret; +@property (nonatomic, copy) NSString *authToken; +@property (nonatomic, copy) NSString *authTokenSecret; +@property (nonatomic, copy) NSString *userId; +@property (nonatomic, copy) NSString *screenName; + +/*! + Displays an auth dialog and populates the authToken, authTokenSecret, userId, and screenName properties if the Twitter user + grants permission to the application. + @param success Invoked upon successful authorization. + @param failure Invoked upon an error occurring in the authorization process. + @param cancel Invoked when the user cancels authorization. + */ +- (void)authorizeWithSuccess:(void (^)(void))success failure:(void (^)(NSError *error))failure cancel:(void (^)(void))cancel; + +/*! + Adds a 3-legged OAuth signature to an NSMutableURLRequest based upon the properties set for the Twitter object. Use this + function to sign requests being made to the Twitter API. + */ +- (void)signRequest:(NSMutableURLRequest *)request; + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Headers/Parse.h b/Example/Parse.framework/Versions/1.2.18/Headers/Parse.h new file mode 100644 index 0000000..24b0a38 --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Headers/Parse.h @@ -0,0 +1,79 @@ +// +// Parse.h +// Parse +// +// Created by Ilya Sukhar on 9/29/11. +// Copyright 2011 Parse, Inc. All rights reserved. +// + +#import +#import "PFACL.h" +#import "PFAnalytics.h" +#import "PFAnonymousUtils.h" +#import "PFCloud.h" +#import "PFConstants.h" +#import "PFFile.h" +#import "PFGeoPoint.h" +#import "PFObject.h" +#import "PFQuery.h" +#import "PFRelation.h" +#import "PFRole.h" +#import "PFSubclassing.h" +#import "PFUser.h" + +#if PARSE_IOS_ONLY +#import "PFImageView.h" +#import "PFInstallation.h" +#import "PFLogInViewController.h" +#import "PFProduct.h" +#import "PFProductTableViewController.h" +#import "PFPurchase.h" +#import "PFPush.h" +#import "PFQueryTableViewController.h" +#import "PFSignUpViewController.h" +#import "PFTableViewCell.h" +#import "PFTwitterUtils.h" + +#if defined(__has_include) +#if __has_include() +#import +#import "PFFacebookUtils.h" +#else +#define PFFacebookUtils Please_add_the_Facebook_SDK_to_your_project +#endif +#endif + +#endif + +@interface Parse : NSObject + +/** @name Connecting to Parse */ + +/*! + Sets the applicationId and clientKey of your application. + @param applicationId The application id for your Parse application. + @param clientKey The client key for your Parse application. + */ ++ (void)setApplicationId:(NSString *)applicationId clientKey:(NSString *)clientKey; ++ (NSString *)getApplicationId; ++ (NSString *)getClientKey; + +#if PARSE_IOS_ONLY +/** @name Configuring UI Settings */ + +/*! + Set whether to show offline messages when using a Parse view or view controller related classes. + @param enabled Whether a UIAlert should be shown when the device is offline and network access is required + from a view or view controller. + */ ++ (void)offlineMessagesEnabled:(BOOL)enabled; + +/*! + Set whether to show an error message when using a Parse view or view controller related classes + and a Parse error was generated via a query. + @param enabled Whether a UIAlert should be shown when a Parse error occurs. + */ ++ (void)errorMessagesEnabled:(BOOL)enabled; +#endif + +@end diff --git a/Example/Parse.framework/Versions/1.2.18/Parse b/Example/Parse.framework/Versions/1.2.18/Parse new file mode 100644 index 0000000..3f2ac89 Binary files /dev/null and b/Example/Parse.framework/Versions/1.2.18/Parse differ diff --git a/Example/Parse.framework/Versions/1.2.18/Resources/Info.plist b/Example/Parse.framework/Versions/1.2.18/Resources/Info.plist new file mode 100644 index 0000000..ce3fc6e --- /dev/null +++ b/Example/Parse.framework/Versions/1.2.18/Resources/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Parse + CFBundleIdentifier + com.parse.Parse + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/Example/Parse.framework/Versions/1.2.18/Resources/Localizable.strings b/Example/Parse.framework/Versions/1.2.18/Resources/Localizable.strings new file mode 100644 index 0000000..e950d1b Binary files /dev/null and b/Example/Parse.framework/Versions/1.2.18/Resources/Localizable.strings differ diff --git a/Example/Parse.framework/Versions/Current b/Example/Parse.framework/Versions/Current new file mode 120000 index 0000000..5ab1538 --- /dev/null +++ b/Example/Parse.framework/Versions/Current @@ -0,0 +1 @@ +1.2.18 \ No newline at end of file diff --git a/Example/Parse.framework/third_party_licenses.txt b/Example/Parse.framework/third_party_licenses.txt new file mode 100644 index 0000000..df7d973 --- /dev/null +++ b/Example/Parse.framework/third_party_licenses.txt @@ -0,0 +1,79 @@ +THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF THE PARSE PRODUCT. + +----- + +The following software may be included in this product: AFNetworking. This software contains the following license and notice below: + +Copyright (c) 2011 Gowalla (http://gowalla.com/) + +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. + +----- + +The following software may be included in this product: EGOTableViewPullRefresh. This software contains the following license and notice below: + +// +// EGORefreshTableHeaderView.h +// Demo +// +// Created by Devin Doty on 10/14/09October14. +// Copyright 2009 enormego. All rights reserved. +// +// 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. +// + +----- + +The following software may be included in this product: MBProgressHUD. This software contains the following license and notice below: + +Copyright (c) 2013 Matej Bukovinski + +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. \ No newline at end of file diff --git a/Example/Sample.xcodeproj/project.pbxproj b/Example/Sample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..edd0abe --- /dev/null +++ b/Example/Sample.xcodeproj/project.pbxproj @@ -0,0 +1,623 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3501C43218C4147E00EE5CFC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C43118C4147E00EE5CFC /* Foundation.framework */; }; + 3501C43418C4147E00EE5CFC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C43318C4147E00EE5CFC /* CoreGraphics.framework */; }; + 3501C43618C4147E00EE5CFC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C43518C4147E00EE5CFC /* UIKit.framework */; }; + 3501C43C18C4147E00EE5CFC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3501C43A18C4147E00EE5CFC /* InfoPlist.strings */; }; + 3501C43E18C4147E00EE5CFC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C43D18C4147E00EE5CFC /* main.m */; }; + 3501C44218C4147E00EE5CFC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C44118C4147E00EE5CFC /* AppDelegate.m */; }; + 3501C44518C4147E00EE5CFC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3501C44318C4147E00EE5CFC /* Main.storyboard */; }; + 3501C44818C4147E00EE5CFC /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C44718C4147E00EE5CFC /* ViewController.m */; }; + 3501C44A18C4147E00EE5CFC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3501C44918C4147E00EE5CFC /* Images.xcassets */; }; + 3501C45118C4147E00EE5CFC /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C45018C4147E00EE5CFC /* XCTest.framework */; }; + 3501C45218C4147E00EE5CFC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C43118C4147E00EE5CFC /* Foundation.framework */; }; + 3501C45318C4147E00EE5CFC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C43518C4147E00EE5CFC /* UIKit.framework */; }; + 3501C45B18C4147E00EE5CFC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3501C45918C4147E00EE5CFC /* InfoPlist.strings */; }; + 3501C45D18C4147E00EE5CFC /* SampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C45C18C4147E00EE5CFC /* SampleTests.m */; }; + 3501C46718C4149B00EE5CFC /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C46618C4149B00EE5CFC /* Parse.framework */; }; + 3501C46818C4149B00EE5CFC /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C46618C4149B00EE5CFC /* Parse.framework */; }; + 3501C46B18C4166F00EE5CFC /* SuperParseTwitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C46A18C4166F00EE5CFC /* SuperParseTwitter.m */; }; + 3501C46C18C4166F00EE5CFC /* SuperParseTwitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C46A18C4166F00EE5CFC /* SuperParseTwitter.m */; }; + 3501C47218C4218800EE5CFC /* TWAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C46F18C4218800EE5CFC /* TWAPIManager.m */; }; + 3501C47318C4218800EE5CFC /* TWAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C46F18C4218800EE5CFC /* TWAPIManager.m */; }; + 3501C47418C4218800EE5CFC /* TWSignedRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47118C4218800EE5CFC /* TWSignedRequest.m */; }; + 3501C47518C4218800EE5CFC /* TWSignedRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47118C4218800EE5CFC /* TWSignedRequest.m */; }; + 3501C47F18C4219700EE5CFC /* OAuth+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47A18C4219700EE5CFC /* OAuth+Additions.m */; }; + 3501C48018C4219700EE5CFC /* OAuth+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47A18C4219700EE5CFC /* OAuth+Additions.m */; }; + 3501C48118C4219700EE5CFC /* OAuthCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47C18C4219700EE5CFC /* OAuthCore.m */; }; + 3501C48218C4219700EE5CFC /* OAuthCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C47C18C4219700EE5CFC /* OAuthCore.m */; }; + 3501C48518C421F500EE5CFC /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C48418C421F500EE5CFC /* NSData+Base64.m */; }; + 3501C48618C421F500EE5CFC /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 3501C48418C421F500EE5CFC /* NSData+Base64.m */; }; + 3501C48918C425A000EE5CFC /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C48818C425A000EE5CFC /* Accounts.framework */; }; + 3501C48C18C42C7900EE5CFC /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C48B18C42C7900EE5CFC /* MobileCoreServices.framework */; }; + 3501C48E18C42C8000EE5CFC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C48D18C42C8000EE5CFC /* Security.framework */; }; + 3501C49018C42C8600EE5CFC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C48F18C42C8600EE5CFC /* libz.dylib */; }; + 3501C49218C42CA600EE5CFC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49118C42CA600EE5CFC /* AudioToolbox.framework */; }; + 3501C49418C42CAC00EE5CFC /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49318C42CAC00EE5CFC /* CFNetwork.framework */; }; + 3501C49618C42CB200EE5CFC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49518C42CB200EE5CFC /* QuartzCore.framework */; }; + 3501C49818C42CC100EE5CFC /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49718C42CC100EE5CFC /* CoreLocation.framework */; }; + 3501C49A18C42CCB00EE5CFC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49918C42CCB00EE5CFC /* SystemConfiguration.framework */; }; + 3501C49C18C42D2D00EE5CFC /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3501C49B18C42D2D00EE5CFC /* StoreKit.framework */; }; + 352AC83D18C43809002FBDE2 /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 352AC83C18C43809002FBDE2 /* Parse.framework */; }; + 352AC83E18C43809002FBDE2 /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 352AC83C18C43809002FBDE2 /* Parse.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3501C45418C4147E00EE5CFC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3501C42618C4147E00EE5CFC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3501C42D18C4147E00EE5CFC; + remoteInfo = Sample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3501C42E18C4147E00EE5CFC /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3501C43118C4147E00EE5CFC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 3501C43318C4147E00EE5CFC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 3501C43518C4147E00EE5CFC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 3501C43918C4147E00EE5CFC /* Sample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Sample-Info.plist"; sourceTree = ""; }; + 3501C43B18C4147E00EE5CFC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 3501C43D18C4147E00EE5CFC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 3501C43F18C4147E00EE5CFC /* Sample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Sample-Prefix.pch"; sourceTree = ""; }; + 3501C44018C4147E00EE5CFC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 3501C44118C4147E00EE5CFC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 3501C44418C4147E00EE5CFC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 3501C44618C4147E00EE5CFC /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 3501C44718C4147E00EE5CFC /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 3501C44918C4147E00EE5CFC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 3501C44F18C4147E00EE5CFC /* SampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3501C45018C4147E00EE5CFC /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 3501C45818C4147E00EE5CFC /* SampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SampleTests-Info.plist"; sourceTree = ""; }; + 3501C45A18C4147E00EE5CFC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 3501C45C18C4147E00EE5CFC /* SampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleTests.m; sourceTree = ""; }; + 3501C46618C4149B00EE5CFC /* Parse.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Parse.framework; sourceTree = ""; }; + 3501C46918C4166F00EE5CFC /* SuperParseTwitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuperParseTwitter.h; sourceTree = ""; }; + 3501C46A18C4166F00EE5CFC /* SuperParseTwitter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SuperParseTwitter.m; sourceTree = ""; }; + 3501C46E18C4218800EE5CFC /* TWAPIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWAPIManager.h; sourceTree = ""; }; + 3501C46F18C4218800EE5CFC /* TWAPIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWAPIManager.m; sourceTree = ""; }; + 3501C47018C4218800EE5CFC /* TWSignedRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWSignedRequest.h; sourceTree = ""; }; + 3501C47118C4218800EE5CFC /* TWSignedRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWSignedRequest.m; sourceTree = ""; }; + 3501C47918C4219700EE5CFC /* OAuth+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OAuth+Additions.h"; sourceTree = ""; }; + 3501C47A18C4219700EE5CFC /* OAuth+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OAuth+Additions.m"; sourceTree = ""; }; + 3501C47B18C4219700EE5CFC /* OAuthCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthCore.h; sourceTree = ""; }; + 3501C47C18C4219700EE5CFC /* OAuthCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthCore.m; sourceTree = ""; }; + 3501C48318C421F500EE5CFC /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; + 3501C48418C421F500EE5CFC /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = ""; }; + 3501C48818C425A000EE5CFC /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = System/Library/Frameworks/Accounts.framework; sourceTree = SDKROOT; }; + 3501C48B18C42C7900EE5CFC /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 3501C48D18C42C8000EE5CFC /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + 3501C48F18C42C8600EE5CFC /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 3501C49118C42CA600EE5CFC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 3501C49318C42CAC00EE5CFC /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 3501C49518C42CB200EE5CFC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 3501C49718C42CC100EE5CFC /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 3501C49918C42CCB00EE5CFC /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 3501C49B18C42D2D00EE5CFC /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + 352AC83C18C43809002FBDE2 /* Parse.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Parse.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3501C42B18C4147E00EE5CFC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C49C18C42D2D00EE5CFC /* StoreKit.framework in Frameworks */, + 3501C49A18C42CCB00EE5CFC /* SystemConfiguration.framework in Frameworks */, + 3501C49818C42CC100EE5CFC /* CoreLocation.framework in Frameworks */, + 3501C43418C4147E00EE5CFC /* CoreGraphics.framework in Frameworks */, + 352AC83D18C43809002FBDE2 /* Parse.framework in Frameworks */, + 3501C49618C42CB200EE5CFC /* QuartzCore.framework in Frameworks */, + 3501C49418C42CAC00EE5CFC /* CFNetwork.framework in Frameworks */, + 3501C49218C42CA600EE5CFC /* AudioToolbox.framework in Frameworks */, + 3501C49018C42C8600EE5CFC /* libz.dylib in Frameworks */, + 3501C48E18C42C8000EE5CFC /* Security.framework in Frameworks */, + 3501C48C18C42C7900EE5CFC /* MobileCoreServices.framework in Frameworks */, + 3501C48918C425A000EE5CFC /* Accounts.framework in Frameworks */, + 3501C43618C4147E00EE5CFC /* UIKit.framework in Frameworks */, + 3501C46718C4149B00EE5CFC /* Parse.framework in Frameworks */, + 3501C43218C4147E00EE5CFC /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3501C44C18C4147E00EE5CFC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C45118C4147E00EE5CFC /* XCTest.framework in Frameworks */, + 3501C45318C4147E00EE5CFC /* UIKit.framework in Frameworks */, + 3501C46818C4149B00EE5CFC /* Parse.framework in Frameworks */, + 3501C45218C4147E00EE5CFC /* Foundation.framework in Frameworks */, + 352AC83E18C43809002FBDE2 /* Parse.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3501C42518C4147E00EE5CFC = { + isa = PBXGroup; + children = ( + 3501C43718C4147E00EE5CFC /* Sample */, + 3501C45618C4147E00EE5CFC /* SampleTests */, + 3501C43018C4147E00EE5CFC /* Frameworks */, + 3501C42F18C4147E00EE5CFC /* Products */, + ); + sourceTree = ""; + }; + 3501C42F18C4147E00EE5CFC /* Products */ = { + isa = PBXGroup; + children = ( + 3501C42E18C4147E00EE5CFC /* Sample.app */, + 3501C44F18C4147E00EE5CFC /* SampleTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 3501C43018C4147E00EE5CFC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 352AC83C18C43809002FBDE2 /* Parse.framework */, + 3501C49B18C42D2D00EE5CFC /* StoreKit.framework */, + 3501C49918C42CCB00EE5CFC /* SystemConfiguration.framework */, + 3501C49718C42CC100EE5CFC /* CoreLocation.framework */, + 3501C49518C42CB200EE5CFC /* QuartzCore.framework */, + 3501C49318C42CAC00EE5CFC /* CFNetwork.framework */, + 3501C49118C42CA600EE5CFC /* AudioToolbox.framework */, + 3501C48F18C42C8600EE5CFC /* libz.dylib */, + 3501C48D18C42C8000EE5CFC /* Security.framework */, + 3501C48B18C42C7900EE5CFC /* MobileCoreServices.framework */, + 3501C48818C425A000EE5CFC /* Accounts.framework */, + 3501C46618C4149B00EE5CFC /* Parse.framework */, + 3501C43118C4147E00EE5CFC /* Foundation.framework */, + 3501C43318C4147E00EE5CFC /* CoreGraphics.framework */, + 3501C43518C4147E00EE5CFC /* UIKit.framework */, + 3501C45018C4147E00EE5CFC /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 3501C43718C4147E00EE5CFC /* Sample */ = { + isa = PBXGroup; + children = ( + 3501C44018C4147E00EE5CFC /* AppDelegate.h */, + 3501C44118C4147E00EE5CFC /* AppDelegate.m */, + 3501C44318C4147E00EE5CFC /* Main.storyboard */, + 3501C44618C4147E00EE5CFC /* ViewController.h */, + 3501C44718C4147E00EE5CFC /* ViewController.m */, + 3501C46D18C4215500EE5CFC /* SuperParseTwitter */, + 3501C44918C4147E00EE5CFC /* Images.xcassets */, + 3501C43818C4147E00EE5CFC /* Supporting Files */, + ); + path = Sample; + sourceTree = ""; + }; + 3501C43818C4147E00EE5CFC /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 3501C43918C4147E00EE5CFC /* Sample-Info.plist */, + 3501C43A18C4147E00EE5CFC /* InfoPlist.strings */, + 3501C43D18C4147E00EE5CFC /* main.m */, + 3501C43F18C4147E00EE5CFC /* Sample-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 3501C45618C4147E00EE5CFC /* SampleTests */ = { + isa = PBXGroup; + children = ( + 3501C45C18C4147E00EE5CFC /* SampleTests.m */, + 3501C45718C4147E00EE5CFC /* Supporting Files */, + ); + path = SampleTests; + sourceTree = ""; + }; + 3501C45718C4147E00EE5CFC /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 3501C45818C4147E00EE5CFC /* SampleTests-Info.plist */, + 3501C45918C4147E00EE5CFC /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 3501C46D18C4215500EE5CFC /* SuperParseTwitter */ = { + isa = PBXGroup; + children = ( + 3501C46918C4166F00EE5CFC /* SuperParseTwitter.h */, + 3501C46A18C4166F00EE5CFC /* SuperParseTwitter.m */, + 3501C48718C4220200EE5CFC /* Sean Cook */, + ); + name = SuperParseTwitter; + sourceTree = ""; + }; + 3501C47618C4219700EE5CFC /* ABOAuthCore */ = { + isa = PBXGroup; + children = ( + 3501C47918C4219700EE5CFC /* OAuth+Additions.h */, + 3501C47A18C4219700EE5CFC /* OAuth+Additions.m */, + 3501C47B18C4219700EE5CFC /* OAuthCore.h */, + 3501C47C18C4219700EE5CFC /* OAuthCore.m */, + ); + path = ABOAuthCore; + sourceTree = ""; + }; + 3501C48718C4220200EE5CFC /* Sean Cook */ = { + isa = PBXGroup; + children = ( + 3501C48A18C4276D00EE5CFC /* Vendor */, + 3501C46E18C4218800EE5CFC /* TWAPIManager.h */, + 3501C46F18C4218800EE5CFC /* TWAPIManager.m */, + 3501C47018C4218800EE5CFC /* TWSignedRequest.h */, + 3501C47118C4218800EE5CFC /* TWSignedRequest.m */, + 3501C48318C421F500EE5CFC /* NSData+Base64.h */, + 3501C48418C421F500EE5CFC /* NSData+Base64.m */, + ); + name = "Sean Cook"; + sourceTree = ""; + }; + 3501C48A18C4276D00EE5CFC /* Vendor */ = { + isa = PBXGroup; + children = ( + 3501C47618C4219700EE5CFC /* ABOAuthCore */, + ); + name = Vendor; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 3501C42D18C4147E00EE5CFC /* Sample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3501C46018C4147E00EE5CFC /* Build configuration list for PBXNativeTarget "Sample" */; + buildPhases = ( + 3501C42A18C4147E00EE5CFC /* Sources */, + 3501C42B18C4147E00EE5CFC /* Frameworks */, + 3501C42C18C4147E00EE5CFC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Sample; + productName = Sample; + productReference = 3501C42E18C4147E00EE5CFC /* Sample.app */; + productType = "com.apple.product-type.application"; + }; + 3501C44E18C4147E00EE5CFC /* SampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3501C46318C4147E00EE5CFC /* Build configuration list for PBXNativeTarget "SampleTests" */; + buildPhases = ( + 3501C44B18C4147E00EE5CFC /* Sources */, + 3501C44C18C4147E00EE5CFC /* Frameworks */, + 3501C44D18C4147E00EE5CFC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3501C45518C4147E00EE5CFC /* PBXTargetDependency */, + ); + name = SampleTests; + productName = SampleTests; + productReference = 3501C44F18C4147E00EE5CFC /* SampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3501C42618C4147E00EE5CFC /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = "John Gazzini"; + TargetAttributes = { + 3501C44E18C4147E00EE5CFC = { + TestTargetID = 3501C42D18C4147E00EE5CFC; + }; + }; + }; + buildConfigurationList = 3501C42918C4147E00EE5CFC /* Build configuration list for PBXProject "Sample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 3501C42518C4147E00EE5CFC; + productRefGroup = 3501C42F18C4147E00EE5CFC /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3501C42D18C4147E00EE5CFC /* Sample */, + 3501C44E18C4147E00EE5CFC /* SampleTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3501C42C18C4147E00EE5CFC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C44A18C4147E00EE5CFC /* Images.xcassets in Resources */, + 3501C43C18C4147E00EE5CFC /* InfoPlist.strings in Resources */, + 3501C44518C4147E00EE5CFC /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3501C44D18C4147E00EE5CFC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C45B18C4147E00EE5CFC /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3501C42A18C4147E00EE5CFC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C47418C4218800EE5CFC /* TWSignedRequest.m in Sources */, + 3501C44818C4147E00EE5CFC /* ViewController.m in Sources */, + 3501C44218C4147E00EE5CFC /* AppDelegate.m in Sources */, + 3501C43E18C4147E00EE5CFC /* main.m in Sources */, + 3501C46B18C4166F00EE5CFC /* SuperParseTwitter.m in Sources */, + 3501C48118C4219700EE5CFC /* OAuthCore.m in Sources */, + 3501C47218C4218800EE5CFC /* TWAPIManager.m in Sources */, + 3501C47F18C4219700EE5CFC /* OAuth+Additions.m in Sources */, + 3501C48518C421F500EE5CFC /* NSData+Base64.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3501C44B18C4147E00EE5CFC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3501C47318C4218800EE5CFC /* TWAPIManager.m in Sources */, + 3501C48018C4219700EE5CFC /* OAuth+Additions.m in Sources */, + 3501C45D18C4147E00EE5CFC /* SampleTests.m in Sources */, + 3501C48618C421F500EE5CFC /* NSData+Base64.m in Sources */, + 3501C48218C4219700EE5CFC /* OAuthCore.m in Sources */, + 3501C47518C4218800EE5CFC /* TWSignedRequest.m in Sources */, + 3501C46C18C4166F00EE5CFC /* SuperParseTwitter.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3501C45518C4147E00EE5CFC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3501C42D18C4147E00EE5CFC /* Sample */; + targetProxy = 3501C45418C4147E00EE5CFC /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 3501C43A18C4147E00EE5CFC /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 3501C43B18C4147E00EE5CFC /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 3501C44318C4147E00EE5CFC /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 3501C44418C4147E00EE5CFC /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 3501C45918C4147E00EE5CFC /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 3501C45A18C4147E00EE5CFC /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 3501C45E18C4147E00EE5CFC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 3501C45F18C4147E00EE5CFC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3501C46118C4147E00EE5CFC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + /Users/johngazzini/Documents/Sample, + /Users/johngazzini/Documents/ParseTwitterStuff/SuperParseTwitter/Example, + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Sample/Sample-Prefix.pch"; + INFOPLIST_FILE = "Sample/Sample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 3501C46218C4147E00EE5CFC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + /Users/johngazzini/Documents/Sample, + /Users/johngazzini/Documents/ParseTwitterStuff/SuperParseTwitter/Example, + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Sample/Sample-Prefix.pch"; + INFOPLIST_FILE = "Sample/Sample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + 3501C46418C4147E00EE5CFC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + /Users/johngazzini/Documents/Sample, + /Users/johngazzini/Documents/ParseTwitterStuff/SuperParseTwitter/Example, + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Sample/Sample-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "SampleTests/SampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + 3501C46518C4147E00EE5CFC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + /Users/johngazzini/Documents/Sample, + /Users/johngazzini/Documents/ParseTwitterStuff/SuperParseTwitter/Example, + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Sample/Sample-Prefix.pch"; + INFOPLIST_FILE = "SampleTests/SampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3501C42918C4147E00EE5CFC /* Build configuration list for PBXProject "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3501C45E18C4147E00EE5CFC /* Debug */, + 3501C45F18C4147E00EE5CFC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3501C46018C4147E00EE5CFC /* Build configuration list for PBXNativeTarget "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3501C46118C4147E00EE5CFC /* Debug */, + 3501C46218C4147E00EE5CFC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3501C46318C4147E00EE5CFC /* Build configuration list for PBXNativeTarget "SampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3501C46418C4147E00EE5CFC /* Debug */, + 3501C46518C4147E00EE5CFC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3501C42618C4147E00EE5CFC /* Project object */; +} diff --git a/Source/Vendor/ABOAuthCore/OAuth+Additions.h b/Example/Sample/ABOAuthCore/OAuth+Additions.h similarity index 100% rename from Source/Vendor/ABOAuthCore/OAuth+Additions.h rename to Example/Sample/ABOAuthCore/OAuth+Additions.h diff --git a/Source/Vendor/ABOAuthCore/OAuth+Additions.m b/Example/Sample/ABOAuthCore/OAuth+Additions.m similarity index 97% rename from Source/Vendor/ABOAuthCore/OAuth+Additions.m rename to Example/Sample/ABOAuthCore/OAuth+Additions.m index b1ee30b..c124f1e 100644 --- a/Source/Vendor/ABOAuthCore/OAuth+Additions.m +++ b/Example/Sample/ABOAuthCore/OAuth+Additions.m @@ -61,7 +61,7 @@ + (NSString *)ab_GUID CFUUIDRef u = CFUUIDCreate(kCFAllocatorDefault); CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, u); CFRelease(u); - return [(NSString *)s autorelease]; + return (__bridge NSString *)s; } @end diff --git a/Source/Vendor/ABOAuthCore/OAuthCore.h b/Example/Sample/ABOAuthCore/OAuthCore.h similarity index 100% rename from Source/Vendor/ABOAuthCore/OAuthCore.h rename to Example/Sample/ABOAuthCore/OAuthCore.h diff --git a/Source/Vendor/ABOAuthCore/OAuthCore.m b/Example/Sample/ABOAuthCore/OAuthCore.m similarity index 91% rename from Source/Vendor/ABOAuthCore/OAuthCore.m rename to Example/Sample/ABOAuthCore/OAuthCore.m index 694e382..fc3e66d 100644 --- a/Source/Vendor/ABOAuthCore/OAuthCore.m +++ b/Example/Sample/ABOAuthCore/OAuthCore.m @@ -13,7 +13,7 @@ static NSInteger SortParameter(NSString *key1, NSString *key2, void *context) { NSComparisonResult r = [key1 compare:key2]; if(r == NSOrderedSame) { // compare by value in this case - NSDictionary *dict = (NSDictionary *)context; + NSDictionary *dict = (__bridge NSDictionary *)context; NSString *value1 = dict[key1]; NSString *value2 = dict[key2]; return [value1 compare:value2]; @@ -47,14 +47,14 @@ static NSInteger SortParameter(NSString *key1, NSString *key2, void *context) { NSDictionary *additionalQueryParameters = [NSURL ab_parseURLQueryString:[url query]]; NSDictionary *additionalBodyParameters = nil; if(body) { - NSString *string = [[[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding] autorelease]; + NSString *string = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]; if(string) { additionalBodyParameters = [NSURL ab_parseURLQueryString:string]; } } // combine all parameters - NSMutableDictionary *parameters = [[oAuthAuthorizationParameters mutableCopy] autorelease]; + NSMutableDictionary *parameters = [oAuthAuthorizationParameters mutableCopy]; if(additionalQueryParameters) [parameters addEntriesFromDictionary:additionalQueryParameters]; if(additionalBodyParameters) [parameters addEntriesFromDictionary:additionalBodyParameters]; @@ -65,7 +65,7 @@ static NSInteger SortParameter(NSString *key1, NSString *key2, void *context) { encodedParameters[[key ab_RFC3986EncodedString]] = [value ab_RFC3986EncodedString]; } - NSArray *sortedKeys = [[encodedParameters allKeys] sortedArrayUsingFunction:SortParameter context:encodedParameters]; + NSArray *sortedKeys = [[encodedParameters allKeys] sortedArrayUsingFunction:SortParameter context:(__bridge void *)(encodedParameters)]; NSMutableArray *parameterArray = [NSMutableArray array]; for(NSString *key in sortedKeys) { @@ -88,7 +88,7 @@ static NSInteger SortParameter(NSString *key1, NSString *key2, void *context) { NSData *signature = HMAC_SHA1(signatureBaseString, key); NSString *base64Signature = [signature base64EncodedString]; - NSMutableDictionary *authorizationHeaderDictionary = [[oAuthAuthorizationParameters mutableCopy] autorelease]; + NSMutableDictionary *authorizationHeaderDictionary = [oAuthAuthorizationParameters mutableCopy]; authorizationHeaderDictionary[@"oauth_signature"] = base64Signature; NSMutableArray *authorizationHeaderItems = [NSMutableArray array]; diff --git a/Example/Sample/AppDelegate.h b/Example/Sample/AppDelegate.h new file mode 100644 index 0000000..3ad87d7 --- /dev/null +++ b/Example/Sample/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/Example/Sample/AppDelegate.m b/Example/Sample/AppDelegate.m new file mode 100644 index 0000000..f2d0aa7 --- /dev/null +++ b/Example/Sample/AppDelegate.m @@ -0,0 +1,57 @@ +// +// AppDelegate.m +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import "AppDelegate.h" +#import + + +//In a real project, you should obfuscate these. +#define TWITTER_CONSUMER_SECRET @"" +#define TWITTER_CONSUMER_KEY @"" +#define PARSE_ID @"" +#define PARSE_CLIENT_KEY @"" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + // Override point for customization after application launch. + [Parse setApplicationId:PARSE_ID clientKey:PARSE_CLIENT_KEY]; + [PFTwitterUtils initializeWithConsumerKey:TWITTER_CONSUMER_KEY consumerSecret:TWITTER_CONSUMER_SECRET]; + [PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Example/Sample/Base.lproj/Main.storyboard b/Example/Sample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..b99208b --- /dev/null +++ b/Example/Sample/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Example/Sample/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/Sample/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a396706 --- /dev/null +++ b/Example/Sample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/Sample/Images.xcassets/LaunchImage.launchimage/Contents.json b/Example/Sample/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..c79ebd3 --- /dev/null +++ b/Example/Sample/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/Sample/NSData+Base64.h b/Example/Sample/NSData+Base64.h new file mode 100755 index 0000000..fd3de2a --- /dev/null +++ b/Example/Sample/NSData+Base64.h @@ -0,0 +1,45 @@ +// +// NSData+Base64.h +// base64 +// +// Created by Matt Gallagher on 2009/06/03. +// Copyright 2009 Matt Gallagher. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import + +void *NewBase64Decode( + const char *inputBuffer, + size_t length, + size_t *outputLength); + +char *NewBase64Encode( + const void *inputBuffer, + size_t length, + bool separateLines, + size_t *outputLength); + +@interface NSData (Base64) + ++ (NSData *)dataFromBase64String:(NSString *)aString; +- (NSString *)base64EncodedString; + +// added by Hiroshi Hashiguchi +- (NSString *)base64EncodedStringWithSeparateLines:(BOOL)separateLines; + +@end diff --git a/Example/Sample/NSData+Base64.m b/Example/Sample/NSData+Base64.m new file mode 100755 index 0000000..a842bf0 --- /dev/null +++ b/Example/Sample/NSData+Base64.m @@ -0,0 +1,329 @@ +// +// NSData+Base64.m +// base64 +// +// Created by Matt Gallagher on 2009/06/03. +// Copyright 2009 Matt Gallagher. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import "NSData+Base64.h" + +// +// Mapping from 6 bit pattern to ASCII character. +// +static unsigned char base64EncodeLookup[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// +// Definition for "masked-out" areas of the base64DecodeLookup mapping +// +#define xx 65 + +// +// Mapping from ASCII character to 6 bit pattern. +// +static unsigned char base64DecodeLookup[256] = +{ + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx, + xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx, + xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, +}; + +// +// Fundamental sizes of the binary and base64 encode/decode units in bytes +// +#define BINARY_UNIT_SIZE 3 +#define BASE64_UNIT_SIZE 4 + +// +// NewBase64Decode +// +// Decodes the base64 ASCII string in the inputBuffer to a newly malloced +// output buffer. +// +// inputBuffer - the source ASCII string for the decode +// length - the length of the string or -1 (to specify strlen should be used) +// outputLength - if not-NULL, on output will contain the decoded length +// +// returns the decoded buffer. Must be free'd by caller. Length is given by +// outputLength. +// +void *NewBase64Decode( + const char *inputBuffer, + size_t length, + size_t *outputLength) +{ + if (length == -1) + { + length = strlen(inputBuffer); + } + + size_t outputBufferSize = + ((length+BASE64_UNIT_SIZE-1) / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE; + unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize); + + size_t i = 0; + size_t j = 0; + while (i < length) + { + // + // Accumulate 4 valid characters (ignore everything else) + // + unsigned char accumulated[BASE64_UNIT_SIZE]; + size_t accumulateIndex = 0; + while (i < length) + { + unsigned char decode = base64DecodeLookup[inputBuffer[i++]]; + if (decode != xx) + { + accumulated[accumulateIndex] = decode; + accumulateIndex++; + + if (accumulateIndex == BASE64_UNIT_SIZE) + { + break; + } + } + } + + // + // Store the 6 bits from each of the 4 characters as 3 bytes + // + // (Uses improved bounds checking suggested by Alexandre Colucci) + // + if(accumulateIndex >= 2) + outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4); + if(accumulateIndex >= 3) + outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2); + if(accumulateIndex >= 4) + outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3]; + j += accumulateIndex - 1; + } + + if (outputLength) + { + *outputLength = j; + } + return outputBuffer; +} + +// +// NewBase64Encode +// +// Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced +// output buffer. +// +// inputBuffer - the source data for the encode +// length - the length of the input in bytes +// separateLines - if zero, no CR/LF characters will be added. Otherwise +// a CR/LF pair will be added every 64 encoded chars. +// outputLength - if not-NULL, on output will contain the encoded length +// (not including terminating 0 char) +// +// returns the encoded buffer. Must be free'd by caller. Length is given by +// outputLength. +// +char *NewBase64Encode( + const void *buffer, + size_t length, + bool separateLines, + size_t *outputLength) +{ + const unsigned char *inputBuffer = (const unsigned char *)buffer; + + #define MAX_NUM_PADDING_CHARS 2 + #define OUTPUT_LINE_LENGTH 64 + #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE) + #define CR_LF_SIZE 2 + + // + // Byte accurate calculation of final buffer size + // + size_t outputBufferSize = + ((length / BINARY_UNIT_SIZE) + + ((length % BINARY_UNIT_SIZE) ? 1 : 0)) + * BASE64_UNIT_SIZE; + if (separateLines) + { + outputBufferSize += + (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE; + } + + // + // Include space for a terminating zero + // + outputBufferSize += 1; + + // + // Allocate the output buffer + // + char *outputBuffer = (char *)malloc(outputBufferSize); + if (!outputBuffer) + { + return NULL; + } + + size_t i = 0; + size_t j = 0; + const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length; + size_t lineEnd = lineLength; + + while (true) + { + if (lineEnd > length) + { + lineEnd = length; + } + + for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE) + { + // + // Inner loop: turn 48 bytes into 64 base64 characters + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) + | ((inputBuffer[i + 1] & 0xF0) >> 4)]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2) + | ((inputBuffer[i + 2] & 0xC0) >> 6)]; + outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F]; + } + + if (lineEnd == length) + { + break; + } + + // + // Add the newline + // + outputBuffer[j++] = '\r'; + outputBuffer[j++] = '\n'; + lineEnd += lineLength; + } + + if (i + 1 < length) + { + // + // Handle the single '=' case + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) + | ((inputBuffer[i + 1] & 0xF0) >> 4)]; + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2]; + outputBuffer[j++] = '='; + } + else if (i < length) + { + // + // Handle the double '=' case + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4]; + outputBuffer[j++] = '='; + outputBuffer[j++] = '='; + } + outputBuffer[j] = 0; + + // + // Set the output length and return the buffer + // + if (outputLength) + { + *outputLength = j; + } + return outputBuffer; +} + +@implementation NSData (Base64) + +// +// dataFromBase64String: +// +// Creates an NSData object containing the base64 decoded representation of +// the base64 string 'aString' +// +// Parameters: +// aString - the base64 string to decode +// +// returns the autoreleased NSData representation of the base64 string +// ++ (NSData *)dataFromBase64String:(NSString *)aString +{ + NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding]; + size_t outputLength; + void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength); + NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength]; + free(outputBuffer); + return result; +} + +// +// base64EncodedString +// +// Creates an NSString object that contains the base 64 encoding of the +// receiver's data. Lines are broken at 64 characters long. +// +// returns an autoreleased NSString being the base 64 representation of the +// receiver. +// +- (NSString *)base64EncodedString +{ + size_t outputLength; + char *outputBuffer = + NewBase64Encode([self bytes], [self length], true, &outputLength); + + NSString *result = + [[NSString alloc] + initWithBytes:outputBuffer + length:outputLength + encoding:NSASCIIStringEncoding]; + free(outputBuffer); + return result; +} + +// added by Hiroshi Hashiguchi +- (NSString *)base64EncodedStringWithSeparateLines:(BOOL)separateLines +{ + size_t outputLength; + char *outputBuffer = + NewBase64Encode([self bytes], [self length], separateLines, &outputLength); + + NSString *result = + [[NSString alloc] + initWithBytes:outputBuffer + length:outputLength + encoding:NSASCIIStringEncoding]; + free(outputBuffer); + return result; +} + + +@end diff --git a/Example/Sample/Sample-Info.plist b/Example/Sample/Sample-Info.plist new file mode 100644 index 0000000..b8463c1 --- /dev/null +++ b/Example/Sample/Sample-Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + John-Gazzini.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example/Sample/Sample-Prefix.pch b/Example/Sample/Sample-Prefix.pch new file mode 100644 index 0000000..82a2bb4 --- /dev/null +++ b/Example/Sample/Sample-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_5_0 +#warning "This project uses features only available in iOS SDK 5.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Source/Classes/TWAppDelegate.m b/Example/Sample/SuperParseTwitter.h similarity index 59% rename from Source/Classes/TWAppDelegate.m rename to Example/Sample/SuperParseTwitter.h index 696100b..39351b0 100644 --- a/Source/Classes/TWAppDelegate.m +++ b/Example/Sample/SuperParseTwitter.h @@ -1,8 +1,9 @@ // -// TWAppDelegate.m -// TWiOSReverseAuthExample +// SuperParseTwitter.h +// Sample // -// Copyright (c) 2013 Sean Cook +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the @@ -24,21 +25,22 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import "TWAppDelegate.h" -#import "TWViewController.h" +#import +#import -@implementation TWAppDelegate +typedef void (^ LoginBlock)(PFUser *user, NSError *error); -@synthesize window = _window; -@synthesize viewController = _viewController; +@interface SuperParseTwitter : NSObject -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.viewController = [[TWViewController alloc] initWithNibName:@"TWViewController" bundle:nil]; - self.window.rootViewController = self.viewController; - [self.window makeKeyAndVisible]; - return YES; -} +//For most people, this method will work fine. It presents the UIActionSheet in the application's main window. ++ (void)logInWithBlock:(LoginBlock)newLoginBlock; + +// You should ensure that you obfuscate your keys before shipping ++ (NSString *)consumerKey; ++ (NSString *)consumerSecret; + + +//For weird people, or people doing weird things with the views, this method lets you specify which view to present the UIActionSheet in. ++ (void)logInWithView:(UIView *)newView Block:(LoginBlock)newLoginBlock; @end diff --git a/Example/Sample/SuperParseTwitter.m b/Example/Sample/SuperParseTwitter.m new file mode 100644 index 0000000..d376581 --- /dev/null +++ b/Example/Sample/SuperParseTwitter.m @@ -0,0 +1,246 @@ +// +// SuperParseTwitter.m +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini +// +// 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 "SuperParseTwitter.h" +#import "TWAPIManager.h" +#import + + +@interface SuperParseTwitter () + +@property (nonatomic, copy)LoginBlock loginBlock; +@property (nonatomic, strong) UIView *view; +@property (nonatomic, strong) ACAccountStore *accountStore; +@property (nonatomic, strong) TWAPIManager *apiManager; +@property (nonatomic, strong) NSArray *accounts; +@property (nonatomic, strong) UIButton *reverseAuthBtn; + +- (void)startLoginProcessWithBlock:(LoginBlock)newLoginBlock andView:(UIView *)newView; + +@end + + +@implementation SuperParseTwitter + +#pragma - Public ++ (void)logInWithView:(UIView *)newView Block:(LoginBlock)newLoginBlock { + //First: create an actual instance of this class (inception-style): + SuperParseTwitter *loginInstance = [SuperParseTwitter sharedManager]; + + //Then, tell that something to login: + [loginInstance startLoginProcessWithBlock:newLoginBlock andView:newView]; +} + ++ (void)logInWithBlock:(LoginBlock)newLoginBlock { + [SuperParseTwitter logInWithView:[[UIApplication sharedApplication].delegate window] Block:newLoginBlock]; +} + +// OBFUSCATE YOUR KEYS! ++ (NSString *)consumerKey +{ + //TODO: ENTER YOUR CONSUMER KEY HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#warning Return your Twitter consumer key here! + return @"YOUR_CONSUMER_KEY_HERE"; +} + +// OBFUSCATE YOUR KEYS! ++ (NSString *)consumerSecret +{ + //TODO: ENTER YOUR CONSUMER SECRET HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#warning Return your Twitter consumer secret here! + return @"YOUR_CONSUMER_SECRET_HERE"; +} + + + + +#pragma - Private +- (void)startLoginProcessWithBlock:(LoginBlock)newLoginBlock andView:(UIView *)newView { + _view = newView; + _accountStore = [[ACAccountStore alloc] init]; + _apiManager = [[TWAPIManager alloc] init]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshTwitterAccounts) name:ACAccountStoreDidChangeNotification object:nil]; + _loginBlock = newLoginBlock; //persisting that block is the only reason this ActualLoginClass exists + [self _refreshTwitterAccounts]; +} +/** + * Checks for the current Twitter configuration on the device / simulator. + * + * First, we check to make sure that we've got keys to work with inside Info.plist (see README) + * + * Then we check to see if the device has accounts available via +[TWAPIManager isLocalTwitterAccountAvailable]. + * + * Next, we ask the user for permission to access his/her accounts. + * + * Upon completion, the button to continue will be displayed, or the user will be presented with a status message. + */ +- (void)_refreshTwitterAccounts +{ + NSLog(@"Refreshing Twitter Accounts \n"); + + if (![TWAPIManager hasAppKeys]) { + NSLog(@"Error! You need to set your keys in SuperParseTwitter.m"); + } + else if (![TWAPIManager isLocalTwitterAccountAvailable]) { + //revert to the old web-view login as a fallback + [self oldLogin]; + } + else { + [self _obtainAccessToAccountsWithBlock:^(BOOL granted) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (granted) { + [self performReverseAuth:nil]; + } + else { + //If the user decides to make things difficult + [self oldLogin]; + NSLog(@"You were not granted access to the Twitter accounts."); + } + }); + }]; + } +} + +- (void)_obtainAccessToAccountsWithBlock:(void (^)(BOOL))block +{ + ACAccountType *twitterType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; + ACAccountStoreRequestAccessCompletionHandler handler = ^(BOOL granted, NSError *error) { + if (granted) { + self.accounts = [_accountStore accountsWithAccountType:twitterType]; + } + + block(granted); + }; + [_accountStore requestAccessToAccountsWithType:twitterType options:NULL completion:handler]; +} + +/** + * Handles the button press that initiates the token exchange. + * + * We check the current configuration inside -[UIViewController viewDidAppear]. + */ +- (void)performReverseAuth:(id)sender +{ + UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Choose an Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; + for (ACAccount *acct in _accounts) { + [sheet addButtonWithTitle:acct.username]; + } + sheet.cancelButtonIndex = [sheet addButtonWithTitle:@"Cancel"]; + [sheet showInView:self.view]; +} + + + + +//This here is a fallback, just incase the user doesn't have any Twitter accounts on their phone. +//Or if the user has Twitter accounts on their phone with invalid credentials. +//Or if the user denies the app permission to use their Twitter account, but still wants to use the app with their Twitter account. +//Or if the user is clever, and finds some other way to make reverse auth fail. +- (void)oldLogin { + [[NSNotificationCenter defaultCenter] removeObserver:self name:ACAccountStoreDidChangeNotification object:nil]; + static Boolean showingLogin = NO; //Only 1 login webview thing should be on the screen at once. + if (!showingLogin) { + showingLogin = YES; + [PFTwitterUtils logInWithBlock:^(PFUser *user, NSError *error) { + showingLogin = NO; + _loginBlock(user, error); + }]; + } +} + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex != actionSheet.cancelButtonIndex) { + [_apiManager performReverseAuthForAccount:_accounts[buttonIndex] withHandler:^(NSData *responseData, NSError *error) { + if (responseData) { + NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; + + //NSLog(@"Reverse Auth process returned: %@", responseStr); + + NSArray *parts = [responseStr componentsSeparatedByString:@"&"]; + if ([parts count] < 4) { + [self oldLogin]; + } + else { + NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:[parts count]]; + NSMutableArray *keys = [[NSMutableArray alloc] initWithCapacity:[parts count]]; + for (NSString *string in parts) { + NSArray *subParts = [string componentsSeparatedByString:@"="]; + //NSLog(@"%@ : %@", subParts[0], subParts[1]); + if ([subParts count] > 1) { + [objects addObject:subParts[1]]; + [keys addObject:subParts[0]]; + } + } + + //NSString *lined = [parts componentsJoinedByString:@"\n"]; + NSDictionary *dict = [[NSDictionary alloc] initWithObjects:objects forKeys:keys]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString *oauth_token = [dict objectForKey:@"oauth_token"]; + NSString *oauth_token_secret = [dict objectForKey:@"oauth_token_secret"]; + NSString *screen_name = [dict objectForKey:@"screen_name"]; + NSString *user_id = [dict objectForKey:@"user_id"]; + + [PFTwitterUtils logInWithTwitterId:user_id screenName:screen_name authToken:oauth_token authTokenSecret:oauth_token_secret block:^(PFUser *user, NSError *error) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:ACAccountStoreDidChangeNotification object:nil]; + _loginBlock(user, error); + }]; + + }); + } + } + else { + NSLog(@"Reverse Auth process failed. Error returned was: %@\n", [error localizedDescription]); + } + }]; + } + else { + [self oldLogin]; + } +} + + ++(id)sharedManager { + static SuperParseTwitter *sharedDataManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedDataManager = [[self alloc] init]; + }); + return sharedDataManager; +} +- (id)init { + if (self = [super init]) { + //Default Values go here! + } + return self; +} + + + +@end \ No newline at end of file diff --git a/Source/Classes/TWAPIManager.h b/Example/Sample/TWAPIManager.h similarity index 100% rename from Source/Classes/TWAPIManager.h rename to Example/Sample/TWAPIManager.h diff --git a/Source/Classes/TWAPIManager.m b/Example/Sample/TWAPIManager.m similarity index 92% rename from Source/Classes/TWAPIManager.m rename to Example/Sample/TWAPIManager.m index 90bde05..eaf7b92 100644 --- a/Source/Classes/TWAPIManager.m +++ b/Example/Sample/TWAPIManager.m @@ -30,6 +30,7 @@ #import "OAuth+Additions.h" #import "TWAPIManager.h" #import "TWSignedRequest.h" +#import "SuperParseTwitter.h" typedef void(^TWAPIHandler)(NSData *data, NSError *error); @@ -41,7 +42,7 @@ @implementation TWAPIManager */ + (BOOL)hasAppKeys { - return ([[TWSignedRequest consumerKey] length] && [[TWSignedRequest consumerSecret] length]); + return ([[SuperParseTwitter consumerKey] length] && [[SuperParseTwitter consumerSecret] length]); } /** @@ -86,7 +87,7 @@ - (void)performReverseAuthForAccount:(ACAccount *)account withHandler:(TWAPIHand NSParameterAssert(account); [self _step1WithCompletion:^(NSData *data, NSError *error) { if (!data) { - TWDLog(@"Step 1 FAILED with error %@\n", [error localizedDescription]); + //TWDLog(@"Step 1 FAILED with error %@\n", [error localizedDescription]); dispatch_async(dispatch_get_main_queue(), ^{ handler(nil, error); @@ -129,11 +130,11 @@ - (void)_step2WithAccount:(ACAccount *)account signature:(NSString *)signedRever NSParameterAssert(account); NSParameterAssert(signedReverseAuthSignature); - NSDictionary *step2Params = @{TW_X_AUTH_REVERSE_TARGET: [TWSignedRequest consumerKey], TW_X_AUTH_REVERSE_PARMS: signedReverseAuthSignature}; + NSDictionary *step2Params = @{TW_X_AUTH_REVERSE_TARGET: [SuperParseTwitter consumerKey], TW_X_AUTH_REVERSE_PARMS: signedReverseAuthSignature}; NSURL *authTokenURL = [NSURL URLWithString:TW_OAUTH_URL_AUTH_TOKEN]; SLRequest *step2Request = [self requestWithUrl:authTokenURL parameters:step2Params requestMethod:SLRequestMethodPOST]; - TWDLog(@"Step 2: Sending a request to %@\nparameters %@\n", authTokenURL, step2Params); + //TWDLog(@"Step 2: Sending a request to %@\nparameters %@\n", authTokenURL, step2Params); [step2Request setAccount:account]; [step2Request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { @@ -157,7 +158,7 @@ - (void)_step1WithCompletion:(TWAPIHandler)completion NSDictionary *dict = @{TW_X_AUTH_MODE_KEY: TW_X_AUTH_MODE_REVERSE_AUTH}; TWSignedRequest *step1Request = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST]; - TWDLog(@"Step 1: Sending a request to %@\nparameters %@\n", url, dict); + //TWDLog(@"Step 1: Sending a request to %@\nparameters %@\n", url, dict); [step1Request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ diff --git a/Source/Classes/TWSignedRequest.h b/Example/Sample/TWSignedRequest.h similarity index 94% rename from Source/Classes/TWSignedRequest.h rename to Example/Sample/TWSignedRequest.h index ba562a5..8616c9a 100644 --- a/Source/Classes/TWSignedRequest.h +++ b/Example/Sample/TWSignedRequest.h @@ -47,7 +47,4 @@ typedef void(^TWSignedRequestHandler) (NSData *data, NSURLResponse *response, NS // Perform the request, and notify handler of results - (void)performRequestWithHandler:(TWSignedRequestHandler)handler; -// You should ensure that you obfuscate your keys before shipping -+ (NSString *)consumerKey; -+ (NSString *)consumerSecret; @end diff --git a/Source/Classes/TWSignedRequest.m b/Example/Sample/TWSignedRequest.m similarity index 86% rename from Source/Classes/TWSignedRequest.m rename to Example/Sample/TWSignedRequest.m index 3c2ed6a..bfb9ec8 100644 --- a/Source/Classes/TWSignedRequest.m +++ b/Example/Sample/TWSignedRequest.m @@ -26,6 +26,7 @@ #import "OAuthCore.h" #import "TWSignedRequest.h" +#import "SuperParseTwitter.h" #define TW_HTTP_METHOD_GET @"GET" #define TW_HTTP_METHOD_POST @"POST" @@ -92,7 +93,7 @@ - (NSURLRequest *)_buildRequest // Create the authorization header and attach to our request NSData *bodyData = [paramsAsString dataUsingEncoding:NSUTF8StringEncoding]; - NSString *authorizationHeader = OAuthorizationHeader(_url, method, bodyData, [TWSignedRequest consumerKey], [TWSignedRequest consumerSecret], _authToken, _authTokenSecret); + NSString *authorizationHeader = OAuthorizationHeader(_url, method, bodyData, [SuperParseTwitter consumerKey], [SuperParseTwitter consumerSecret], _authToken, _authTokenSecret); NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url]; [request setTimeoutInterval:REQUEST_TIMEOUT_INTERVAL]; [request setHTTPMethod:method]; @@ -110,26 +111,4 @@ - (void)performRequestWithHandler:(TWSignedRequestHandler)handler }]; } -// OBFUSCATE YOUR KEYS! -+ (NSString *)consumerKey -{ - if (!gTWConsumerKey) { - NSBundle* bundle = [NSBundle mainBundle]; - gTWConsumerKey = bundle.infoDictionary[TW_CONSUMER_KEY]; - } - - return gTWConsumerKey; -} - -// OBFUSCATE YOUR KEYS! -+ (NSString *)consumerSecret -{ - if (!gTWConsumerSecret) { - NSBundle* bundle = [NSBundle mainBundle]; - gTWConsumerSecret = bundle.infoDictionary[TW_CONSUMER_SECRET]; - } - - return gTWConsumerSecret; -} - @end diff --git a/Example/Sample/ViewController.h b/Example/Sample/ViewController.h new file mode 100644 index 0000000..ef70056 --- /dev/null +++ b/Example/Sample/ViewController.h @@ -0,0 +1,13 @@ +// +// ViewController.h +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + +@end diff --git a/Example/Sample/ViewController.m b/Example/Sample/ViewController.m new file mode 100644 index 0000000..e7d5399 --- /dev/null +++ b/Example/Sample/ViewController.m @@ -0,0 +1,51 @@ +// +// ViewController.m +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import "ViewController.h" +#import "SuperParseTwitter.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + +- (void)viewDidAppear:(BOOL)animated { + + [SuperParseTwitter logInWithView:self.view Block:^(PFUser *user, NSError *error) { + if (!user) { + NSLog(@"Uh oh. The user cancelled the Twitter login."); + [self sayHello]; + return; + } else if (user.isNew) { + NSLog(@"User signed up and logged in with Twitter!"); + [self sayHello]; + } else { + NSLog(@"User logged in with Twitter!"); + [self sayHello]; + } + }]; +} + +- (void)sayHello { + NSLog(@"Hello!"); +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +@end diff --git a/Source/Other/en.lproj/InfoPlist.strings b/Example/Sample/en.lproj/InfoPlist.strings similarity index 100% rename from Source/Other/en.lproj/InfoPlist.strings rename to Example/Sample/en.lproj/InfoPlist.strings diff --git a/Example/Sample/main.m b/Example/Sample/main.m new file mode 100644 index 0000000..eebf509 --- /dev/null +++ b/Example/Sample/main.m @@ -0,0 +1,18 @@ +// +// main.m +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Example/SampleTests/SampleTests-Info.plist b/Example/SampleTests/SampleTests-Info.plist new file mode 100644 index 0000000..eb88695 --- /dev/null +++ b/Example/SampleTests/SampleTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + John-Gazzini.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Example/SampleTests/SampleTests.m b/Example/SampleTests/SampleTests.m new file mode 100644 index 0000000..aec68cd --- /dev/null +++ b/Example/SampleTests/SampleTests.m @@ -0,0 +1,34 @@ +// +// SampleTests.m +// SampleTests +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. All rights reserved. +// + +#import + +@interface SampleTests : XCTestCase + +@end + +@implementation SampleTests + +- (void)setUp +{ + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample +{ + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +} + +@end diff --git a/Example/SampleTests/en.lproj/InfoPlist.strings b/Example/SampleTests/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example/SampleTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/README.md b/README.md index 794fa8d..7c70a07 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,46 @@ -# TWiOSReverseAuthExample +#Update +This functionality is now included by default in the latest Parse SDK. If you need to support an older version of the Parse SDK, you might still find it useful. However, you should really just use the latest version of the Parse SDK instead. -## Summary +#Purpose -This project illustrates how to use the Twitter API's reverse\_auth endpoint to obtain a user's access token and secret for your application's consumer key and secret. +To replace Parse's OAuth process with deep iOS Twitter integration (pictures included below). This requires minimal changes to your existing code, and it becomes **so much easier** for a user to link their Twitter account and start using your app! -The project is configured for building with the iOS7 SDK with a deployment target of iOS6. +#Usage +1. Create a Parse app that successfully authenticates with Twitter by following [Parse's instructions](https://parse.com/docs/ios_guide#twitterusers/iOS). -The latest version of this project can be found at [github](https://github.com/seancook/TWReverseAuthExample). +2. Drag my "SuperParseTwitter" sub-folder into your project (make sure to check the "copy" box when prompted). -### To use the demo: +3. Add the following frameworks to your project (Select your project in the navigator, then your target, then the “Build Phases” tab, and look for the “Link Binary with Libraries” section): + - Accounts.framework + - Social.framework -1. First, take a look at ["Using Reverse Auth"](https://dev.twitter.com/docs/ios/using-reverse-auth) to understand how the process works. -2. Add your application's consumer key and secret to TWiOSReverseAuthExample-Info.plist under the `TWITTER_CONSUMER_KEY` and `TWITTER_CONSUMER_SECRET` keys, respectively. -3. Build and run. Click the button labeled "Perform Token Exchange" to execute the token exchange. +4. In your view controller that contains the Parse login block, make 2 replacements: + 1. Change `#import ` to `#import "SuperParseTwitter.h"` + + 2. Change `[PFTwitterUtils logInWithBlock:...];` to `[SuperParseTwitter logInWithBlock:...];` -## Author +5. Configure your Twitter app keys in SuperParseTwitter.m (the app will throw warnings if you don't). -This example was created by Sean Cook ([@theSeanCook](http://twitter.com/theSeanCook)). +###You're done! Now you'll see none of this: -### License +![reverse_auth](http://johngazzini.com/assets/images/fini_oauth.jpeg "Webview Oauth") -Copyright (c) 2013 Sean Cook +###And lots of this: -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: +![reverse_auth](http://johngazzini.com/assets/images/fini_reverse.jpeg "Reverse Auth") -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. -### Twitter Marks +#Disclaimer +At the time of writing, I can find no other drop-in libraries that provide this functionality. This library is (obviously) forked from Sean Cook's library, which was suggested by a Parser on [this post](https://parse.com/questions/ios-builtin-twitter-integration). -The use of the Twitter logos is governed by the [Guidelines for Use of the Twitter Trademark](https://support.twitter.com/articles/77641-guidelines-for-use-of-the-twitter-trademark) -### Memory Management Style +##Known Issues +- Memory Management: The app never actually releases the SuperParseTwitter singleton that gets created... oops. +- Untested: I'm sure there's a few ways to make this crash. +- [issue #249](http://www.youtube.com/watch?v=oHg5SJYRHA0) -Main application: Automatic Reference Counting (ARC) - -Third party libraries: Manual reference counting - -### Library Credits -Loren Brichter's ([@atebits](http://twitter.com/lorenb)) ABOAuthCore is available for download at [https://bitbucket.org/atebits/oauthcore](https://bitbucket.org/atebits/oauthcore) (see source files for license information). +##Suggested Updates +- Come up with a clever way to pull obfuscated keys from the same spot in both SuperParseTwitter.m and AppDelegate.m +- Include support for linking an existing PFUser to a Twitter account. But really, who does that? +- General code clean-up. Any help is appreciated; just initiate a pull-request! diff --git a/Resources/Default-568h@2x.png b/Resources/Default-568h@2x.png deleted file mode 100644 index 6ffac10..0000000 Binary files a/Resources/Default-568h@2x.png and /dev/null differ diff --git a/Resources/Default.png b/Resources/Default.png deleted file mode 100644 index 2ef38a3..0000000 Binary files a/Resources/Default.png and /dev/null differ diff --git a/Resources/Default@2x.png b/Resources/Default@2x.png deleted file mode 100644 index 9c8be40..0000000 Binary files a/Resources/Default@2x.png and /dev/null differ diff --git a/Resources/ic_twitterapi.png b/Resources/ic_twitterapi.png deleted file mode 100644 index 4d53d3f..0000000 Binary files a/Resources/ic_twitterapi.png and /dev/null differ diff --git a/Resources/ic_twitterapi@2x.png b/Resources/ic_twitterapi@2x.png deleted file mode 100644 index d17634a..0000000 Binary files a/Resources/ic_twitterapi@2x.png and /dev/null differ diff --git a/Resources/twitter.png b/Resources/twitter.png deleted file mode 100644 index 95b023e..0000000 Binary files a/Resources/twitter.png and /dev/null differ diff --git a/Source/Classes/TWViewController.m b/Source/Classes/TWViewController.m deleted file mode 100644 index a416491..0000000 --- a/Source/Classes/TWViewController.m +++ /dev/null @@ -1,205 +0,0 @@ -// -// TWViewController.m -// TWiOSReverseAuthExample -// -// Copyright (c) 2013 Sean Cook -// -// 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 -#import "OAuth+Additions.h" -#import "TWAPIManager.h" -#import "TWSignedRequest.h" -#import "TWViewController.h" - -#define ERROR_TITLE_MSG @"Whoa, there cowboy" -#define ERROR_NO_ACCOUNTS @"You must add a Twitter account in Settings.app to use this demo." -#define ERROR_PERM_ACCESS @"We weren't granted access to the user's accounts" -#define ERROR_NO_KEYS @"You need to add your Twitter app keys to Info.plist to use this demo.\nPlease see README.md for more info." -#define ERROR_OK @"OK" - -@interface TWViewController() - -@property (nonatomic, strong) ACAccountStore *accountStore; -@property (nonatomic, strong) TWAPIManager *apiManager; -@property (nonatomic, strong) NSArray *accounts; -@property (nonatomic, strong) UIButton *reverseAuthBtn; - -@end - -@implementation TWViewController - -#pragma mark - UIViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nil bundle:nil]; - if (self) { - _accountStore = [[ACAccountStore alloc] init]; - _apiManager = [[TWAPIManager alloc] init]; - } - return self; -} - -- (void)loadView -{ - CGRect appFrame = [UIScreen mainScreen].applicationFrame; - - CGRect buttonFrame = appFrame; - buttonFrame.origin.y = floorf(0.75f * appFrame.size.height); - buttonFrame.size.height = 44.0f; - buttonFrame = CGRectInset(buttonFrame, 20, 0); - - UIView *view = [[UIView alloc] initWithFrame:appFrame]; - [view setBackgroundColor:[UIColor colorWithWhite:0.502 alpha:1.000]]; - - UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"twitter.png"]]; - [view addSubview:imageView]; - [imageView sizeToFit]; - imageView.center = view.center; - - CGRect imageFrame = imageView.frame; - imageFrame.origin.y = floorf(0.25f * appFrame.size.height); - imageView.frame = imageFrame; - - _reverseAuthBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - [_reverseAuthBtn setTitle:@"Perform Token Exchange" forState:UIControlStateNormal]; - [_reverseAuthBtn addTarget:self action:@selector(performReverseAuth:) forControlEvents:UIControlEventTouchUpInside]; - _reverseAuthBtn.frame = buttonFrame; - _reverseAuthBtn.enabled = NO; - [_reverseAuthBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; - [view addSubview:_reverseAuthBtn]; - - self.view = view; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - [self _refreshTwitterAccounts]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshTwitterAccounts) name:ACAccountStoreDidChangeNotification object:nil]; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -#pragma mark - UIActionSheetDelegate - -- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if (buttonIndex != actionSheet.cancelButtonIndex) { - [_apiManager performReverseAuthForAccount:_accounts[buttonIndex] withHandler:^(NSData *responseData, NSError *error) { - if (responseData) { - NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; - - TWDLog(@"Reverse Auth process returned: %@", responseStr); - - NSArray *parts = [responseStr componentsSeparatedByString:@"&"]; - NSString *lined = [parts componentsJoinedByString:@"\n"]; - - dispatch_async(dispatch_get_main_queue(), ^{ - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:lined delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; - [alert show]; - }); - } - else { - TWALog(@"Reverse Auth process failed. Error returned was: %@\n", [error localizedDescription]); - } - }]; - } -} - -#pragma mark - Private -/** - * Checks for the current Twitter configuration on the device / simulator. - * - * First, we check to make sure that we've got keys to work with inside Info.plist (see README) - * - * Then we check to see if the device has accounts available via +[TWAPIManager isLocalTwitterAccountAvailable]. - * - * Next, we ask the user for permission to access his/her accounts. - * - * Upon completion, the button to continue will be displayed, or the user will be presented with a status message. - */ -- (void)_refreshTwitterAccounts -{ - TWDLog(@"Refreshing Twitter Accounts \n"); - - if (![TWAPIManager hasAppKeys]) { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:ERROR_TITLE_MSG message:ERROR_NO_KEYS delegate:nil cancelButtonTitle:ERROR_OK otherButtonTitles:nil]; - [alert show]; - } - else if (![TWAPIManager isLocalTwitterAccountAvailable]) { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:ERROR_TITLE_MSG message:ERROR_NO_ACCOUNTS delegate:nil cancelButtonTitle:ERROR_OK otherButtonTitles:nil]; - [alert show]; - } - else { - [self _obtainAccessToAccountsWithBlock:^(BOOL granted) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (granted) { - _reverseAuthBtn.enabled = YES; - } - else { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:ERROR_TITLE_MSG message:ERROR_PERM_ACCESS delegate:nil cancelButtonTitle:ERROR_OK otherButtonTitles:nil]; - [alert show]; - TWALog(@"You were not granted access to the Twitter accounts."); - } - }); - }]; - } -} - -- (void)_obtainAccessToAccountsWithBlock:(void (^)(BOOL))block -{ - ACAccountType *twitterType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; - ACAccountStoreRequestAccessCompletionHandler handler = ^(BOOL granted, NSError *error) { - if (granted) { - self.accounts = [_accountStore accountsWithAccountType:twitterType]; - } - - block(granted); - }; - [_accountStore requestAccessToAccountsWithType:twitterType options:NULL completion:handler]; -} - -/** - * Handles the button press that initiates the token exchange. - * - * We check the current configuration inside -[UIViewController viewDidAppear]. - */ -- (void)performReverseAuth:(id)sender -{ - UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Choose an Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; - for (ACAccount *acct in _accounts) { - [sheet addButtonWithTitle:acct.username]; - } - sheet.cancelButtonIndex = [sheet addButtonWithTitle:@"Cancel"]; - [sheet showInView:self.view]; -} - -@end diff --git a/Source/Other/TWiOSReverseAuthExample-Info.plist b/Source/Other/TWiOSReverseAuthExample-Info.plist deleted file mode 100644 index 9639f17..0000000 --- a/Source/Other/TWiOSReverseAuthExample-Info.plist +++ /dev/null @@ -1,72 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFiles - - ic_twitterapi.png - ic_twitterapi@2x.png - - CFBundleIcons - - CFBundlePrimaryIcon - - CFBundleIconFiles - - ic_twitterapi.png - ic_twitterapi@2x.png - - UIPrerenderedIcon - - - - CFBundleIdentifier - com.twitter.ios.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIStatusBarStyle - UIStatusBarStyleBlackOpaque - UIStatusBarHidden - - UIPrerenderedIcon - - LSRequiresIPhoneOS - - ////////////////////////// - - +++++++++++++++++ - - NOTE: - THIS IS FOR EXAMPLE PURPOSES ONLY. DO NOT SHIP YOUR CONSUMER KEYS AS PLAIN TEXT IN YOUR INFO.PLIST! - TWITTER_CONSUMER_KEY - - TWITTER_CONSUMER_SECRET - - ##################### - - \\\\\\\\\\\\\\\\\\\\\\\\\\ - - - diff --git a/Source/Other/TWiOSReverseAuthExample-Prefix.pch b/Source/Other/TWiOSReverseAuthExample-Prefix.pch deleted file mode 100644 index 56318f9..0000000 --- a/Source/Other/TWiOSReverseAuthExample-Prefix.pch +++ /dev/null @@ -1,33 +0,0 @@ -// -// Prefix header for all source files of the 'TWiOSReverseAuthExample' target in the 'TWiOSReverseAuthExample' project -// - -#import - -#ifndef __IPHONE_6_0 -#warning "This project was designed to be built with iOS6." -#endif - -#ifdef __OBJC__ - #import - #import -#endif - -#ifdef AWESOME_ALL_AROUND_PERSON -#warning "Interested in a job at Twitter? Send me a note: theSeanCook@twitter.com" -#endif - -// -// I use a variation of these logging methods in most projects. If anyone knows the original author, please let me know so I can attribute. -// -#ifdef DEBUG -# define TWDLog(fmt, ...) NSLog((@"\n%s\n" fmt), __PRETTY_FUNCTION__, ##__VA_ARGS__) -#else -# define TWDLog(...) -#endif - - -// -// Logs regardless of debug setting. -// -#define TWALog(fmt, ...) NSLog((@"\n%s\n" fmt), __PRETTY_FUNCTION__, ##__VA_ARGS__) diff --git a/Source/Other/main.m b/Source/Other/main.m deleted file mode 100644 index 8229672..0000000 --- a/Source/Other/main.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// main.m -// TWiOSReverseAuthExample -// -// Copyright (c) 2013 Sean Cook -// -// 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 - -#import "TWAppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([TWAppDelegate class])); - } -} diff --git a/Source/Vendor/ABOAuthCore/NSData+Base64.h b/Source/Vendor/ABOAuthCore/NSData+Base64.h deleted file mode 100755 index b7dab52..0000000 --- a/Source/Vendor/ABOAuthCore/NSData+Base64.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * NSData+Base64.h - * AQToolkit - * - * Created by Jim Dovey on 31/8/2008. - * - * Copyright (c) 2008-2009, Jim Dovey - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of this project's author nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#import - -@class NSString; - -@interface NSData (Base64) - -+ (NSData *) dataFromBase64String: (NSString *) base64String; -- (id) initWithBase64String: (NSString *) base64String; -- (NSString *) base64EncodedString; - -@end diff --git a/Source/Vendor/ABOAuthCore/NSData+Base64.m b/Source/Vendor/ABOAuthCore/NSData+Base64.m deleted file mode 100755 index c36ca89..0000000 --- a/Source/Vendor/ABOAuthCore/NSData+Base64.m +++ /dev/null @@ -1,259 +0,0 @@ -/* - * NSData+Base64.h - * AQToolkit - * - * Created by Jim Dovey on 31/8/2008. - * - * Copyright (c) 2008-2009, Jim Dovey - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of this project's author nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/* - * OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE - * - * Omni Source Code software is available from The Omni Group on their - * web site at www.omnigroup.com. - * - * 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: - * - * Any original copyright notices 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 -#import "NSData+Base64.h" - -// implementation for base64 comes from OmniFoundation. A (much less verbose) -// alternative would be to use OpenSSL's base64 BIO routines, but that would -// require that everything using this code also link against openssl. Should -// this become part of a larger independently-compiled framework that could be -// an option, but for now, since it's just a class for inclusion into other -// things, I'll resort to using the Omni version - -@implementation NSData (Base64) - -// -// Base-64 (RFC-1521) support. The following is based on mpack-1.5 (ftp://ftp.andrew.cmu.edu/pub/mpack/) -// - -#define XX 127 -static char index_64[256] = { -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63, -52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,XX,XX,XX, -XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, -15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX, -XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, -41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -}; -#define CHAR64(c) (index_64[(unsigned char)(c)]) - -#define BASE64_GETC (length > 0 ? (length--, bytes++, (unsigned int)(bytes[-1])) : (unsigned int)EOF) -#define BASE64_PUTC(c) [buffer appendBytes: &c length: 1] - -+ (NSData *) dataFromBase64String: (NSString *) base64String -{ - return ( [[[self alloc] initWithBase64String: base64String] autorelease] ); -} - -- (id) initWithBase64String: (NSString *) base64String -{ - const char * bytes; - NSUInteger length; - NSMutableData * buffer; - NSData * base64Data; - BOOL suppressCR = NO; - unsigned int c1, c2, c3, c4; - int done = 0; - char buf[3]; - - NSParameterAssert([base64String canBeConvertedToEncoding: NSASCIIStringEncoding]); - - buffer = [NSMutableData data]; - - base64Data = [base64String dataUsingEncoding: NSASCIIStringEncoding]; - bytes = [base64Data bytes]; - length = [base64Data length]; - - while ( (c1 = BASE64_GETC) != (unsigned int)EOF ) - { - if ( (c1 != '=') && CHAR64(c1) == XX ) - continue; - if ( done ) - continue; - - do - { - c2 = BASE64_GETC; - - } while ( (c2 != (unsigned int)EOF) && (c2 != '=') && (CHAR64(c2) == XX) ); - - do - { - c3 = BASE64_GETC; - - } while ( (c3 != (unsigned int)EOF) && (c3 != '=') && (CHAR64(c3) == XX) ); - - do - { - c4 = BASE64_GETC; - - } while ( (c4 != (unsigned int)EOF) && (c4 != '=') && (CHAR64(c4) == XX) ); - - if ( (c2 == (unsigned int)EOF) || (c3 == (unsigned int)EOF) || (c4 == (unsigned int)EOF) ) - { - [NSException raise: @"Base64Error" format: @"Premature end of Base64 string"]; - break; - } - - if ( (c1 == '=') || (c2 == '=') ) - { - done = 1; - continue; - } - - c1 = CHAR64(c1); - c2 = CHAR64(c2); - - buf[0] = ((c1 << 2) || ((c2 & 0x30) >> 4)); - if ( (!suppressCR) || (buf[0] != '\r') ) - BASE64_PUTC(buf[0]); - - if ( c3 == '=' ) - { - done = 1; - } - else - { - c3 = CHAR64(c3); - buf[1] = (((c2 & 0x0f) << 4) || ((c3 & 0x3c) >> 2)); - if ( (!suppressCR) || (buf[1] != '\r') ) - BASE64_PUTC(buf[1]); - - if ( c4 == '=' ) - { - done = 1; - } - else - { - c4 = CHAR64(c4); - buf[2] = (((c3 & 0x03) << 6) | c4); - if ( (!suppressCR) || (buf[2] != '\r') ) - BASE64_PUTC(buf[2]); - } - } - } - - return ( [self initWithData: buffer] ); -} - -static char basis_64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static inline void output64Chunk( int c1, int c2, int c3, int pads, NSMutableData * buffer ) -{ - char pad = '='; - BASE64_PUTC(basis_64[c1 >> 2]); - BASE64_PUTC(basis_64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)]); - - switch ( pads ) - { - case 2: - BASE64_PUTC(pad); - BASE64_PUTC(pad); - break; - - case 1: - BASE64_PUTC(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)]); - BASE64_PUTC(pad); - break; - - default: - case 0: - BASE64_PUTC(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)]); - BASE64_PUTC(basis_64[c3 & 0x3F]); - break; - } -} - -- (NSString *) base64EncodedString -{ - NSMutableData * buffer = [NSMutableData data]; - const unsigned char * bytes; - NSUInteger length; - unsigned int c1, c2, c3; - - bytes = [self bytes]; - length = [self length]; - - while ( (c1 = BASE64_GETC) != (unsigned int)EOF ) - { - c2 = BASE64_GETC; - if ( c2 == (unsigned int)EOF ) - { - output64Chunk( c1, 0, 0, 2, buffer ); - } - else - { - c3 = BASE64_GETC; - if ( c3 == (unsigned int)EOF ) - output64Chunk( c1, c2, 0, 1, buffer ); - else - output64Chunk( c1, c2, c3, 0, buffer ); - } - } - - return ( [[[NSString allocWithZone: [self zone]] initWithData: buffer encoding: NSASCIIStringEncoding] autorelease] ); -} - -@end diff --git a/SuperParseTwitter/Sean Cook/TWAPIManager.h b/SuperParseTwitter/Sean Cook/TWAPIManager.h new file mode 100644 index 0000000..8471604 --- /dev/null +++ b/SuperParseTwitter/Sean Cook/TWAPIManager.h @@ -0,0 +1,63 @@ +// +// TWAPIManager.h +// TWiOSReverseAuthExample +// +// Copyright (c) 2013 Sean Cook +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@class ACAccount; + +typedef void(^ReverseAuthResponseHandler)(NSData *responseData, NSError *error); + +@interface TWAPIManager : NSObject + +/** + * Obtains the access token and secret for |account|. + * + * There are two steps required for Reverse Auth: + * + * The first sends a signed request that *you* must sign to Twitter to obtain + * an Authorization: header. You sign the request with your own OAuth keys. + * All apps have access to Reverse Auth by default, so there are no special + * permissions required. + * + * The second step uses SLRequest to sign and send the response to step 1 back + * to Twitter. The response to this request, if everything worked, will + * include an user's access token and secret which can then + * be used in conjunction with your consumer key and secret to make + * authenticated calls to Twitter. + */ +- (void)performReverseAuthForAccount:(ACAccount *)account withHandler:(ReverseAuthResponseHandler)handler; + +/** + * Returns true if there are local Twitter accounts available. + */ ++ (BOOL)isLocalTwitterAccountAvailable; + +/** + * Returns true if the Info.plist is configured properly. + */ ++ (BOOL)hasAppKeys; + +@end diff --git a/SuperParseTwitter/Sean Cook/TWAPIManager.m b/SuperParseTwitter/Sean Cook/TWAPIManager.m new file mode 100644 index 0000000..eaf7b92 --- /dev/null +++ b/SuperParseTwitter/Sean Cook/TWAPIManager.m @@ -0,0 +1,170 @@ +// +// TWAPIManager.m +// TWiOSReverseAuthExample +// +// Copyright (c) 2013 Sean Cook +// +// 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 +#import +#import +#import "OAuth+Additions.h" +#import "TWAPIManager.h" +#import "TWSignedRequest.h" +#import "SuperParseTwitter.h" + +typedef void(^TWAPIHandler)(NSData *data, NSError *error); + +@implementation TWAPIManager + +/** + * Ensures that we have a consumer key and secret configured + * + */ ++ (BOOL)hasAppKeys +{ + return ([[SuperParseTwitter consumerKey] length] && [[SuperParseTwitter consumerSecret] length]); +} + +/** + * Returns true if there are local Twitter accounts available for use. + * + * NOTE: The system will report an account as being present even if the + * account's tokens are no longer valid. For extra protection, you should + * verify the user's credentials with a call to /1.1/accounts/verify_credentials + */ ++ (BOOL)isLocalTwitterAccountAvailable +{ + return [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]; +} + +/** + * Returns a generic self-signing request that can be used to perform Twitter + * API requests. + * + * @param The URL of the endpoint to retrieve + * @dict The API parameters to include with the request + * @requestMethod The HTTP method to use + */ +- (SLRequest *)requestWithUrl:(NSURL *)url parameters:(NSDictionary *)dict requestMethod:(SLRequestMethod )requestMethod +{ + NSParameterAssert(url); + NSParameterAssert(dict); + + return [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:requestMethod URL:url parameters:dict]; +} + +/** + * Performs Reverse Auth for the given account. + * + * Responsible for dispatching the result of the call, either sucess or error. + * + * @param account The local account for which we wish to exchange tokens + * @param handler The block to call upon completion. Will be called on the + * main thread. + */ +- (void)performReverseAuthForAccount:(ACAccount *)account withHandler:(TWAPIHandler)handler +{ + NSParameterAssert(account); + [self _step1WithCompletion:^(NSData *data, NSError *error) { + if (!data) { + //TWDLog(@"Step 1 FAILED with error %@\n", [error localizedDescription]); + + dispatch_async(dispatch_get_main_queue(), ^{ + handler(nil, error); + }); + } + else { + NSString *signedReverseAuthSignature = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [self _step2WithAccount:account signature:signedReverseAuthSignature andHandler:^(NSData *responseData, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(responseData, error); + }); + }]; + } + }]; +} + +#define TW_API_ROOT @"https://api.twitter.com" +#define TW_X_AUTH_MODE_KEY @"x_auth_mode" +#define TW_X_AUTH_MODE_REVERSE_AUTH @"reverse_auth" +#define TW_X_AUTH_MODE_CLIENT_AUTH @"client_auth" +#define TW_X_AUTH_REVERSE_PARMS @"x_reverse_auth_parameters" +#define TW_X_AUTH_REVERSE_TARGET @"x_reverse_auth_target" +#define TW_OAUTH_URL_REQUEST_TOKEN TW_API_ROOT "/oauth/request_token" +#define TW_OAUTH_URL_AUTH_TOKEN TW_API_ROOT "/oauth/access_token" + +/** + * The second stage of Reverse Auth. + * + * In this step, we send our signed authorization header to Twitter in a + * request that is signed by iOS. + * + * @param account The local account for which we wish to exchange tokens + * @param signedReverseAuthSignature The Authorization: header returned from + * a successful step 1 + * @param completion The block to call when finished. Can be called on any + * thread. + */ +- (void)_step2WithAccount:(ACAccount *)account signature:(NSString *)signedReverseAuthSignature andHandler:(TWAPIHandler)completion +{ + NSParameterAssert(account); + NSParameterAssert(signedReverseAuthSignature); + + NSDictionary *step2Params = @{TW_X_AUTH_REVERSE_TARGET: [SuperParseTwitter consumerKey], TW_X_AUTH_REVERSE_PARMS: signedReverseAuthSignature}; + NSURL *authTokenURL = [NSURL URLWithString:TW_OAUTH_URL_AUTH_TOKEN]; + SLRequest *step2Request = [self requestWithUrl:authTokenURL parameters:step2Params requestMethod:SLRequestMethodPOST]; + + //TWDLog(@"Step 2: Sending a request to %@\nparameters %@\n", authTokenURL, step2Params); + + [step2Request setAccount:account]; + [step2Request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(responseData, error); + }); + }]; +} + +/** + * The first stage of Reverse Auth. + * + * In this step, we sign and send a request to Twitter to obtain an + * Authorization: header which we will use in Step 2. + * + * @param completion The block to call when finished. Can be called on any thread. + */ +- (void)_step1WithCompletion:(TWAPIHandler)completion +{ + NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN]; + NSDictionary *dict = @{TW_X_AUTH_MODE_KEY: TW_X_AUTH_MODE_REVERSE_AUTH}; + TWSignedRequest *step1Request = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST]; + + //TWDLog(@"Step 1: Sending a request to %@\nparameters %@\n", url, dict); + + [step1Request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(data, error); + }); + }]; +} + +@end diff --git a/Source/Classes/TWAppDelegate.h b/SuperParseTwitter/Sean Cook/TWSignedRequest.h similarity index 61% rename from Source/Classes/TWAppDelegate.h rename to SuperParseTwitter/Sean Cook/TWSignedRequest.h index 805fdcb..8616c9a 100644 --- a/Source/Classes/TWAppDelegate.h +++ b/SuperParseTwitter/Sean Cook/TWSignedRequest.h @@ -1,5 +1,5 @@ // -// TWAppDelegate.h +// TWSignedRequest.h // TWiOSReverseAuthExample // // Copyright (c) 2013 Sean Cook @@ -24,14 +24,27 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import +#import -@class TWViewController; +enum TWSignedRequestMethod { + TWSignedRequestMethodGET, + TWSignedRequestMethodPOST, + TWSignedRequestMethodDELETE +}; -@interface TWAppDelegate : UIResponder +typedef enum TWSignedRequestMethod TWSignedRequestMethod; -@property (strong, nonatomic) UIWindow *window; +typedef void(^TWSignedRequestHandler) (NSData *data, NSURLResponse *response, NSError *error); -@property (strong, nonatomic) TWViewController *viewController; +@interface TWSignedRequest : NSObject + +@property (nonatomic, copy) NSString *authToken; +@property (nonatomic, copy) NSString *authTokenSecret; + +// Creates a new request +- (id)initWithURL:(NSURL *)url parameters:(NSDictionary *)parameters requestMethod:(TWSignedRequestMethod)requestMethod; + +// Perform the request, and notify handler of results +- (void)performRequestWithHandler:(TWSignedRequestHandler)handler; @end diff --git a/SuperParseTwitter/Sean Cook/TWSignedRequest.m b/SuperParseTwitter/Sean Cook/TWSignedRequest.m new file mode 100644 index 0000000..bfb9ec8 --- /dev/null +++ b/SuperParseTwitter/Sean Cook/TWSignedRequest.m @@ -0,0 +1,114 @@ +// +// TWSignedRequest.m +// TWiOSReverseAuthExample +// +// Copyright (c) 2013 Sean Cook +// +// 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 "OAuthCore.h" +#import "TWSignedRequest.h" +#import "SuperParseTwitter.h" + +#define TW_HTTP_METHOD_GET @"GET" +#define TW_HTTP_METHOD_POST @"POST" +#define TW_HTTP_METHOD_DELETE @"DELETE" +#define TW_HTTP_HEADER_AUTHORIZATION @"Authorization" +#define TW_CONSUMER_KEY @"TWITTER_CONSUMER_KEY" +#define TW_CONSUMER_SECRET @"TWITTER_CONSUMER_SECRET" + +#define REQUEST_TIMEOUT_INTERVAL 8 + +static NSString *gTWConsumerKey; +static NSString *gTWConsumerSecret; + +@interface TWSignedRequest() +{ + NSURL *_url; + NSDictionary *_parameters; + TWSignedRequestMethod _signedRequestMethod; + NSOperationQueue *_signedRequestQueue; +} + +- (NSURLRequest *)_buildRequest; + +@end + +@implementation TWSignedRequest +@synthesize authToken = _authToken; +@synthesize authTokenSecret = _authTokenSecret; + +- (id)initWithURL:(NSURL *)url parameters:(NSDictionary *)parameters requestMethod:(TWSignedRequestMethod)requestMethod +{ + self = [super init]; + if (self) { + _url = url; + _parameters = parameters; + _signedRequestMethod = requestMethod; + _signedRequestQueue = [[NSOperationQueue alloc] init]; + } + return self; +} + +- (NSURLRequest *)_buildRequest +{ + NSString *method; + + switch (_signedRequestMethod) { + case TWSignedRequestMethodPOST: + method = TW_HTTP_METHOD_POST; + break; + case TWSignedRequestMethodDELETE: + method = TW_HTTP_METHOD_DELETE; + break; + case TWSignedRequestMethodGET: + default: + method = TW_HTTP_METHOD_GET; + } + + // Build our parameter string + NSMutableString *paramsAsString = [[NSMutableString alloc] init]; + [_parameters enumerateKeysAndObjectsUsingBlock: + ^(id key, id obj, BOOL *stop) { + [paramsAsString appendFormat:@"%@=%@&", key, obj]; + }]; + + // Create the authorization header and attach to our request + NSData *bodyData = [paramsAsString dataUsingEncoding:NSUTF8StringEncoding]; + NSString *authorizationHeader = OAuthorizationHeader(_url, method, bodyData, [SuperParseTwitter consumerKey], [SuperParseTwitter consumerSecret], _authToken, _authTokenSecret); + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url]; + [request setTimeoutInterval:REQUEST_TIMEOUT_INTERVAL]; + [request setHTTPMethod:method]; + [request setValue:authorizationHeader forHTTPHeaderField:TW_HTTP_HEADER_AUTHORIZATION]; + [request setHTTPBody:bodyData]; + + return request; +} + +- (void)performRequestWithHandler:(TWSignedRequestHandler)handler +{ + NSURLRequest *request = [self _buildRequest]; + [NSURLConnection sendAsynchronousRequest:request queue:_signedRequestQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { + handler(data, response, connectionError); + }]; +} + +@end diff --git a/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.h b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.h new file mode 100644 index 0000000..9034928 --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.h @@ -0,0 +1,21 @@ +// +// OAuth+Additions.h +// +// Created by Loren Brichter on 6/9/10. +// Copyright 2010 Loren Brichter. All rights reserved. +// + +#import + +@interface NSURL (OAuthAdditions) + ++ (NSDictionary *)ab_parseURLQueryString:(NSString *)query; + +@end + +@interface NSString (OAuthAdditions) + ++ (NSString *)ab_GUID; +- (NSString *)ab_RFC3986EncodedString; + +@end diff --git a/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.m b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.m new file mode 100644 index 0000000..c124f1e --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuth+Additions.m @@ -0,0 +1,67 @@ +// +// OAuth+Additions.m +// +// Created by Loren Brichter on 6/9/10. +// Copyright 2010 Loren Brichter. All rights reserved. +// + +#import "OAuth+Additions.h" + +@implementation NSURL (OAuthAdditions) + ++ (NSDictionary *)ab_parseURLQueryString:(NSString *)query +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + NSArray *pairs = [query componentsSeparatedByString:@"&"]; + for(NSString *pair in pairs) { + NSArray *keyValue = [pair componentsSeparatedByString:@"="]; + if([keyValue count] == 2) { + NSString *key = keyValue[0]; + NSString *value = keyValue[1]; + value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + if(key && value) + dict[key] = value; + } + } + return [NSDictionary dictionaryWithDictionary:dict]; +} + +@end + +@implementation NSString (OAuthAdditions) + +- (NSString *)ab_RFC3986EncodedString // UTF-8 encodes prior to URL encoding +{ + NSMutableString *result = [NSMutableString string]; + const char *p = [self UTF8String]; + unsigned char c; + + for(; (c = *p); p++) + { + switch(c) + { + case '0' ... '9': + case 'A' ... 'Z': + case 'a' ... 'z': + case '.': + case '-': + case '~': + case '_': + [result appendFormat:@"%c", c]; + break; + default: + [result appendFormat:@"%%%02X", c]; + } + } + return result; +} + ++ (NSString *)ab_GUID +{ + CFUUIDRef u = CFUUIDCreate(kCFAllocatorDefault); + CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, u); + CFRelease(u); + return (__bridge NSString *)s; +} + +@end diff --git a/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.h b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.h new file mode 100644 index 0000000..f001a5b --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.h @@ -0,0 +1,16 @@ +// +// OAuthCore.h +// +// Created by Loren Brichter on 6/9/10. +// Copyright 2010 Loren Brichter. All rights reserved. +// + +#import + +extern NSString *OAuthorizationHeader(NSURL *url, + NSString *method, + NSData *body, + NSString *_oAuthConsumerKey, + NSString *_oAuthConsumerSecret, + NSString *_oAuthToken, + NSString *_oAuthTokenSecret); diff --git a/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.m b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.m new file mode 100644 index 0000000..fc3e66d --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/ABOAuthCore/OAuthCore.m @@ -0,0 +1,107 @@ +// +// OAuthCore.m +// +// Created by Loren Brichter on 6/9/10. +// Copyright 2010 Loren Brichter. All rights reserved. +// + +#import "OAuthCore.h" +#import "OAuth+Additions.h" +#import "NSData+Base64.h" +#import + +static NSInteger SortParameter(NSString *key1, NSString *key2, void *context) { + NSComparisonResult r = [key1 compare:key2]; + if(r == NSOrderedSame) { // compare by value in this case + NSDictionary *dict = (__bridge NSDictionary *)context; + NSString *value1 = dict[key1]; + NSString *value2 = dict[key2]; + return [value1 compare:value2]; + } + return r; +} + +static NSData *HMAC_SHA1(NSString *data, NSString *key) { + unsigned char buf[CC_SHA1_DIGEST_LENGTH]; + CCHmac(kCCHmacAlgSHA1, [key UTF8String], [key length], [data UTF8String], [data length], buf); + return [NSData dataWithBytes:buf length:CC_SHA1_DIGEST_LENGTH]; +} + +NSString *OAuthorizationHeader(NSURL *url, NSString *method, NSData *body, NSString *_oAuthConsumerKey, NSString *_oAuthConsumerSecret, NSString *_oAuthToken, NSString *_oAuthTokenSecret) +{ + NSString *_oAuthNonce = [NSString ab_GUID]; + NSString *_oAuthTimestamp = [NSString stringWithFormat:@"%d", (int)[[NSDate date] timeIntervalSince1970]]; + NSString *_oAuthSignatureMethod = @"HMAC-SHA1"; + NSString *_oAuthVersion = @"1.0"; + + NSMutableDictionary *oAuthAuthorizationParameters = [NSMutableDictionary dictionary]; + oAuthAuthorizationParameters[@"oauth_nonce"] = _oAuthNonce; + oAuthAuthorizationParameters[@"oauth_timestamp"] = _oAuthTimestamp; + oAuthAuthorizationParameters[@"oauth_signature_method"] = _oAuthSignatureMethod; + oAuthAuthorizationParameters[@"oauth_version"] = _oAuthVersion; + oAuthAuthorizationParameters[@"oauth_consumer_key"] = _oAuthConsumerKey; + if(_oAuthToken) + oAuthAuthorizationParameters[@"oauth_token"] = _oAuthToken; + + // get query and body parameters + NSDictionary *additionalQueryParameters = [NSURL ab_parseURLQueryString:[url query]]; + NSDictionary *additionalBodyParameters = nil; + if(body) { + NSString *string = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]; + if(string) { + additionalBodyParameters = [NSURL ab_parseURLQueryString:string]; + } + } + + // combine all parameters + NSMutableDictionary *parameters = [oAuthAuthorizationParameters mutableCopy]; + if(additionalQueryParameters) [parameters addEntriesFromDictionary:additionalQueryParameters]; + if(additionalBodyParameters) [parameters addEntriesFromDictionary:additionalBodyParameters]; + + // -> UTF-8 -> RFC3986 + NSMutableDictionary *encodedParameters = [NSMutableDictionary dictionary]; + for(NSString *key in parameters) { + NSString *value = parameters[key]; + encodedParameters[[key ab_RFC3986EncodedString]] = [value ab_RFC3986EncodedString]; + } + + NSArray *sortedKeys = [[encodedParameters allKeys] sortedArrayUsingFunction:SortParameter context:(__bridge void *)(encodedParameters)]; + + NSMutableArray *parameterArray = [NSMutableArray array]; + for(NSString *key in sortedKeys) { + [parameterArray addObject:[NSString stringWithFormat:@"%@=%@", key, encodedParameters[key]]]; + } + NSString *normalizedParameterString = [parameterArray componentsJoinedByString:@"&"]; + + NSString *normalizedURLString = [NSString stringWithFormat:@"%@://%@%@", [url scheme], [url host], [url path]]; + + NSString *signatureBaseString = [NSString stringWithFormat:@"%@&%@&%@", + [method ab_RFC3986EncodedString], + [normalizedURLString ab_RFC3986EncodedString], + [normalizedParameterString ab_RFC3986EncodedString]]; + + // Updated this from original to allow us to pass in nil to method + NSString *key = [NSString stringWithFormat:@"%@&%@", + [_oAuthConsumerSecret ab_RFC3986EncodedString], + (_oAuthTokenSecret) ? [_oAuthTokenSecret ab_RFC3986EncodedString] : @""]; + + NSData *signature = HMAC_SHA1(signatureBaseString, key); + NSString *base64Signature = [signature base64EncodedString]; + + NSMutableDictionary *authorizationHeaderDictionary = [oAuthAuthorizationParameters mutableCopy]; + authorizationHeaderDictionary[@"oauth_signature"] = base64Signature; + + NSMutableArray *authorizationHeaderItems = [NSMutableArray array]; + for(NSString *key in authorizationHeaderDictionary) { + NSString *value = authorizationHeaderDictionary[key]; + [authorizationHeaderItems addObject:[NSString stringWithFormat:@"%@=\"%@\"", + [key ab_RFC3986EncodedString], + [value ab_RFC3986EncodedString]]]; + } + + NSString *authorizationHeaderString = [authorizationHeaderItems componentsJoinedByString:@", "]; + + authorizationHeaderString = [NSString stringWithFormat:@"OAuth %@", authorizationHeaderString]; + + return authorizationHeaderString; +} diff --git a/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.h b/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.h new file mode 100755 index 0000000..fd3de2a --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.h @@ -0,0 +1,45 @@ +// +// NSData+Base64.h +// base64 +// +// Created by Matt Gallagher on 2009/06/03. +// Copyright 2009 Matt Gallagher. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import + +void *NewBase64Decode( + const char *inputBuffer, + size_t length, + size_t *outputLength); + +char *NewBase64Encode( + const void *inputBuffer, + size_t length, + bool separateLines, + size_t *outputLength); + +@interface NSData (Base64) + ++ (NSData *)dataFromBase64String:(NSString *)aString; +- (NSString *)base64EncodedString; + +// added by Hiroshi Hashiguchi +- (NSString *)base64EncodedStringWithSeparateLines:(BOOL)separateLines; + +@end diff --git a/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.m b/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.m new file mode 100755 index 0000000..a842bf0 --- /dev/null +++ b/SuperParseTwitter/Sean Cook/Vendor/NSData+Base64.m @@ -0,0 +1,329 @@ +// +// NSData+Base64.m +// base64 +// +// Created by Matt Gallagher on 2009/06/03. +// Copyright 2009 Matt Gallagher. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import "NSData+Base64.h" + +// +// Mapping from 6 bit pattern to ASCII character. +// +static unsigned char base64EncodeLookup[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// +// Definition for "masked-out" areas of the base64DecodeLookup mapping +// +#define xx 65 + +// +// Mapping from ASCII character to 6 bit pattern. +// +static unsigned char base64DecodeLookup[256] = +{ + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx, + xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx, + xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, +}; + +// +// Fundamental sizes of the binary and base64 encode/decode units in bytes +// +#define BINARY_UNIT_SIZE 3 +#define BASE64_UNIT_SIZE 4 + +// +// NewBase64Decode +// +// Decodes the base64 ASCII string in the inputBuffer to a newly malloced +// output buffer. +// +// inputBuffer - the source ASCII string for the decode +// length - the length of the string or -1 (to specify strlen should be used) +// outputLength - if not-NULL, on output will contain the decoded length +// +// returns the decoded buffer. Must be free'd by caller. Length is given by +// outputLength. +// +void *NewBase64Decode( + const char *inputBuffer, + size_t length, + size_t *outputLength) +{ + if (length == -1) + { + length = strlen(inputBuffer); + } + + size_t outputBufferSize = + ((length+BASE64_UNIT_SIZE-1) / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE; + unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize); + + size_t i = 0; + size_t j = 0; + while (i < length) + { + // + // Accumulate 4 valid characters (ignore everything else) + // + unsigned char accumulated[BASE64_UNIT_SIZE]; + size_t accumulateIndex = 0; + while (i < length) + { + unsigned char decode = base64DecodeLookup[inputBuffer[i++]]; + if (decode != xx) + { + accumulated[accumulateIndex] = decode; + accumulateIndex++; + + if (accumulateIndex == BASE64_UNIT_SIZE) + { + break; + } + } + } + + // + // Store the 6 bits from each of the 4 characters as 3 bytes + // + // (Uses improved bounds checking suggested by Alexandre Colucci) + // + if(accumulateIndex >= 2) + outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4); + if(accumulateIndex >= 3) + outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2); + if(accumulateIndex >= 4) + outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3]; + j += accumulateIndex - 1; + } + + if (outputLength) + { + *outputLength = j; + } + return outputBuffer; +} + +// +// NewBase64Encode +// +// Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced +// output buffer. +// +// inputBuffer - the source data for the encode +// length - the length of the input in bytes +// separateLines - if zero, no CR/LF characters will be added. Otherwise +// a CR/LF pair will be added every 64 encoded chars. +// outputLength - if not-NULL, on output will contain the encoded length +// (not including terminating 0 char) +// +// returns the encoded buffer. Must be free'd by caller. Length is given by +// outputLength. +// +char *NewBase64Encode( + const void *buffer, + size_t length, + bool separateLines, + size_t *outputLength) +{ + const unsigned char *inputBuffer = (const unsigned char *)buffer; + + #define MAX_NUM_PADDING_CHARS 2 + #define OUTPUT_LINE_LENGTH 64 + #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE) + #define CR_LF_SIZE 2 + + // + // Byte accurate calculation of final buffer size + // + size_t outputBufferSize = + ((length / BINARY_UNIT_SIZE) + + ((length % BINARY_UNIT_SIZE) ? 1 : 0)) + * BASE64_UNIT_SIZE; + if (separateLines) + { + outputBufferSize += + (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE; + } + + // + // Include space for a terminating zero + // + outputBufferSize += 1; + + // + // Allocate the output buffer + // + char *outputBuffer = (char *)malloc(outputBufferSize); + if (!outputBuffer) + { + return NULL; + } + + size_t i = 0; + size_t j = 0; + const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length; + size_t lineEnd = lineLength; + + while (true) + { + if (lineEnd > length) + { + lineEnd = length; + } + + for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE) + { + // + // Inner loop: turn 48 bytes into 64 base64 characters + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) + | ((inputBuffer[i + 1] & 0xF0) >> 4)]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2) + | ((inputBuffer[i + 2] & 0xC0) >> 6)]; + outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F]; + } + + if (lineEnd == length) + { + break; + } + + // + // Add the newline + // + outputBuffer[j++] = '\r'; + outputBuffer[j++] = '\n'; + lineEnd += lineLength; + } + + if (i + 1 < length) + { + // + // Handle the single '=' case + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) + | ((inputBuffer[i + 1] & 0xF0) >> 4)]; + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2]; + outputBuffer[j++] = '='; + } + else if (i < length) + { + // + // Handle the double '=' case + // + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; + outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4]; + outputBuffer[j++] = '='; + outputBuffer[j++] = '='; + } + outputBuffer[j] = 0; + + // + // Set the output length and return the buffer + // + if (outputLength) + { + *outputLength = j; + } + return outputBuffer; +} + +@implementation NSData (Base64) + +// +// dataFromBase64String: +// +// Creates an NSData object containing the base64 decoded representation of +// the base64 string 'aString' +// +// Parameters: +// aString - the base64 string to decode +// +// returns the autoreleased NSData representation of the base64 string +// ++ (NSData *)dataFromBase64String:(NSString *)aString +{ + NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding]; + size_t outputLength; + void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength); + NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength]; + free(outputBuffer); + return result; +} + +// +// base64EncodedString +// +// Creates an NSString object that contains the base 64 encoding of the +// receiver's data. Lines are broken at 64 characters long. +// +// returns an autoreleased NSString being the base 64 representation of the +// receiver. +// +- (NSString *)base64EncodedString +{ + size_t outputLength; + char *outputBuffer = + NewBase64Encode([self bytes], [self length], true, &outputLength); + + NSString *result = + [[NSString alloc] + initWithBytes:outputBuffer + length:outputLength + encoding:NSASCIIStringEncoding]; + free(outputBuffer); + return result; +} + +// added by Hiroshi Hashiguchi +- (NSString *)base64EncodedStringWithSeparateLines:(BOOL)separateLines +{ + size_t outputLength; + char *outputBuffer = + NewBase64Encode([self bytes], [self length], separateLines, &outputLength); + + NSString *result = + [[NSString alloc] + initWithBytes:outputBuffer + length:outputLength + encoding:NSASCIIStringEncoding]; + free(outputBuffer); + return result; +} + + +@end diff --git a/Source/Classes/TWViewController.h b/SuperParseTwitter/SuperParseTwitter.h similarity index 59% rename from Source/Classes/TWViewController.h rename to SuperParseTwitter/SuperParseTwitter.h index af82193..39351b0 100644 --- a/Source/Classes/TWViewController.h +++ b/SuperParseTwitter/SuperParseTwitter.h @@ -1,8 +1,9 @@ // -// TWViewController.h -// TWiOSReverseAuthExample +// SuperParseTwitter.h +// Sample // -// Copyright (c) 2013 Sean Cook +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the @@ -24,8 +25,22 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import +#import +#import -@interface TWViewController : UIViewController +typedef void (^ LoginBlock)(PFUser *user, NSError *error); + +@interface SuperParseTwitter : NSObject + +//For most people, this method will work fine. It presents the UIActionSheet in the application's main window. ++ (void)logInWithBlock:(LoginBlock)newLoginBlock; + +// You should ensure that you obfuscate your keys before shipping ++ (NSString *)consumerKey; ++ (NSString *)consumerSecret; + + +//For weird people, or people doing weird things with the views, this method lets you specify which view to present the UIActionSheet in. ++ (void)logInWithView:(UIView *)newView Block:(LoginBlock)newLoginBlock; @end diff --git a/SuperParseTwitter/SuperParseTwitter.m b/SuperParseTwitter/SuperParseTwitter.m new file mode 100644 index 0000000..d376581 --- /dev/null +++ b/SuperParseTwitter/SuperParseTwitter.m @@ -0,0 +1,246 @@ +// +// SuperParseTwitter.m +// Sample +// +// Created by John Gazzini on 3/2/14. +// Copyright (c) 2014 John Gazzini +// +// 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 "SuperParseTwitter.h" +#import "TWAPIManager.h" +#import + + +@interface SuperParseTwitter () + +@property (nonatomic, copy)LoginBlock loginBlock; +@property (nonatomic, strong) UIView *view; +@property (nonatomic, strong) ACAccountStore *accountStore; +@property (nonatomic, strong) TWAPIManager *apiManager; +@property (nonatomic, strong) NSArray *accounts; +@property (nonatomic, strong) UIButton *reverseAuthBtn; + +- (void)startLoginProcessWithBlock:(LoginBlock)newLoginBlock andView:(UIView *)newView; + +@end + + +@implementation SuperParseTwitter + +#pragma - Public ++ (void)logInWithView:(UIView *)newView Block:(LoginBlock)newLoginBlock { + //First: create an actual instance of this class (inception-style): + SuperParseTwitter *loginInstance = [SuperParseTwitter sharedManager]; + + //Then, tell that something to login: + [loginInstance startLoginProcessWithBlock:newLoginBlock andView:newView]; +} + ++ (void)logInWithBlock:(LoginBlock)newLoginBlock { + [SuperParseTwitter logInWithView:[[UIApplication sharedApplication].delegate window] Block:newLoginBlock]; +} + +// OBFUSCATE YOUR KEYS! ++ (NSString *)consumerKey +{ + //TODO: ENTER YOUR CONSUMER KEY HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#warning Return your Twitter consumer key here! + return @"YOUR_CONSUMER_KEY_HERE"; +} + +// OBFUSCATE YOUR KEYS! ++ (NSString *)consumerSecret +{ + //TODO: ENTER YOUR CONSUMER SECRET HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#warning Return your Twitter consumer secret here! + return @"YOUR_CONSUMER_SECRET_HERE"; +} + + + + +#pragma - Private +- (void)startLoginProcessWithBlock:(LoginBlock)newLoginBlock andView:(UIView *)newView { + _view = newView; + _accountStore = [[ACAccountStore alloc] init]; + _apiManager = [[TWAPIManager alloc] init]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshTwitterAccounts) name:ACAccountStoreDidChangeNotification object:nil]; + _loginBlock = newLoginBlock; //persisting that block is the only reason this ActualLoginClass exists + [self _refreshTwitterAccounts]; +} +/** + * Checks for the current Twitter configuration on the device / simulator. + * + * First, we check to make sure that we've got keys to work with inside Info.plist (see README) + * + * Then we check to see if the device has accounts available via +[TWAPIManager isLocalTwitterAccountAvailable]. + * + * Next, we ask the user for permission to access his/her accounts. + * + * Upon completion, the button to continue will be displayed, or the user will be presented with a status message. + */ +- (void)_refreshTwitterAccounts +{ + NSLog(@"Refreshing Twitter Accounts \n"); + + if (![TWAPIManager hasAppKeys]) { + NSLog(@"Error! You need to set your keys in SuperParseTwitter.m"); + } + else if (![TWAPIManager isLocalTwitterAccountAvailable]) { + //revert to the old web-view login as a fallback + [self oldLogin]; + } + else { + [self _obtainAccessToAccountsWithBlock:^(BOOL granted) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (granted) { + [self performReverseAuth:nil]; + } + else { + //If the user decides to make things difficult + [self oldLogin]; + NSLog(@"You were not granted access to the Twitter accounts."); + } + }); + }]; + } +} + +- (void)_obtainAccessToAccountsWithBlock:(void (^)(BOOL))block +{ + ACAccountType *twitterType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; + ACAccountStoreRequestAccessCompletionHandler handler = ^(BOOL granted, NSError *error) { + if (granted) { + self.accounts = [_accountStore accountsWithAccountType:twitterType]; + } + + block(granted); + }; + [_accountStore requestAccessToAccountsWithType:twitterType options:NULL completion:handler]; +} + +/** + * Handles the button press that initiates the token exchange. + * + * We check the current configuration inside -[UIViewController viewDidAppear]. + */ +- (void)performReverseAuth:(id)sender +{ + UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Choose an Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; + for (ACAccount *acct in _accounts) { + [sheet addButtonWithTitle:acct.username]; + } + sheet.cancelButtonIndex = [sheet addButtonWithTitle:@"Cancel"]; + [sheet showInView:self.view]; +} + + + + +//This here is a fallback, just incase the user doesn't have any Twitter accounts on their phone. +//Or if the user has Twitter accounts on their phone with invalid credentials. +//Or if the user denies the app permission to use their Twitter account, but still wants to use the app with their Twitter account. +//Or if the user is clever, and finds some other way to make reverse auth fail. +- (void)oldLogin { + [[NSNotificationCenter defaultCenter] removeObserver:self name:ACAccountStoreDidChangeNotification object:nil]; + static Boolean showingLogin = NO; //Only 1 login webview thing should be on the screen at once. + if (!showingLogin) { + showingLogin = YES; + [PFTwitterUtils logInWithBlock:^(PFUser *user, NSError *error) { + showingLogin = NO; + _loginBlock(user, error); + }]; + } +} + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex != actionSheet.cancelButtonIndex) { + [_apiManager performReverseAuthForAccount:_accounts[buttonIndex] withHandler:^(NSData *responseData, NSError *error) { + if (responseData) { + NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; + + //NSLog(@"Reverse Auth process returned: %@", responseStr); + + NSArray *parts = [responseStr componentsSeparatedByString:@"&"]; + if ([parts count] < 4) { + [self oldLogin]; + } + else { + NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:[parts count]]; + NSMutableArray *keys = [[NSMutableArray alloc] initWithCapacity:[parts count]]; + for (NSString *string in parts) { + NSArray *subParts = [string componentsSeparatedByString:@"="]; + //NSLog(@"%@ : %@", subParts[0], subParts[1]); + if ([subParts count] > 1) { + [objects addObject:subParts[1]]; + [keys addObject:subParts[0]]; + } + } + + //NSString *lined = [parts componentsJoinedByString:@"\n"]; + NSDictionary *dict = [[NSDictionary alloc] initWithObjects:objects forKeys:keys]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString *oauth_token = [dict objectForKey:@"oauth_token"]; + NSString *oauth_token_secret = [dict objectForKey:@"oauth_token_secret"]; + NSString *screen_name = [dict objectForKey:@"screen_name"]; + NSString *user_id = [dict objectForKey:@"user_id"]; + + [PFTwitterUtils logInWithTwitterId:user_id screenName:screen_name authToken:oauth_token authTokenSecret:oauth_token_secret block:^(PFUser *user, NSError *error) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:ACAccountStoreDidChangeNotification object:nil]; + _loginBlock(user, error); + }]; + + }); + } + } + else { + NSLog(@"Reverse Auth process failed. Error returned was: %@\n", [error localizedDescription]); + } + }]; + } + else { + [self oldLogin]; + } +} + + ++(id)sharedManager { + static SuperParseTwitter *sharedDataManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedDataManager = [[self alloc] init]; + }); + return sharedDataManager; +} +- (id)init { + if (self = [super init]) { + //Default Values go here! + } + return self; +} + + + +@end \ No newline at end of file diff --git a/TWiOSReverseAuthExample.xcodeproj/project.pbxproj b/TWiOSReverseAuthExample.xcodeproj/project.pbxproj deleted file mode 100644 index f2f7f09..0000000 --- a/TWiOSReverseAuthExample.xcodeproj/project.pbxproj +++ /dev/null @@ -1,386 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - CD3557481610E7290004F744 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF37997142293220071ABF7 /* Accounts.framework */; }; - CDAACA6B1610E55A006E4808 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF37960142291940071ABF7 /* UIKit.framework */; }; - CDAACA6C1610E55A006E4808 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF37962142291940071ABF7 /* Foundation.framework */; }; - CDAACA6E1610E55A006E4808 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDAACA6D1610E55A006E4808 /* CoreGraphics.framework */; }; - CDAACAA31610E5D9006E4808 /* TWAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A1FF1610E3060051AE3D /* TWAPIManager.m */; }; - CDAACAA51610E5D9006E4808 /* TWAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2011610E3060051AE3D /* TWAppDelegate.m */; }; - CDAACAA71610E5D9006E4808 /* TWSignedRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2031610E3060051AE3D /* TWSignedRequest.m */; settings = {COMPILER_FLAGS = "-D'TWITTER_CONSUMER_KEY=@\"$(TWITTER_CONSUMER_KEY)\"' -D'TWITTER_CONSUMER_SECRET=@\"$(TWITTER_CONSUMER_SECRET)\"'"; }; }; - CDAACAA91610E5D9006E4808 /* TWViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2051610E3060051AE3D /* TWViewController.m */; }; - CDAACAAA1610E5D9006E4808 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2091610E3060051AE3D /* main.m */; }; - CDAACAAC1610E5D9006E4808 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A20F1610E3060051AE3D /* NSData+Base64.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - CDAACAAE1610E5D9006E4808 /* OAuth+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2111610E3060051AE3D /* OAuth+Additions.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - CDAACAB01610E5D9006E4808 /* OAuthCore.m in Sources */ = {isa = PBXBuildFile; fileRef = CD40A2131610E3060051AE3D /* OAuthCore.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - CDAACAB11610E5F6006E4808 /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF53BCA160BC8C500AD69A6 /* Social.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - CDAACAB31610E606006E4808 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1EA1610E0DC0051AE3D /* Default-568h@2x.png */; }; - CDAACAB41610E606006E4808 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1EB1610E0DC0051AE3D /* Default.png */; }; - CDAACAB51610E606006E4808 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1EC1610E0DC0051AE3D /* Default@2x.png */; }; - CDAACAB61610E606006E4808 /* ic_twitterapi.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1ED1610E0DC0051AE3D /* ic_twitterapi.png */; }; - CDAACAB71610E606006E4808 /* ic_twitterapi@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1EE1610E0DC0051AE3D /* ic_twitterapi@2x.png */; }; - CDAACAB81610E606006E4808 /* twitter.png in Resources */ = {isa = PBXBuildFile; fileRef = CD40A1EF1610E0DC0051AE3D /* twitter.png */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - CD14C12214B3A92B00B8A188 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; - CD21A6191610E4EA002E73B7 /* TWiOSReverseAuthExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TWiOSReverseAuthExample-Info.plist"; sourceTree = ""; }; - CD21A61A1610E4EA002E73B7 /* TWiOSReverseAuthExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TWiOSReverseAuthExample-Prefix.pch"; sourceTree = ""; }; - CD40A1EA1610E0DC0051AE3D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - CD40A1EB1610E0DC0051AE3D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - CD40A1EC1610E0DC0051AE3D /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; - CD40A1ED1610E0DC0051AE3D /* ic_twitterapi.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_twitterapi.png; sourceTree = ""; }; - CD40A1EE1610E0DC0051AE3D /* ic_twitterapi@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ic_twitterapi@2x.png"; sourceTree = ""; }; - CD40A1EF1610E0DC0051AE3D /* twitter.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = twitter.png; sourceTree = ""; }; - CD40A1FE1610E3060051AE3D /* TWAPIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWAPIManager.h; sourceTree = ""; }; - CD40A1FF1610E3060051AE3D /* TWAPIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWAPIManager.m; sourceTree = ""; }; - CD40A2001610E3060051AE3D /* TWAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWAppDelegate.h; sourceTree = ""; }; - CD40A2011610E3060051AE3D /* TWAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWAppDelegate.m; sourceTree = ""; }; - CD40A2021610E3060051AE3D /* TWSignedRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWSignedRequest.h; sourceTree = ""; }; - CD40A2031610E3060051AE3D /* TWSignedRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWSignedRequest.m; sourceTree = ""; }; - CD40A2041610E3060051AE3D /* TWViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWViewController.h; sourceTree = ""; }; - CD40A2051610E3060051AE3D /* TWViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TWViewController.m; sourceTree = ""; }; - CD40A2081610E3060051AE3D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - CD40A2091610E3060051AE3D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - CD40A20E1610E3060051AE3D /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; - CD40A20F1610E3060051AE3D /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = ""; }; - CD40A2101610E3060051AE3D /* OAuth+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OAuth+Additions.h"; sourceTree = ""; }; - CD40A2111610E3060051AE3D /* OAuth+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OAuth+Additions.m"; sourceTree = ""; }; - CD40A2121610E3060051AE3D /* OAuthCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthCore.h; sourceTree = ""; }; - CD40A2131610E3060051AE3D /* OAuthCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthCore.m; sourceTree = ""; }; - CDAACA691610E55A006E4808 /* ReverseAuth.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReverseAuth.app; sourceTree = BUILT_PRODUCTS_DIR; }; - CDAACA6D1610E55A006E4808 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - CDF37960142291940071ABF7 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - CDF37962142291940071ABF7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - CDF379951422931E0071ABF7 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; }; - CDF37997142293220071ABF7 /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = System/Library/Frameworks/Accounts.framework; sourceTree = SDKROOT; }; - CDF53BCA160BC8C500AD69A6 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - CDAACA661610E55A006E4808 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CD3557481610E7290004F744 /* Accounts.framework in Frameworks */, - CDAACAB11610E5F6006E4808 /* Social.framework in Frameworks */, - CDAACA6B1610E55A006E4808 /* UIKit.framework in Frameworks */, - CDAACA6C1610E55A006E4808 /* Foundation.framework in Frameworks */, - CDAACA6E1610E55A006E4808 /* CoreGraphics.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - CD40A1E91610E0DC0051AE3D /* Resources */ = { - isa = PBXGroup; - children = ( - CD40A1EA1610E0DC0051AE3D /* Default-568h@2x.png */, - CD40A1EB1610E0DC0051AE3D /* Default.png */, - CD40A1EC1610E0DC0051AE3D /* Default@2x.png */, - CD40A1ED1610E0DC0051AE3D /* ic_twitterapi.png */, - CD40A1EE1610E0DC0051AE3D /* ic_twitterapi@2x.png */, - CD40A1EF1610E0DC0051AE3D /* twitter.png */, - ); - path = Resources; - sourceTree = ""; - }; - CD40A1FC1610E3060051AE3D /* Source */ = { - isa = PBXGroup; - children = ( - CD40A1FD1610E3060051AE3D /* Classes */, - CD40A2061610E3060051AE3D /* Other */, - CD40A20C1610E3060051AE3D /* Vendor */, - ); - path = Source; - sourceTree = ""; - }; - CD40A1FD1610E3060051AE3D /* Classes */ = { - isa = PBXGroup; - children = ( - CD40A1FE1610E3060051AE3D /* TWAPIManager.h */, - CD40A1FF1610E3060051AE3D /* TWAPIManager.m */, - CD40A2001610E3060051AE3D /* TWAppDelegate.h */, - CD40A2011610E3060051AE3D /* TWAppDelegate.m */, - CD40A2021610E3060051AE3D /* TWSignedRequest.h */, - CD40A2031610E3060051AE3D /* TWSignedRequest.m */, - CD40A2041610E3060051AE3D /* TWViewController.h */, - CD40A2051610E3060051AE3D /* TWViewController.m */, - ); - path = Classes; - sourceTree = ""; - }; - CD40A2061610E3060051AE3D /* Other */ = { - isa = PBXGroup; - children = ( - CD21A6191610E4EA002E73B7 /* TWiOSReverseAuthExample-Info.plist */, - CD21A61A1610E4EA002E73B7 /* TWiOSReverseAuthExample-Prefix.pch */, - CD40A2071610E3060051AE3D /* InfoPlist.strings */, - CD40A2091610E3060051AE3D /* main.m */, - ); - path = Other; - sourceTree = ""; - }; - CD40A20C1610E3060051AE3D /* Vendor */ = { - isa = PBXGroup; - children = ( - CD40A20D1610E3060051AE3D /* ABOAuthCore */, - ); - path = Vendor; - sourceTree = ""; - }; - CD40A20D1610E3060051AE3D /* ABOAuthCore */ = { - isa = PBXGroup; - children = ( - CD40A20E1610E3060051AE3D /* NSData+Base64.h */, - CD40A20F1610E3060051AE3D /* NSData+Base64.m */, - CD40A2101610E3060051AE3D /* OAuth+Additions.h */, - CD40A2111610E3060051AE3D /* OAuth+Additions.m */, - CD40A2121610E3060051AE3D /* OAuthCore.h */, - CD40A2131610E3060051AE3D /* OAuthCore.m */, - ); - path = ABOAuthCore; - sourceTree = ""; - }; - CDF37951142291940071ABF7 = { - isa = PBXGroup; - children = ( - CD14C12214B3A92B00B8A188 /* README.md */, - CD40A1FC1610E3060051AE3D /* Source */, - CD40A1E91610E0DC0051AE3D /* Resources */, - CDF3795D142291940071ABF7 /* Products */, - CDF3795F142291940071ABF7 /* Frameworks */, - ); - sourceTree = ""; - }; - CDF3795D142291940071ABF7 /* Products */ = { - isa = PBXGroup; - children = ( - CDAACA691610E55A006E4808 /* ReverseAuth.app */, - ); - name = Products; - sourceTree = ""; - }; - CDF3795F142291940071ABF7 /* Frameworks */ = { - isa = PBXGroup; - children = ( - CDF53BCA160BC8C500AD69A6 /* Social.framework */, - CDF37997142293220071ABF7 /* Accounts.framework */, - CDF379951422931E0071ABF7 /* Twitter.framework */, - CDF37960142291940071ABF7 /* UIKit.framework */, - CDF37962142291940071ABF7 /* Foundation.framework */, - CDAACA6D1610E55A006E4808 /* CoreGraphics.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - CDAACA681610E55A006E4808 /* ReverseAuth */ = { - isa = PBXNativeTarget; - buildConfigurationList = CDAACA9C1610E55A006E4808 /* Build configuration list for PBXNativeTarget "ReverseAuth" */; - buildPhases = ( - CDAACA651610E55A006E4808 /* Sources */, - CDAACA661610E55A006E4808 /* Frameworks */, - CDAACA671610E55A006E4808 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ReverseAuth; - productName = ReverseAuth; - productReference = CDAACA691610E55A006E4808 /* ReverseAuth.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - CDF37953142291940071ABF7 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0460; - ORGANIZATIONNAME = "Twitter, Inc"; - }; - buildConfigurationList = CDF37956142291940071ABF7 /* Build configuration list for PBXProject "TWiOSReverseAuthExample" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = CDF37951142291940071ABF7; - productRefGroup = CDF3795D142291940071ABF7 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - CDAACA681610E55A006E4808 /* ReverseAuth */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - CDAACA671610E55A006E4808 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CDAACAB31610E606006E4808 /* Default-568h@2x.png in Resources */, - CDAACAB41610E606006E4808 /* Default.png in Resources */, - CDAACAB51610E606006E4808 /* Default@2x.png in Resources */, - CDAACAB61610E606006E4808 /* ic_twitterapi.png in Resources */, - CDAACAB71610E606006E4808 /* ic_twitterapi@2x.png in Resources */, - CDAACAB81610E606006E4808 /* twitter.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - CDAACA651610E55A006E4808 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CDAACAA31610E5D9006E4808 /* TWAPIManager.m in Sources */, - CDAACAA51610E5D9006E4808 /* TWAppDelegate.m in Sources */, - CDAACAA71610E5D9006E4808 /* TWSignedRequest.m in Sources */, - CDAACAA91610E5D9006E4808 /* TWViewController.m in Sources */, - CDAACAAA1610E5D9006E4808 /* main.m in Sources */, - CDAACAAC1610E5D9006E4808 /* NSData+Base64.m in Sources */, - CDAACAAE1610E5D9006E4808 /* OAuth+Additions.m in Sources */, - CDAACAB01610E5D9006E4808 /* OAuthCore.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - CD40A2071610E3060051AE3D /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - CD40A2081610E3060051AE3D /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - CDAACA9D1610E55A006E4808 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Source/Other/TWiOSReverseAuthExample-Prefix.pch"; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - INFOPLIST_FILE = "Source/Other/TWiOSReverseAuthExample-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - CDAACA9E1610E55A006E4808 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Source/Other/TWiOSReverseAuthExample-Prefix.pch"; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - INFOPLIST_FILE = "Source/Other/TWiOSReverseAuthExample-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - CDF3798D142291940071ABF7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - OTHER_CFLAGS = ""; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = NO; - }; - name = Debug; - }; - CDF3798E142291940071ABF7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - CDAACA9C1610E55A006E4808 /* Build configuration list for PBXNativeTarget "ReverseAuth" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CDAACA9D1610E55A006E4808 /* Debug */, - CDAACA9E1610E55A006E4808 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - CDF37956142291940071ABF7 /* Build configuration list for PBXProject "TWiOSReverseAuthExample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CDF3798D142291940071ABF7 /* Debug */, - CDF3798E142291940071ABF7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = CDF37953142291940071ABF7 /* Project object */; -}