diff --git a/External/google-plus-ios-sdk/Changelog b/External/google-plus-ios-sdk/Changelog index 90344a99..015f192d 100644 --- a/External/google-plus-ios-sdk/Changelog +++ b/External/google-plus-ios-sdk/Changelog @@ -1,3 +1,9 @@ +2012-10-12 -- v1.1.0 +- Content deep linking on Google+ share +- iOS6 support +- Shortened class names +- Bug fixes + 2012-06-25 -- v1.0.0 - Google+ sign-in button, share plugin, and Google+ history integration library with sample app. diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.m index 28938e24..cbf556e1 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.m @@ -80,7 +80,7 @@ static NSData *DecodeBase64StringCommon(NSString *base64Str, const char *cString = [base64Str cStringUsingEncoding:NSASCIIStringEncoding]; if (cString == nil) return nil; - NSUInteger inputLength = strlen(cString); + NSInteger inputLength = strlen(cString); if (inputLength % 4 != 0) return nil; if (inputLength == 0) return [NSData data]; diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.h index 68018bfa..2f20137d 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.h @@ -17,6 +17,9 @@ // GTLBatchQuery.h // +// Batch query documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Batch_Operations + #import "GTLQuery.h" @interface GTLBatchQuery : NSObject { diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.h index 4a04b4dc..f6b1ffb3 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.h @@ -16,6 +16,9 @@ // // GTLDateTime.h // +// This is an immutable class representing a date and optionally a +// time with time zone. +// #import #import "GTLDefines.h" @@ -28,14 +31,16 @@ NSTimeZone *timeZone_; // specific time zone by name, if known } -// Note: nil can be passed for time zone arguments when the time zone is not -// known. - + (GTLDateTime *)dateTimeWithRFC3339String:(NSString *)str; + +// timeZone may be nil if the time zone is not known. + (GTLDateTime *)dateTimeWithDate:(NSDate *)date timeZone:(NSTimeZone *)tz; -- (void)setFromDate:(NSDate *)date timeZone:(NSTimeZone *)tz; -- (void)setFromRFC3339String:(NSString *)str; +// Use this method to make a dateTime for an all-day event (date only, so +// hasTime is NO.) ++ (GTLDateTime *)dateTimeForAllDayWithDate:(NSDate *)date; + ++ (GTLDateTime *)dateTimeWithDateComponents:(NSDateComponents *)date; @property (nonatomic, readonly) NSDate *date; @property (nonatomic, readonly) NSCalendar *calendar; @@ -43,14 +48,13 @@ @property (nonatomic, readonly) NSString *RFC3339String; @property (nonatomic, readonly) NSString *stringValue; // same as RFC3339String -@property (nonatomic, retain) NSTimeZone *timeZone; -@property (nonatomic, copy) NSDateComponents *dateComponents; -@property (nonatomic, assign) NSInteger milliseconds; // This is only for the fraction of a second 0-999 +@property (nonatomic, readonly, retain) NSTimeZone *timeZone; +@property (nonatomic, readonly, copy) NSDateComponents *dateComponents; +@property (nonatomic, readonly) NSInteger milliseconds; // This is only for the fraction of a second 0-999 -@property (nonatomic, assign) BOOL hasTime; -@property (nonatomic, assign) NSInteger offsetSeconds; -@property (nonatomic, assign, getter=isUniversalTime) BOOL universalTime; +@property (nonatomic, readonly) BOOL hasTime; +@property (nonatomic, readonly) NSInteger offsetSeconds; +@property (nonatomic, readonly, getter=isUniversalTime) BOOL universalTime; -- (void)setTimeZone:(NSTimeZone *)timeZone withOffsetSeconds:(NSInteger)val; @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.m index 7e45759e..632943d8 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.m @@ -19,6 +19,20 @@ #import "GTLDateTime.h" +@interface GTLDateTime () + +- (void)setFromDate:(NSDate *)date timeZone:(NSTimeZone *)tz; +- (void)setFromRFC3339String:(NSString *)str; + +@property (nonatomic, retain, readwrite) NSTimeZone *timeZone; +@property (nonatomic, copy, readwrite) NSDateComponents *dateComponents; +@property (nonatomic, assign, readwrite) NSInteger milliseconds; + +@property (nonatomic, assign, readwrite) BOOL hasTime; +@property (nonatomic, assign, readwrite) NSInteger offsetSeconds; +@property (nonatomic, assign, getter=isUniversalTime, readwrite) BOOL universalTime; + +@end @implementation GTLDateTime @@ -60,6 +74,30 @@ return result; } ++ (GTLDateTime *)dateTimeForAllDayWithDate:(NSDate *)date { + if (date == nil) return nil; + + GTLDateTime *result = [[[self alloc] init] autorelease]; + [result setFromDate:date timeZone:nil]; + result.hasTime = NO; + return result; +} + ++ (GTLDateTime *)dateTimeWithDateComponents:(NSDateComponents *)components { + NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; + NSDate *date = [cal dateFromComponents:components]; +#if GTL_IPHONE + NSTimeZone *tz = [components timeZone]; +#else + // NSDateComponents added timeZone: in Mac OS X 10.7. + NSTimeZone *tz = nil; + if ([components respondsToSelector:@selector(timeZone)]) { + tz = [components timeZone]; + } +#endif + return [self dateTimeWithDate:date timeZone:tz]; +} + - (void)dealloc { [dateComponents_ release]; [timeZone_ release]; @@ -67,15 +105,8 @@ } - (id)copyWithZone:(NSZone *)zone { - - GTLDateTime *newObj = [[GTLDateTime alloc] init]; - - newObj.universalTime = self.isUniversalTime; - [newObj setTimeZone:self.timeZone withOffsetSeconds:self.offsetSeconds]; - newObj.dateComponents = self.dateComponents; - newObj.milliseconds = self.milliseconds; - - return newObj; + // Object is immutable + return [self retain]; } // until NSDateComponent implements isEqual, we'll use this @@ -148,13 +179,6 @@ } } -- (void)setTimeZone:(NSTimeZone *)timeZone withOffsetSeconds:(NSInteger)val { - [timeZone_ release]; - timeZone_ = [timeZone retain]; - - offsetSeconds_ = val; -} - - (NSCalendar *)calendar { NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; NSTimeZone *tz = self.timeZone; diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.h index fcbdf43c..42d79fe4 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.h @@ -17,6 +17,8 @@ // GTLObject.h // +// GTLObject documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Objects_and_Queries #import @@ -51,7 +53,7 @@ // Used when creating the subobjects from this one. NSDictionary *surrogates_; - + // Any complex object hung off this object goes into the cache so the // next fetch will get the same object back instead of having to recreate // it. @@ -156,15 +158,39 @@ @end // Collection objects with an "items" property should derive from GTLCollection -// object. This provides support for fast object enumeration and the -// itemAtIndex: convenience method. +// object. This provides support for fast object enumeration, the +// itemAtIndex: convenience method, and indexed subscripts. // // Subclasses must implement the items method dynamically. -@interface GTLCollectionObject : GTLObject +@interface GTLCollectionObject : GTLObject { + @private + NSDictionary *identifierMap_; +} -// itemAtIndex: returns nil when the index exceeds the bounds of the items array +// itemAtIndex: and objectAtIndexedSubscript: return nil when the index exceeds +// the bounds of the items array. - (id)itemAtIndex:(NSUInteger)idx; +- (id)objectAtIndexedSubscript:(NSInteger)idx; + +// itemForIdentifier: looks up items from the collection object by identifier, +// and returns the first one. +// +// Typically, items will have a unique identifier (with key "id" in the +// object's JSON). This method returns the first item found in the collection +// with the specified identifier. +// +// The first time this method is used, the collection will cache a map of +// identifiers to items. If the items list for the instance somehow changes, +// use the reset method below to force a new cache to be created for this +// collection. +- (id)itemForIdentifier:(NSString *)key; + +// Identifiers for all items are cached when the first one is obtained. +// This method resets the cache. It is needed only if the item list has +// changed. +- (void)resetIdentifierMap; + @end @interface GTLCollectionObject (DynamicMethods) diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.m index cf4e84cc..8f1048e3 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.m @@ -516,14 +516,11 @@ static NSMutableDictionary *gKindMap = nil; defaultClass:(Class)defaultClass surrogates:(NSDictionary *)surrogates batchClassMap:(NSDictionary *)batchClassMap { - if ([json isEqual:[NSNull null]]) { + if ([json count] == 0 || [json isEqual:[NSNull null]]) { // no actual result, such as the response from a delete return nil; } - GTL_ASSERT([json count] != 0, @"Creating object from empty json"); - if ([json count] == 0) return nil; - // Determine the class to instantiate, based on the original fetch // request or by looking up "kind" string from the registration at // +load time of GTLObject subclasses @@ -629,9 +626,13 @@ static NSMutableDictionary *gArrayPropertyToClassMapCache = nil; @end @implementation GTLCollectionObject - // Subclasses must implement the items method dynamically. +- (void)dealloc { + [identifierMap_ release]; + [super dealloc]; +} + - (id)itemAtIndex:(NSUInteger)idx { NSArray *items = [self performSelector:@selector(items)]; if (idx < [items count]) { @@ -640,6 +641,36 @@ static NSMutableDictionary *gArrayPropertyToClassMapCache = nil; return nil; } +- (id)objectAtIndexedSubscript:(NSInteger)idx { + if (idx >= 0) { + return [self itemAtIndex:(NSUInteger)idx]; + } + return nil; +} + +- (id)itemForIdentifier:(NSString *)key { + if (identifierMap_ == nil) { + NSArray *items = [self performSelector:@selector(items)]; + NSMutableDictionary *dict = + [NSMutableDictionary dictionaryWithCapacity:[items count]]; + for (id item in items) { + id identifier = [item valueForKey:@"identifier"]; + if (identifier != nil && identifier != [NSNull null]) { + if ([dict objectForKey:identifier] == nil) { + [dict setObject:item forKey:identifier]; + } + } + } + identifierMap_ = [dict copy]; + } + return [identifierMap_ objectForKey:key]; +} + +- (void)resetIdentifierMap { + [identifierMap_ release]; + identifierMap_ = nil; +} + // NSFastEnumeration protocol - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlus.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlus.h index ac691b73..f7e52a46 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlus.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlus.h @@ -24,13 +24,12 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ #import "GTLPlusConstants.h" #import "GTLPlusItemScope.h" #import "GTLPlusMoment.h" -#import "GTLPlusPerson.h" #import "GTLQueryPlus.h" #import "GTLServicePlus.h" diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.h index e2e425dd..f4f91c55 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.h @@ -24,7 +24,7 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ #import @@ -36,11 +36,9 @@ // Authorization scope // Know who you are on Google -GTL_EXTERN NSString * const kGTLAuthScopePlusMe; // "https://www.googleapis.com/auth/plus.me" -// View and manage user activity information in Google+ -GTL_EXTERN NSString * const kGTLAuthScopePlusMomentsWrite; // "https://www.googleapis.com/auth/plus.moments.write" -// View your email address -GTL_EXTERN NSString * const kGTLAuthScopePlusUserinfoEmail; // "https://www.googleapis.com/auth/userinfo.email" +GTL_EXTERN NSString * const kGTLAuthScopePlusMe; // "https://www.googleapis.com/auth/plus.me" +// Send your activity to your private Google+ history +GTL_EXTERN NSString * const kGTLAuthScopePlusMomentsWrite; // "https://www.googleapis.com/auth/plus.moments.write" // Collection GTL_EXTERN NSString * const kGTLPlusCollectionVault; // "vault" diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.m index 2c15fda1..28f4a30e 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.m @@ -24,14 +24,13 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ #import "GTLPlusConstants.h" // Authorization scope -NSString * const kGTLAuthScopePlusMe = @"https://www.googleapis.com/auth/plus.me"; -NSString * const kGTLAuthScopePlusMomentsWrite = @"https://www.googleapis.com/auth/plus.moments.write"; -NSString * const kGTLAuthScopePlusUserinfoEmail = @"https://www.googleapis.com/auth/userinfo.email"; +NSString * const kGTLAuthScopePlusMe = @"https://www.googleapis.com/auth/plus.me"; +NSString * const kGTLAuthScopePlusMomentsWrite = @"https://www.googleapis.com/auth/plus.moments.write"; // Collection NSString * const kGTLPlusCollectionVault = @"vault"; diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.h index 38166b26..6826f2bc 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.h @@ -24,7 +24,7 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLPlusItemScope (0 custom class methods, 55 custom properties) @@ -169,11 +169,11 @@ // belongs to. @property (retain) GTLPlusItemScope *partOfTVSeries; -// The main performer or performers of the event—for example, a presenter, +// The main performer or performers of the event-for example, a presenter, // musician, or actor. @property (retain) NSArray *performers; // of GTLPlusItemScope -// Player type required—for example, Flash or Silverlight. +// Player type required-for example, Flash or Silverlight. @property (copy) NSString *playerType; // Postal code. @@ -186,7 +186,7 @@ @property (copy) NSString *ratingValue; // Review rating. -@property (retain) NSArray *reviewRating; // of GTLPlusItemScope +@property (retain) GTLPlusItemScope *reviewRating; // The start date and time of the event (in ISO 8601 date format). @property (copy) NSString *startDate; @@ -213,7 +213,7 @@ // The item type. @property (copy) NSString *type; -// A url for this scope. +// A URL for the item upon which the action was performed. @property (copy) NSString *url; // The width of the media object. diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.m index e9c89799..4ae390c0 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.m @@ -24,7 +24,7 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLPlusItemScope (0 custom class methods, 55 custom properties) @@ -66,7 +66,6 @@ [GTLPlusItemScope class], @"author", [GTLPlusItemScope class], @"contributor", [GTLPlusItemScope class], @"performers", - [GTLPlusItemScope class], @"reviewRating", nil]; return map; } diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.h index 1d4d98d1..1ab05cac 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.h @@ -24,10 +24,9 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLPlusMoment (0 custom class methods, 6 custom properties) -// GTLPlusMomentVerb (0 custom class methods, 1 custom properties) #if GTL_BUILT_AS_FRAMEWORK #import "GTL/GTLObject.h" @@ -36,7 +35,6 @@ #endif @class GTLPlusItemScope; -@class GTLPlusMomentVerb; // ---------------------------------------------------------------------------- // @@ -45,35 +43,23 @@ @interface GTLPlusMoment : GTLObject +// The moment ID. +// identifier property maps to 'id' in JSON (to avoid Objective C's 'id'). +@property (copy) NSString *identifier; + // Identifies this resource as a moment. @property (copy) NSString *kind; // The object generated by performing the action on the item @property (retain) GTLPlusItemScope *result; -// Timestamp of the action (when it occured) in RFC3339 format. +// Time stamp of when the action occurred in RFC3339 format. @property (retain) GTLDateTime *startDate; -// The object on which the action was performed +// The object on which the action was performed. @property (retain) GTLPlusItemScope *target; -// The schema.org activity type +// The schema.org activity type. @property (copy) NSString *type; -// The action the user performed -@property (retain) GTLPlusMomentVerb *verb; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusMomentVerb -// - -@interface GTLPlusMomentVerb : GTLObject - -// Url name of the verb -@property (copy) NSString *url; - @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.m index 6d95a0ac..5d06e924 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.m @@ -24,10 +24,9 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLPlusMoment (0 custom class methods, 6 custom properties) -// GTLPlusMomentVerb (0 custom class methods, 1 custom properties) #import "GTLPlusMoment.h" @@ -39,20 +38,17 @@ // @implementation GTLPlusMoment -@dynamic kind, result, startDate, target, type, verb; +@dynamic identifier, kind, result, startDate, target, type; + ++ (NSDictionary *)propertyToJSONKeyMap { + NSDictionary *map = + [NSDictionary dictionaryWithObject:@"id" + forKey:@"identifier"]; + return map; +} + (void)load { [self registerObjectClassForKind:@"plus#moment"]; } @end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusMomentVerb -// - -@implementation GTLPlusMomentVerb -@dynamic url; -@end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.h deleted file mode 100644 index 95169fa8..00000000 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.h +++ /dev/null @@ -1,285 +0,0 @@ -/* Copyright (c) 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// GTLPlusPerson.h -// - -// ---------------------------------------------------------------------------- -// NOTE: This file is generated from Google APIs Discovery Service. -// Service: -// Google+ API (plus/v1moments) -// Description: -// The Google+ API enables developers to build on top of the Google+ platform. -// Documentation: -// http://developers.google.com/+/api/ -// Classes: -// GTLPlusPerson (0 custom class methods, 21 custom properties) -// GTLPlusPersonEmailsItem (0 custom class methods, 3 custom properties) -// GTLPlusPersonImage (0 custom class methods, 1 custom properties) -// GTLPlusPersonName (0 custom class methods, 6 custom properties) -// GTLPlusPersonOrganizationsItem (0 custom class methods, 9 custom properties) -// GTLPlusPersonPlacesLivedItem (0 custom class methods, 2 custom properties) -// GTLPlusPersonUrlsItem (0 custom class methods, 3 custom properties) - -#if GTL_BUILT_AS_FRAMEWORK - #import "GTL/GTLObject.h" -#else - #import "GTLObject.h" -#endif - -@class GTLPlusPersonEmailsItem; -@class GTLPlusPersonImage; -@class GTLPlusPersonName; -@class GTLPlusPersonOrganizationsItem; -@class GTLPlusPersonPlacesLivedItem; -@class GTLPlusPersonUrlsItem; - -// ---------------------------------------------------------------------------- -// -// GTLPlusPerson -// - -@interface GTLPlusPerson : GTLObject - -// A short biography for this person. -@property (copy) NSString *aboutMe; - -// The person's date of birth, represented as YYYY-MM-DD. -@property (copy) NSString *birthday; - -// The current location for this person. -@property (copy) NSString *currentLocation; - -// The name of this person, suitable for display. -@property (copy) NSString *displayName; - -// A list of email addresses for this person. -@property (retain) NSArray *emails; // of GTLPlusPersonEmailsItem - -// ETag of this response for caching purposes. -@property (copy) NSString *ETag; - -// The person's gender. Possible values are: -// - "male" - Male gender. -// - "female" - Female gender. -// - "other" - Other. -@property (copy) NSString *gender; - -// If "true", indicates that the person has installed the app that is making the -// request and has chosen to expose this install state to the caller. A value of -// "false" indicates that the install state cannot be determined (it is either -// not installed or the person has chosen to keep this information private). -@property (retain) NSNumber *hasApp; // boolValue - -// The ID of this person. -// identifier property maps to 'id' in JSON (to avoid Objective C's 'id'). -@property (copy) NSString *identifier; - -// The representation of the person's profile photo. -@property (retain) GTLPlusPersonImage *image; - -// Identifies this resource as a person. Value: "plus#person". -@property (copy) NSString *kind; - -// The languages spoken by this person. -@property (retain) NSArray *languagesSpoken; // of NSString - -// An object representation of the individual components of a person's name. -@property (retain) GTLPlusPersonName *name; - -// The nickname of this person. -@property (copy) NSString *nickname; - -// Type of person within Google+. Possible values are: -// - "person" - represents an actual person. -// - "page" - represents a page. -@property (copy) NSString *objectType; - -// A list of current or past organizations with which this person is associated. -@property (retain) NSArray *organizations; // of GTLPlusPersonOrganizationsItem - -// A list of places where this person has lived. -@property (retain) NSArray *placesLived; // of GTLPlusPersonPlacesLivedItem - -// The person's relationship status. Possible values are: -// - "single" - Person is single. -// - "in_a_relationship" - Person is in a relationship. -// - "engaged" - Person is engaged. -// - "married" - Person is married. -// - "its_complicated" - The relationship is complicated. -// - "open_relationship" - Person is in an open relationship. -// - "widowed" - Person is widowed. -// - "in_domestic_partnership" - Person is in a domestic partnership. -// - "in_civil_union" - Person is in a civil union. -@property (copy) NSString *relationshipStatus; - -// The brief description (tagline) of this person. -@property (copy) NSString *tagline; - -// The URL of this person's profile. -@property (copy) NSString *url; - -// A list of URLs for this person. -@property (retain) NSArray *urls; // of GTLPlusPersonUrlsItem - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonEmailsItem -// - -@interface GTLPlusPersonEmailsItem : GTLObject - -// If "true", indicates this email address is the person's primary one. -@property (retain) NSNumber *primary; // boolValue - -// The type of address. Possible values are: -// - "home" - Home email address. -// - "work" - Work email address. -// - "other" - Other. -@property (copy) NSString *type; - -// The email address. -@property (copy) NSString *value; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonImage -// - -@interface GTLPlusPersonImage : GTLObject - -// The URL of the person's profile photo. To re-size the image and crop it to a -// square, append the query string ?sz=x, where x is the dimension in pixels of -// each side. -@property (copy) NSString *url; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonName -// - -@interface GTLPlusPersonName : GTLObject - -// The family name (last name) of this person. -@property (copy) NSString *familyName; - -// The full name of this person, including middle names, suffixes, etc. -@property (copy) NSString *formatted; - -// The given name (first name) of this person. -@property (copy) NSString *givenName; - -// The honorific prefixes (such as "Dr." or "Mrs.") for this person. -@property (copy) NSString *honorificPrefix; - -// The honorific suffixes (such as "Jr.") for this person. -@property (copy) NSString *honorificSuffix; - -// The middle name of this person. -@property (copy) NSString *middleName; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonOrganizationsItem -// - -@interface GTLPlusPersonOrganizationsItem : GTLObject - -// The department within the organization. -@property (copy) NSString *department; - -// A short description of the person's role in this organization. -// Remapped to 'descriptionProperty' to avoid NSObject's 'description'. -@property (copy) NSString *descriptionProperty; - -// The date the person left this organization. -@property (copy) NSString *endDate; - -// The location of this organization. -@property (copy) NSString *location; - -// The name of the organization. -@property (copy) NSString *name; - -// If "true", indicates this organization is the person's primary one (typically -// interpreted as current one). -@property (retain) NSNumber *primary; // boolValue - -// The date the person joined this organization. -@property (copy) NSString *startDate; - -// The person's job title or role within the organization. -@property (copy) NSString *title; - -// The type of organization. Possible values are: -// - "work" - Work. -// - "school" - School. -@property (copy) NSString *type; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonPlacesLivedItem -// - -@interface GTLPlusPersonPlacesLivedItem : GTLObject - -// If "true", this place of residence is this person's primary residence. -@property (retain) NSNumber *primary; // boolValue - -// A place where this person has lived. For example: "Seattle, WA", "Near -// Toronto". -@property (copy) NSString *value; - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonUrlsItem -// - -@interface GTLPlusPersonUrlsItem : GTLObject - -// If "true", this URL is the person's primary URL. -@property (retain) NSNumber *primary; // boolValue - -// The type of URL. Possible values are: -// - "home" - URL for home. -// - "work" - URL for work. -// - "blog" - URL for blog. -// - "profile" - URL for profile. -// - "other" - Other. -@property (copy) NSString *type; - -// The URL value. -@property (copy) NSString *value; - -@end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.m deleted file mode 100644 index d56f8824..00000000 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.m +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (c) 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// GTLPlusPerson.m -// - -// ---------------------------------------------------------------------------- -// NOTE: This file is generated from Google APIs Discovery Service. -// Service: -// Google+ API (plus/v1moments) -// Description: -// The Google+ API enables developers to build on top of the Google+ platform. -// Documentation: -// http://developers.google.com/+/api/ -// Classes: -// GTLPlusPerson (0 custom class methods, 21 custom properties) -// GTLPlusPersonEmailsItem (0 custom class methods, 3 custom properties) -// GTLPlusPersonImage (0 custom class methods, 1 custom properties) -// GTLPlusPersonName (0 custom class methods, 6 custom properties) -// GTLPlusPersonOrganizationsItem (0 custom class methods, 9 custom properties) -// GTLPlusPersonPlacesLivedItem (0 custom class methods, 2 custom properties) -// GTLPlusPersonUrlsItem (0 custom class methods, 3 custom properties) - -#import "GTLPlusPerson.h" - -// ---------------------------------------------------------------------------- -// -// GTLPlusPerson -// - -@implementation GTLPlusPerson -@dynamic aboutMe, birthday, currentLocation, displayName, emails, ETag, gender, - hasApp, identifier, image, kind, languagesSpoken, name, nickname, - objectType, organizations, placesLived, relationshipStatus, tagline, - url, urls; - -+ (NSDictionary *)propertyToJSONKeyMap { - NSDictionary *map = - [NSDictionary dictionaryWithObjectsAndKeys: - @"etag", @"ETag", - @"id", @"identifier", - nil]; - return map; -} - -+ (NSDictionary *)arrayPropertyToClassMap { - NSDictionary *map = - [NSDictionary dictionaryWithObjectsAndKeys: - [GTLPlusPersonEmailsItem class], @"emails", - [NSString class], @"languagesSpoken", - [GTLPlusPersonOrganizationsItem class], @"organizations", - [GTLPlusPersonPlacesLivedItem class], @"placesLived", - [GTLPlusPersonUrlsItem class], @"urls", - nil]; - return map; -} - -+ (void)load { - [self registerObjectClassForKind:@"plus#person"]; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonEmailsItem -// - -@implementation GTLPlusPersonEmailsItem -@dynamic primary, type, value; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonImage -// - -@implementation GTLPlusPersonImage -@dynamic url; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonName -// - -@implementation GTLPlusPersonName -@dynamic familyName, formatted, givenName, honorificPrefix, honorificSuffix, - middleName; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonOrganizationsItem -// - -@implementation GTLPlusPersonOrganizationsItem -@dynamic department, descriptionProperty, endDate, location, name, primary, - startDate, title, type; - -+ (NSDictionary *)propertyToJSONKeyMap { - NSDictionary *map = - [NSDictionary dictionaryWithObject:@"description" - forKey:@"descriptionProperty"]; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonPlacesLivedItem -// - -@implementation GTLPlusPersonPlacesLivedItem -@dynamic primary, value; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLPlusPersonUrlsItem -// - -@implementation GTLPlusPersonUrlsItem -@dynamic primary, type, value; -@end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.h index 4d39389d..66ac63d6 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.h @@ -24,9 +24,9 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: -// GTLQueryPlus (2 custom class methods, 4 custom properties) +// GTLQueryPlus (1 custom class methods, 4 custom properties) #if GTL_BUILT_AS_FRAMEWORK #import "GTL/GTLQuery.h" @@ -59,32 +59,18 @@ // Method: plus.moments.insert // Record a user activity (e.g Bill watched a video on Youtube) // Required: -// userId: The ID of the user to get activities for. The special value "me" -// can be used to indicate the authenticated user. +// userId: The ID of the user to record activities for. The only valid values +// are "me" and the ID of the authenticated user. // collection: The collection to which to write moments. // kGTLPlusCollectionVault: The default collection for writing new moments. // Optional: // debug: Return the moment as written. Should be used only for debugging. // Authorization scope(s): +// kGTLAuthScopePlusMe // kGTLAuthScopePlusMomentsWrite // Fetches a GTLPlusMoment. + (id)queryForMomentsInsertWithObject:(GTLPlusMoment *)object userId:(NSString *)userId collection:(NSString *)collection; -#pragma mark - -#pragma mark "people" methods -// These create a GTLQueryPlus object. - -// Method: plus.people.get -// Get a person's profile. -// Required: -// userId: The ID of the person to get the profile for. The special value "me" -// can be used to indicate the authenticated user. -// Authorization scope(s): -// kGTLAuthScopePlusMe -// kGTLAuthScopePlusUserinfoEmail -// Fetches a GTLPlusPerson. -+ (id)queryForPeopleGetWithUserId:(NSString *)userId; - @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.m index 65bff36b..45b98c4f 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.m @@ -24,14 +24,13 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: -// GTLQueryPlus (2 custom class methods, 4 custom properties) +// GTLQueryPlus (1 custom class methods, 4 custom properties) #import "GTLQueryPlus.h" #import "GTLPlusMoment.h" -#import "GTLPlusPerson.h" @implementation GTLQueryPlus @@ -57,16 +56,4 @@ return query; } -#pragma mark - -#pragma mark "people" methods -// These create a GTLQueryPlus object. - -+ (id)queryForPeopleGetWithUserId:(NSString *)userId { - NSString *methodName = @"plus.people.get"; - GTLQueryPlus *query = [self queryWithMethodName:methodName]; - query.userId = userId; - query.expectedObjectClass = [GTLPlusPerson class]; - return query; -} - @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.h index 22a575b8..0ec90133 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.h @@ -24,7 +24,7 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLServicePlus (0 custom class methods, 0 custom properties) diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.m index ee66db50..e131d257 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.m @@ -24,7 +24,7 @@ // Description: // The Google+ API enables developers to build on top of the Google+ platform. // Documentation: -// http://developers.google.com/+/api/ +// https://developers.google.com/+/history/ // Classes: // GTLServicePlus (0 custom class methods, 0 custom properties) @@ -40,7 +40,6 @@ [GTLQueryPlus class], [GTLPlusItemScope class], [GTLPlusMoment class], - [GTLPlusPerson class], nil]; return classes; } diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.h index 0afe823e..7b9f8139 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.h @@ -17,6 +17,9 @@ // GTLQuery.h // +// Query documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Query_Operations + #import "GTLObject.h" #import "GTLUploadParameters.h" diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.m index 6b2880be..5f6613d0 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.m @@ -108,6 +108,12 @@ static NSString *const kJSONKey = @"jsonKey"; canBeCached = NO; } else if ([obj isKindOfClass:[GTLObject class]]) { result = [obj JSON]; + if (result == nil) { + // adding an empty object; it should have a JSON dictionary so it can + // hold future assignments + [obj setJSON:[NSMutableDictionary dictionary]]; + result = [obj JSON]; + } } else if ([obj isKindOfClass:[NSArray class]]) { checkExpected = NO; NSArray *array = obj; diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.h index f7929e2f..c2b8b991 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.h @@ -17,6 +17,9 @@ // GTLService.h // +// Service object documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Services_and_Tickets + #import #import "GTLDefines.h" @@ -123,8 +126,8 @@ typedef void *GTLServiceUploadProgressBlock; NSUInteger uploadChunkSize_; // zero when uploading via multi-part MIME http body - BOOL isRetryEnabled_; // user allows auto-retries - SEL retrySelector_; // optional; set with setServiceRetrySelector + BOOL isRetryEnabled_; // user allows auto-retries + SEL retrySelector_; // optional; set with setServiceRetrySelector NSTimeInterval maxRetryInterval_; // default to 600. seconds BOOL shouldFetchNextPages_; @@ -152,7 +155,8 @@ typedef void *GTLServiceUploadProgressBlock; // be nil.) // // If the query object is a GTLBatchQuery, the object passed to the callback -// will be a GTLBatchResult +// will be a GTLBatchResult; see the batch query documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Batch_Operations - (GTLServiceTicket *)executeQuery:(id)query delegate:(id)delegate @@ -350,6 +354,17 @@ typedef void *GTLServiceUploadProgressBlock; // is ignored. @property (nonatomic, assign) BOOL shouldFetchInBackground; +// Callbacks can be invoked on an operation queue rather than via the run loop +// starting on 10.7 and iOS 6. Do not specify both run loop modes and an +// operation queue. Specifying a delegate queue typically looks like this: +// +// service.delegateQueue = [[[NSOperationQueue alloc] init] autorelease]; +// +// Since the callbacks will be on a thread of the operation queue, the client +// may re-dispatch from the callbacks to a known dispatch queue or to the +// main queue. +@property (nonatomic, retain) NSOperationQueue *delegateQueue; + // Run loop modes are used for scheduling NSURLConnections. // // The default value, nil, schedules connections using the current run diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.m index 2e405324..78dbd27e 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLService.m @@ -1159,20 +1159,29 @@ totalBytesExpectedToSend:(NSInteger)totalBytesExpected { SEL parseDoneSel = @selector(handleParsedObjectForFetcher:); NSArray *runLoopModes = [properties valueForKey:kFetcherCallbackRunLoopModesKey]; - if (runLoopModes) { + // If this callback was enqueued, then the fetcher has already released + // its delegateQueue. We'll use our own delegateQueue to determine how to + // invoke the callbacks. + NSOperationQueue *delegateQueue = self.delegateQueue; + if (delegateQueue) { + NSInvocationOperation *op; + op = [[[NSInvocationOperation alloc] initWithTarget:self + selector:parseDoneSel + object:fetcher] autorelease]; + [delegateQueue addOperation:op]; + } else if (runLoopModes) { [self performSelector:parseDoneSel onThread:callbackThread withObject:fetcher waitUntilDone:NO modes:runLoopModes]; } else { - // defaults to common modes + // Defaults to common modes [self performSelector:parseDoneSel onThread:callbackThread withObject:fetcher waitUntilDone:NO]; } - // the fetcher now belongs to the callback thread } @@ -2031,6 +2040,14 @@ totalBytesExpectedToSend:(NSInteger)totalBytesExpected { return self.fetcherService.shouldFetchInBackground; } +- (void)setDelegateQueue:(NSOperationQueue *)delegateQueue { + self.fetcherService.delegateQueue = delegateQueue; +} + +- (NSOperationQueue *)delegateQueue { + return self.fetcherService.delegateQueue; +} + - (void)setRunLoopModes:(NSArray *)array { self.fetcherService.runLoopModes = array; } diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.h index 6b6c20ba..9abd2758 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.h @@ -17,6 +17,9 @@ // GTLUploadParameters.h // +// Uploading documentation: +// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Uploading_Files + #import #import "GTLDefines.h" diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.h b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.h index 1694df61..97f4bf07 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.h +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.h @@ -90,16 +90,4 @@ NSNumber *GTL_EnsureNSNumber(NSNumber *num); startClass:(Class)startClass ancestorClass:(Class)ancestorClass cache:(NSMutableDictionary *)cache; - -// -// MIME Types -// - -// Utility routine to convert a file path to the file's MIME type using -// Mac OS X's UTI database -#if !GTL_FOUNDATION_ONLY -+ (NSString *)MIMETypeForFileAtPath:(NSString *)path - defaultMIMEType:(NSString *)defaultType; -#endif - @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.m b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.m index 71b7ee8a..56062a95 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.m +++ b/External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.m @@ -300,41 +300,6 @@ const CFStringRef kCharsToForceEscape = CFSTR("!*'();:@&=+$,/?%#[]"); return result; } -#pragma mark MIME Types - -// Utility routine to convert a file path to the file's MIME type using -// Mac OS X's UTI database -#if !GTL_FOUNDATION_ONLY -+ (NSString *)MIMETypeForFileAtPath:(NSString *)path - defaultMIMEType:(NSString *)defaultType { - NSString *result = defaultType; - - // Convert the path to an FSRef - FSRef fileFSRef; - Boolean isDirectory; - OSStatus err = FSPathMakeRef((UInt8 *) [path fileSystemRepresentation], - &fileFSRef, &isDirectory); - if (err == noErr) { - // Get the UTI (content type) for the FSRef - CFStringRef fileUTI; - err = LSCopyItemAttribute(&fileFSRef, kLSRolesAll, kLSItemContentType, - (CFTypeRef *)&fileUTI); - if (err == noErr) { - // Get the MIME type for the UTI - CFStringRef mimeTypeTag; - mimeTypeTag = UTTypeCopyPreferredTagWithClass(fileUTI, - kUTTagClassMIMEType); - if (mimeTypeTag) { - // Convert the CFStringRef to an autoreleased NSString - result = [(id)CFMakeCollectable(mimeTypeTag) autorelease]; - } - CFRelease(fileUTI); - } - } - return result; -} -#endif - @end // isEqual: has the fatal flaw that it doesn't deal well with the receiver diff --git a/External/google-plus-ios-sdk/OpenSource/GTMDefines.h b/External/google-plus-ios-sdk/OpenSource/GTMDefines.h index 59a1723c..b970d69c 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMDefines.h +++ b/External/google-plus-ios-sdk/OpenSource/GTMDefines.h @@ -21,9 +21,13 @@ #include #include +#ifdef __OBJC__ +#include +#endif // __OBJC__ + #if TARGET_OS_IPHONE #include -#endif // TARGET_OS_IPHONE +#endif // TARGET_OS_IPHONE // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs #ifndef MAC_OS_X_VERSION_10_5 @@ -356,6 +360,7 @@ #if __has_feature(objc_arc) #define GTMInvalidateInitializer() \ do { \ + [self class]; /* Avoid warning of dead store to |self|. */ \ _GTMDevAssert(NO, @"Invalid initializer."); \ return nil; \ } while (0) @@ -436,4 +441,4 @@ GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, #endif // DEBUG #endif // GTM_SEL_STRING -#endif // __OBJC__ +#endif // __OBJC__ diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.m b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.m index 7bf0684a..0bbd81d2 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.m @@ -40,10 +40,10 @@ static NSString* const kGTMETagHeader = @"Etag"; [super dealloc]; } -// add all cookies in the new cookie array to the storage, -// replacing stored cookies as appropriate +// Add all cookies in the new cookie array to the storage, +// replacing stored cookies as appropriate. // -// Side effect: removes expired cookies from the storage array +// Side effect: removes expired cookies from the storage array. - (void)setCookies:(NSArray *)newCookies { @synchronized(cookies_) { @@ -82,9 +82,9 @@ static NSString* const kGTMETagHeader = @"Etag"; } } -// retrieve all cookies appropriate for the given URL, considering +// Retrieve all cookies appropriate for the given URL, considering // domain, path, cookie name, expiration, security setting. -// Side effect: removed expired cookies from the storage array +// Side effect: removed expired cookies from the storage array. - (NSArray *)cookiesForURL:(NSURL *)theURL { NSMutableArray *foundCookies = nil; @@ -92,9 +92,9 @@ static NSString* const kGTMETagHeader = @"Etag"; @synchronized(cookies_) { [self removeExpiredCookies]; - // we'll prepend "." to the desired domain, since we want the + // We'll prepend "." to the desired domain, since we want the // actual domain "nytimes.com" to still match the cookie domain - // ".nytimes.com" when we check it below with hasSuffix + // ".nytimes.com" when we check it below with hasSuffix. NSString *host = [[theURL host] lowercaseString]; NSString *path = [theURL path]; NSString *scheme = [theURL scheme]; @@ -144,13 +144,13 @@ static NSString* const kGTMETagHeader = @"Etag"; return foundCookies; } -// return a cookie from the array with the same name, domain, and path as the -// given cookie, or else return nil if none found +// Return a cookie from the array with the same name, domain, and path as the +// given cookie, or else return nil if none found. // // Both the cookie being tested and all cookies in the storage array should -// be valid (non-nil name, domains, paths) +// be valid (non-nil name, domains, paths). // -// note: this should only be called from inside a @synchronized(cookies_) block +// Note: this should only be called from inside a @synchronized(cookies_) block - (NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie { NSUInteger numberOfCookies = [cookies_ count]; @@ -176,10 +176,10 @@ static NSString* const kGTMETagHeader = @"Etag"; } -// internal routine to remove any expired cookies from the array, excluding -// cookies with nil expirations +// Internal routine to remove any expired cookies from the array, excluding +// cookies with nil expirations. // -// note: this should only be called from inside a @synchronized(cookies_) block +// Note: this should only be called from inside a @synchronized(cookies_) block - (void)removeExpiredCookies { // count backwards since we're deleting items from the array @@ -281,18 +281,18 @@ static NSString* const kGTMETagHeader = @"Etag"; [self class], self, [responses_ allValues]]; } -// setters/getters +// Setters/getters - (void)pruneCacheResponses { - // internal routine to remove the least-recently-used responses when the + // Internal routine to remove the least-recently-used responses when the // cache has grown too large if (memoryCapacity_ >= totalDataSize_) return; - // sort keys by date + // Sort keys by date SEL sel = @selector(compareUseDate:); NSArray *sortedKeys = [responses_ keysSortedByValueUsingSelector:sel]; - // the least-recently-used keys are at the beginning of the sorted array; + // The least-recently-used keys are at the beginning of the sorted array; // remove those (except ones still reserved) until the total data size is // reduced sufficiently for (NSURL *key in sortedKeys) { @@ -303,13 +303,13 @@ static NSString* const kGTMETagHeader = @"Etag"; && ([resDate timeIntervalSinceNow] > -reservationInterval_); if (!isResponseReserved) { - // we can remove this response from the cache + // We can remove this response from the cache NSUInteger storedSize = [[response data] length]; totalDataSize_ -= storedSize; [responses_ removeObjectForKey:key]; } - // if we've removed enough response data, then we're done + // If we've removed enough response data, then we're done if (memoryCapacity_ >= totalDataSize_) break; } } @@ -317,7 +317,7 @@ static NSString* const kGTMETagHeader = @"Etag"; - (void)storeCachedResponse:(GTMCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request { @synchronized(self) { - // remove any previous entry for this request + // Remove any previous entry for this request [self removeCachedResponseForRequest:request]; // cache this one only if it's not bigger than our cache @@ -340,7 +340,7 @@ static NSString* const kGTMETagHeader = @"Etag"; NSURL *key = [request URL]; response = [[[responses_ objectForKey:key] retain] autorelease]; - // touch the date to indicate this was recently retrieved + // Touch the date to indicate this was recently retrieved [response setUseDate:[NSDate date]]; } return response; @@ -376,7 +376,7 @@ static NSString* const kGTMETagHeader = @"Etag"; } } -// methods for unit testing +// Methods for unit testing. - (void)setReservationInterval:(NSTimeInterval)secs { reservationInterval_ = secs; } @@ -432,32 +432,34 @@ static NSString* const kGTMETagHeader = @"Etag"; } - (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet { - if ([self shouldRememberETags]) { - // If this URL is in the history, and no ETag has been set, then - // set the ETag header field + @synchronized(self) { + if ([self shouldRememberETags]) { + // If this URL is in the history, and no ETag has been set, then + // set the ETag header field - // if we have a history, we're tracking across fetches, so we don't - // want to pull results from any other cache - [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; + // If we have a history, we're tracking across fetches, so we don't + // want to pull results from any other cache + [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; - if (isHTTPGet) { - // we'll only add an ETag if there's no ETag specified in the user's - // request - NSString *specifiedETag = [request valueForHTTPHeaderField:kGTMIfNoneMatchHeader]; - if (specifiedETag == nil) { - // no ETag: extract the previous ETag for this request from the - // fetch history, and add it to the request - NSString *cachedETag = [self cachedETagForRequest:request]; + if (isHTTPGet) { + // We'll only add an ETag if there's no ETag specified in the user's + // request + NSString *specifiedETag = [request valueForHTTPHeaderField:kGTMIfNoneMatchHeader]; + if (specifiedETag == nil) { + // No ETag: extract the previous ETag for this request from the + // fetch history, and add it to the request + NSString *cachedETag = [self cachedETagForRequest:request]; - if (cachedETag != nil) { - [request addValue:cachedETag forHTTPHeaderField:kGTMIfNoneMatchHeader]; + if (cachedETag != nil) { + [request addValue:cachedETag forHTTPHeaderField:kGTMIfNoneMatchHeader]; + } + } else { + // Has an ETag: remove any stored response in the fetch history + // for this request, as the If-None-Match header could lead to + // a 304 Not Modified, and we want that error delivered to the + // user since they explicitly specified the ETag + [self removeCachedDataForRequest:request]; } - } else { - // has an ETag: remove any stored response in the fetch history - // for this request, as the If-None-Match header could lead to - // a 304 Not Modified, and we want that error delivered to the - // user since they explicitly specified the ETag - [self removeCachedDataForRequest:request]; } } } @@ -466,38 +468,41 @@ static NSString* const kGTMETagHeader = @"Etag"; - (void)updateFetchHistoryWithRequest:(NSURLRequest *)request response:(NSURLResponse *)response downloadedData:(NSData *)downloadedData { - if (![self shouldRememberETags]) return; + @synchronized(self) { + if (![self shouldRememberETags]) return; - if (![response respondsToSelector:@selector(allHeaderFields)]) return; + if (![response respondsToSelector:@selector(allHeaderFields)]) return; - NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; + NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; - if (statusCode != kGTMHTTPFetcherStatusNotModified) { - // save this ETag string for successful results (<300) - // If there's no last modified string, clear the dictionary - // entry for this URL. Also cache or delete the data, if appropriate - // (when etaggedDataCache is non-nil.) - NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields]; - NSString* etag = [headers objectForKey:kGTMETagHeader]; + if (statusCode != kGTMHTTPFetcherStatusNotModified) { + // Save this ETag string for successful results (<300) + // If there's no last modified string, clear the dictionary + // entry for this URL. Also cache or delete the data, if appropriate + // (when etaggedDataCache is non-nil.) + NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields]; + NSString* etag = [headers objectForKey:kGTMETagHeader]; - if (etag != nil && statusCode < 300) { + if (etag != nil && statusCode < 300) { - // we want to cache responses for the headers, even if the client - // doesn't want the response body data caches - NSData *dataToStore = shouldCacheETaggedData_ ? downloadedData : nil; + // we want to cache responses for the headers, even if the client + // doesn't want the response body data caches + NSData *dataToStore = shouldCacheETaggedData_ ? downloadedData : nil; - GTMCachedURLResponse *cachedResponse; - cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response - data:dataToStore] autorelease]; - [etaggedDataCache_ storeCachedResponse:cachedResponse - forRequest:request]; - } else { - [etaggedDataCache_ removeCachedResponseForRequest:request]; + GTMCachedURLResponse *cachedResponse; + cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response + data:dataToStore] autorelease]; + [etaggedDataCache_ storeCachedResponse:cachedResponse + forRequest:request]; + } else { + [etaggedDataCache_ removeCachedResponseForRequest:request]; + } } } } - (NSString *)cachedETagForRequest:(NSURLRequest *)request { + // Internal routine. GTMCachedURLResponse *cachedResponse; cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request]; @@ -505,46 +510,56 @@ static NSString* const kGTMETagHeader = @"Etag"; NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields]; NSString *cachedETag = [headers objectForKey:kGTMETagHeader]; if (cachedETag) { - // since the request having an ETag implies this request is about + // Since the request having an ETag implies this request is about // to be fetched again, reserve the cached response to ensure that - // that it will be around at least until the fetch completes + // that it will be around at least until the fetch completes. // - // when the fetch completes, either the cached response will be replaced + // When the fetch completes, either the cached response will be replaced // with a new response, or the cachedDataForRequest: method below will - // clear the reservation + // clear the reservation. [cachedResponse setReservationDate:[NSDate date]]; } return cachedETag; } - (NSData *)cachedDataForRequest:(NSURLRequest *)request { - GTMCachedURLResponse *cachedResponse; - cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request]; + @synchronized(self) { + GTMCachedURLResponse *cachedResponse; + cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request]; - NSData *cachedData = [cachedResponse data]; + NSData *cachedData = [cachedResponse data]; - // since the data for this cached request is being obtained from the cache, - // we can clear the reservation as the fetch has completed - [cachedResponse setReservationDate:nil]; + // Since the data for this cached request is being obtained from the cache, + // we can clear the reservation as the fetch has completed. + [cachedResponse setReservationDate:nil]; - return cachedData; + return cachedData; + } } - (void)removeCachedDataForRequest:(NSURLRequest *)request { - [etaggedDataCache_ removeCachedResponseForRequest:request]; + @synchronized(self) { + [etaggedDataCache_ removeCachedResponseForRequest:request]; + } } - (void)clearETaggedDataCache { - [etaggedDataCache_ removeAllCachedResponses]; + @synchronized(self) { + [etaggedDataCache_ removeAllCachedResponses]; + } } - (void)clearHistory { - [self clearETaggedDataCache]; - [cookieStorage_ removeAllCookies]; + @synchronized(self) { + [self clearETaggedDataCache]; + [cookieStorage_ removeAllCookies]; + } } - (void)removeAllCookies { - [cookieStorage_ removeAllCookies]; + @synchronized(self) { + [cookieStorage_ removeAllCookies]; + } } - (BOOL)shouldRememberETags { @@ -556,7 +571,7 @@ static NSString* const kGTMETagHeader = @"Etag"; shouldRememberETags_ = flag; if (wasRemembering && !flag) { - // free up the cache memory + // Free up the cache memory [self clearETaggedDataCache]; } } diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.h b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.h index dedc4c01..3f58f3d6 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.h +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.h @@ -77,6 +77,33 @@ // Status codes are at // // +// Threading and queue support: +// +// Callbacks require either that the thread used to start the fetcher have a run +// loop spinning (typically the main thread), or that an NSOperationQueue be +// provided upon which the delegate callbacks will be called. Starting with +// iOS 6 and Mac OS X 10.7, clients may simply create an operation queue for +// callbacks on a background thread: +// +// fetcher.delegateQueue = [[[NSOperationQueue alloc] init] autorelease]; +// +// or specify the main queue for callbacks on the main thread: +// +// fetcher.delegateQueue = [NSOperationQueue mainQueue]; +// +// The client may also re-dispatch from the callbacks and notifications to +// a known dispatch queue: +// +// [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { +// if (error == nil) { +// dispatch_async(myDispatchQueue, ^{ +// ... +// }); +// } +// }]; +// +// +// // Downloading to disk: // // To have downloaded data saved directly to disk, specify either a path for the @@ -343,6 +370,9 @@ NSString *GTMApplicationIdentifier(NSBundle *bundle); @protocol GTMHTTPFetcherServiceProtocol // This protocol allows us to call into the service without requiring // GTMHTTPFetcherService sources in this project + +@property (retain) NSOperationQueue *delegateQueue; + - (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher; - (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher; @@ -416,7 +446,8 @@ NSString *GTMApplicationIdentifier(NSBundle *bundle); #endif id userData_; // retained, if set by caller NSMutableDictionary *properties_; // more data retained for caller - NSArray *runLoopModes_; // optional, for 10.5 and later + NSArray *runLoopModes_; // optional + NSOperationQueue *delegateQueue_; // optional; available iOS 6/10.7 and later id fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies NSInteger cookieStorageMethod_; // constant from above id cookieStorage_; @@ -502,7 +533,8 @@ NSString *GTMApplicationIdentifier(NSBundle *bundle); // fetchers that are being delayed by a fetcher service. @property (assign) NSInteger servicePriority; -// The thread used to run this fetcher in the fetcher service +// The thread used to run this fetcher in the fetcher service when no operation +// queue is provided. @property (retain) NSThread *thread; // The delegate is retained during the connection @@ -677,6 +709,11 @@ NSString *GTMApplicationIdentifier(NSBundle *bundle); // Log of request and response, if logging is enabled @property (copy) NSString *log; +// Callbacks can be invoked on an operation queue rather than via the run loop, +// starting on 10.7 and iOS 6. If a delegate queue is supplied. the run loop +// modes are ignored. +@property (retain) NSOperationQueue *delegateQueue; + // Using the fetcher while a modal dialog is displayed requires setting the // run-loop modes to include NSModalPanelRunLoopMode @property (retain) NSArray *runLoopModes; diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.m b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.m index 3a448c6c..75fe3bf8 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.m @@ -28,11 +28,15 @@ static id gGTMFetcherStaticCookieStorage = nil; static Class gGTMFetcherConnectionClass = nil; -// the default max retry interview is 10 minutes for uploads (POST/PUT/PATCH), -// 1 minute for downloads -const NSTimeInterval kUnsetMaxRetryInterval = -1; -const NSTimeInterval kDefaultMaxDownloadRetryInterval = 60.0; -const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; +// The default max retry interview is 10 minutes for uploads (POST/PUT/PATCH), +// 1 minute for downloads. +static const NSTimeInterval kUnsetMaxRetryInterval = -1; +static const NSTimeInterval kDefaultMaxDownloadRetryInterval = 60.0; +static const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; + +// delegateQueue callback parameters +static NSString *const kCallbackData = @"data"; +static NSString *const kCallbackError = @"error"; // // GTMHTTPFetcher @@ -62,7 +66,6 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; finishedWithError:(NSError *)error; - (NSString *)createTempDownloadFilePathForPath:(NSString *)targetPath; -- (NSFileManager *)fileManager; - (void)stopFetchReleasingCallbacks:(BOOL)shouldReleaseCallbacks; - (BOOL)shouldReleaseCallbacksUponCompletion; @@ -77,6 +80,8 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; target:(id)target data:(NSData *)data error:(NSError *)error; +- (void)invokeFetchCallbacksOnDelegateQueueWithData:(NSData *)data + error:(NSError *)error; - (void)releaseCallbacks; - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; @@ -110,7 +115,7 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; } + (void)initialize { - // note that initialize is guaranteed by the runtime to be called in a + // initialize is guaranteed by the runtime to be called in a // thread-safe manner if (!gGTMFetcherStaticCookieStorage) { Class cookieStorageClass = NSClassFromString(@"GTMCookieStorage"); @@ -130,12 +135,12 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; request_ = [request mutableCopy]; if (gGTMFetcherStaticCookieStorage != nil) { - // the user has compiled with the cookie storage class available; + // The user has compiled with the cookie storage class available; // default to static cookie storage, so our cookies are independent - // of the cookies of other apps + // of the cookies of other apps. [self setCookieStorageMethod:kGTMHTTPFetcherCookieStorageMethodStatic]; } else { - // default to system default cookie storage + // Default to system default cookie storage [self setCookieStorageMethod:kGTMHTTPFetcherCookieStorageMethodSystemDefault]; } } @@ -189,6 +194,7 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; #endif [userData_ release]; [properties_ release]; + [delegateQueue_ release]; [runLoopModes_ release]; [fetchHistory_ release]; [cookieStorage_ release]; @@ -321,28 +327,40 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; Class connectionClass = [[self class] connectionClass]; - NSArray *runLoopModes = nil; - - // use the connection-specific run loop modes, if they were provided, - // or else use the GTMHTTPFetcher default run loop modes, if any - if (runLoopModes_) { - runLoopModes = runLoopModes_; + NSOperationQueue *delegateQueue = delegateQueue_; + if (delegateQueue && + ![connectionClass instancesRespondToSelector:@selector(setDelegateQueue:)]) { + // NSURLConnection has no setDelegateQueue: on iOS 4 and Mac OS X 10.5. + delegateQueue = nil; + self.delegateQueue = nil; } - if ([runLoopModes count] == 0) { +#if DEBUG && TARGET_OS_IPHONE + BOOL isPreIOS6 = (NSFoundationVersionNumber <= 890.1); + if (isPreIOS6 && delegateQueue) { + NSLog(@"GTMHTTPFetcher delegateQueue not safe in iOS 5"); + } +#endif - // if no run loop modes were specified, then we'll start the connection + if ([runLoopModes_ count] == 0 && delegateQueue == nil) { + // No custom callback modes or queue were specified, so start the connection // on the current run loop in the current mode - connection_ = [[connectionClass connectionWithRequest:request_ + connection_ = [[connectionClass connectionWithRequest:request_ delegate:self] retain]; } else { - - // schedule on current run loop in the specified modes + // Specify callbacks be on an operation queue or on the current run loop + // in the specified modes connection_ = [[connectionClass alloc] initWithRequest:request_ delegate:self startImmediately:NO]; - for (NSString *mode in runLoopModes) { - [connection_ scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; + if (delegateQueue) { + [connection_ performSelector:@selector(setDelegateQueue:) + withObject:delegateQueue]; + } else if (runLoopModes_) { + NSRunLoop *rl = [NSRunLoop currentRunLoop]; + for (NSString *mode in runLoopModes_) { + [connection_ scheduleInRunLoop:rl forMode:mode]; + } } [connection_ start]; } @@ -366,12 +384,12 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; UIApplication *app = [UIApplication sharedApplication]; if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) { // Tell UIApplication that we want to continue even when the app is in the - // background + // background. NSThread *thread = [NSThread currentThread]; backgroundTaskIdentifer_ = [app beginBackgroundTaskWithExpirationHandler:^{ // Callback - this block is always invoked by UIApplication on the main // thread, but we want to run the user's callbacks on the thread used - // to start the fetch + // to start the fetch. [self performSelector:@selector(backgroundFetchExpired) onThread:thread withObject:nil @@ -381,7 +399,7 @@ const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; } #endif - // once connection_ is non-nil we can send the start notification + // Once connection_ is non-nil we can send the start notification isStopNotificationNeeded_ = YES; NSNotificationCenter *defaultNC = [NSNotificationCenter defaultCenter]; [defaultNC postNotificationName:kGTMHTTPFetcherStartedNotification @@ -402,8 +420,8 @@ CannotBeginFetch: [[self retain] autorelease]; // In case the callback releases us - [self invokeFetchCallbacksWithData:nil - error:error]; + [self invokeFetchCallbacksOnDelegateQueueWithData:nil + error:error]; [self releaseCallbacks]; @@ -412,26 +430,28 @@ CannotBeginFetch: self.authorizer = nil; if (temporaryDownloadPath_) { - [[self fileManager] removeItemAtPath:temporaryDownloadPath_ - error:NULL]; + [[NSFileManager defaultManager] removeItemAtPath:temporaryDownloadPath_ + error:NULL]; self.temporaryDownloadPath = nil; } } #if GTM_BACKGROUND_FETCHING - (void)backgroundFetchExpired { - // On background expiration, we stop the fetch and invoke the callbacks - NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherErrorDomain - code:kGTMHTTPFetcherErrorBackgroundExpiration - userInfo:nil]; - [self invokeFetchCallbacksWithData:nil - error:error]; + @synchronized(self) { + // On background expiration, we stop the fetch and invoke the callbacks + NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherErrorDomain + code:kGTMHTTPFetcherErrorBackgroundExpiration + userInfo:nil]; + [self invokeFetchCallbacksOnDelegateQueueWithData:nil + error:error]; - // Stopping the fetch here will indirectly call endBackgroundTask - [self stopFetchReleasingCallbacks:NO]; + // Stopping the fetch here will indirectly call endBackgroundTask + [self stopFetchReleasingCallbacks:NO]; - [self releaseCallbacks]; - self.authorizer = nil; + [self releaseCallbacks]; + self.authorizer = nil; + } } - (void)endBackgroundTask { @@ -445,7 +465,7 @@ CannotBeginFetch: backgroundTaskIdentifer_ = 0; } } -#endif +#endif // GTM_BACKGROUND_FETCHING - (BOOL)authorizeRequest { id authorizer = self.authorizer; @@ -459,7 +479,7 @@ CannotBeginFetch: } else { NSAssert(authorizer == nil, @"invalid authorizer for fetch"); - // no authorizing possible, and authorizing happens only after any delay; + // No authorizing possible, and authorizing happens only after any delay; // just begin fetching return [self beginFetchMayDelay:NO mayAuthorize:NO]; @@ -470,7 +490,7 @@ CannotBeginFetch: request:(NSMutableURLRequest *)request finishedWithError:(NSError *)error { if (error != nil) { - // we can't fetch without authorization + // We can't fetch without authorization [self failToBeginFetchWithError:error]; } else { [self beginFetchMayDelay:NO @@ -482,9 +502,9 @@ CannotBeginFetch: - (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler { self.completionBlock = handler; - // the user may have called setDelegate: earlier if they want to use other + // The user may have called setDelegate: earlier if they want to use other // delegate-style callbacks during the fetch; otherwise, the delegate is nil, - // which is fine + // which is fine. return [self beginFetchWithDelegate:[self delegate] didFinishSelector:nil]; } @@ -494,11 +514,11 @@ CannotBeginFetch: NSString *tempDir = nil; #if (!TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)) - // find an appropriate directory for the download, ideally on the same disk + // Find an appropriate directory for the download, ideally on the same disk // as the final target location so the temporary file won't have to be moved - // to a different disk + // to a different disk. // - // available in SDKs for 10.6 and iOS 4 + // Available in SDKs for 10.6 and iOS 4 // // Oct 2011: We previously also used URLForDirectory for // (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000)) @@ -508,7 +528,7 @@ CannotBeginFetch: if ([NSFileManager instancesRespondToSelector:sel]) { NSError *error = nil; NSURL *targetURL = [NSURL fileURLWithPath:targetPath]; - NSFileManager *fileMgr = [self fileManager]; + NSFileManager *fileMgr = [NSFileManager defaultManager]; NSURL *tempDirURL = [fileMgr URLForDirectory:NSItemReplacementDirectory inDomain:NSUserDomainMask @@ -531,7 +551,7 @@ CannotBeginFetch: } - (void)addCookiesToRequest:(NSMutableURLRequest *)request { - // get cookies for this URL from our storage array, if + // Get cookies for this URL from our storage array, if // we have a storage array if (cookieStorageMethod_ != kGTMHTTPFetcherCookieStorageMethodSystemDefault && cookieStorageMethod_ != kGTMHTTPFetcherCookieStorageMethodNone) { @@ -592,6 +612,9 @@ CannotBeginFetch: [delegate_ autorelease]; delegate_ = nil; + [delegateQueue_ autorelease]; + delegateQueue_ = nil; + #if NS_BLOCKS_AVAILABLE self.completionBlock = nil; self.sentDataBlock = nil; @@ -648,9 +671,11 @@ CannotBeginFetch: #endif } -// external stop method +// External stop method - (void)stopFetching { - [self stopFetchReleasingCallbacks:YES]; + @synchronized(self) { + [self stopFetchReleasingCallbacks:YES]; + } } - (void)sendStopNotificationIfNeeded { @@ -664,7 +689,6 @@ CannotBeginFetch: } - (void)retryFetch { - [self stopFetchReleasingCallbacks:NO]; [self beginFetchWithDelegate:delegate_ @@ -674,8 +698,10 @@ CannotBeginFetch: - (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds { NSDate* giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; - // loop until the callbacks have been called and released, and until + // Loop until the callbacks have been called and released, and until // the connection is no longer pending, or until the timeout has expired + BOOL isMainThread = [NSThread isMainThread]; + while ((!hasConnectionEnded_ #if NS_BLOCKS_AVAILABLE || completionBlock_ != nil @@ -683,18 +709,17 @@ CannotBeginFetch: || delegate_ != nil) && [giveUpDate timeIntervalSinceNow] > 0) { - // run the current run loop 1/1000 of a second to give the networking + // Run the current run loop 1/1000 of a second to give the networking // code a chance to work - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; + if (isMainThread || delegateQueue_ == nil) { + NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; + [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; + } else { + [NSThread sleepForTimeInterval:0.001]; + } } } -- (NSFileManager *)fileManager { - // use a temporary instance of NSFileManager for thread-safety - return [[[NSFileManager alloc] init] autorelease]; -} - #pragma mark NSURLConnection Delegate Methods // @@ -716,70 +741,73 @@ CannotBeginFetch: - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)redirectRequest redirectResponse:(NSURLResponse *)redirectResponse { + @synchronized(self) { + if (redirectRequest && redirectResponse) { + // save cookies from the response + [self handleCookiesForResponse:redirectResponse]; - if (redirectRequest && redirectResponse) { - // save cookies from the response - [self handleCookiesForResponse:redirectResponse]; + NSMutableURLRequest *newRequest = [[request_ mutableCopy] autorelease]; + // copy the URL + NSURL *redirectURL = [redirectRequest URL]; + NSURL *url = [newRequest URL]; - NSMutableURLRequest *newRequest = [[request_ mutableCopy] autorelease]; - // copy the URL - NSURL *redirectURL = [redirectRequest URL]; - NSURL *url = [newRequest URL]; + // disallow scheme changes (say, from https to http) + NSString *redirectScheme = [url scheme]; + NSString *newScheme = [redirectURL scheme]; + NSString *newResourceSpecifier = [redirectURL resourceSpecifier]; - // disallow scheme changes (say, from https to http) - NSString *redirectScheme = [url scheme]; - NSString *newScheme = [redirectURL scheme]; - NSString *newResourceSpecifier = [redirectURL resourceSpecifier]; + if ([redirectScheme caseInsensitiveCompare:@"http"] == NSOrderedSame + && newScheme != nil + && [newScheme caseInsensitiveCompare:@"https"] == NSOrderedSame) { - if ([redirectScheme caseInsensitiveCompare:@"http"] == NSOrderedSame - && newScheme != nil - && [newScheme caseInsensitiveCompare:@"https"] == NSOrderedSame) { + // allow the change from http to https + redirectScheme = newScheme; + } - // allow the change from http to https - redirectScheme = newScheme; + NSString *newUrlString = [NSString stringWithFormat:@"%@:%@", + redirectScheme, newResourceSpecifier]; + + NSURL *newURL = [NSURL URLWithString:newUrlString]; + [newRequest setURL:newURL]; + + // any headers in the redirect override headers in the original. + NSDictionary *redirectHeaders = [redirectRequest allHTTPHeaderFields]; + for (NSString *key in redirectHeaders) { + NSString *value = [redirectHeaders objectForKey:key]; + [newRequest setValue:value forHTTPHeaderField:key]; + } + + [self addCookiesToRequest:newRequest]; + + redirectRequest = newRequest; + + // log the response we just received + [self setResponse:redirectResponse]; + [self logNowWithError:nil]; + + // update the request for future logging + NSMutableURLRequest *mutable = [[redirectRequest mutableCopy] autorelease]; + [self setMutableRequest:mutable]; } - - NSString *newUrlString = [NSString stringWithFormat:@"%@:%@", - redirectScheme, newResourceSpecifier]; - - NSURL *newURL = [NSURL URLWithString:newUrlString]; - [newRequest setURL:newURL]; - - // any headers in the redirect override headers in the original. - NSDictionary *redirectHeaders = [redirectRequest allHTTPHeaderFields]; - for (NSString *key in redirectHeaders) { - NSString *value = [redirectHeaders objectForKey:key]; - [newRequest setValue:value forHTTPHeaderField:key]; - } - - [self addCookiesToRequest:newRequest]; - - redirectRequest = newRequest; - - // log the response we just received - [self setResponse:redirectResponse]; - [self logNowWithError:nil]; - - // update the request for future logging - NSMutableURLRequest *mutable = [[redirectRequest mutableCopy] autorelease]; - [self setMutableRequest:mutable]; -} - return redirectRequest; + return redirectRequest; + } } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { - // this method is called when the server has determined that it - // has enough information to create the NSURLResponse - // it can be called multiple times, for example in the case of a - // redirect, so each time we reset the data. - [downloadedData_ setLength:0]; - [downloadFileHandle_ truncateFileAtOffset:0]; - downloadedLength_ = 0; + @synchronized(self) { + // This method is called when the server has determined that it + // has enough information to create the NSURLResponse + // it can be called multiple times, for example in the case of a + // redirect, so each time we reset the data. + [downloadedData_ setLength:0]; + [downloadFileHandle_ truncateFileAtOffset:0]; + downloadedLength_ = 0; - [self setResponse:response]; + [self setResponse:response]; - // save cookies from the response - [self handleCookiesForResponse:response]; + // Save cookies from the response + [self handleCookiesForResponse:response]; + } } @@ -811,57 +839,58 @@ CannotBeginFetch: } -(void)connection:(NSURLConnection *)connection - didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + @synchronized(self) { + if ([challenge previousFailureCount] <= 2) { - if ([challenge previousFailureCount] <= 2) { + NSURLCredential *credential = credential_; - NSURLCredential *credential = credential_; + if ([[challenge protectionSpace] isProxy] && proxyCredential_ != nil) { + credential = proxyCredential_; + } - if ([[challenge protectionSpace] isProxy] && proxyCredential_ != nil) { - credential = proxyCredential_; + // Here, if credential is still nil, then we *could* try to get it from + // NSURLCredentialStorage's defaultCredentialForProtectionSpace:. + // We don't, because we're assuming: + // + // - for server credentials, we only want ones supplied by the program + // calling http fetcher + // - for proxy credentials, if one were necessary and available in the + // keychain, it would've been found automatically by NSURLConnection + // and this challenge delegate method never would've been called + // anyway + + if (credential) { + // try the credential + [[challenge sender] useCredential:credential + forAuthenticationChallenge:challenge]; + return; + } } - // Here, if credential is still nil, then we *could* try to get it from - // NSURLCredentialStorage's defaultCredentialForProtectionSpace:. - // We don't, because we're assuming: - // - // - for server credentials, we only want ones supplied by the program - // calling http fetcher - // - for proxy credentials, if one were necessary and available in the - // keychain, it would've been found automatically by NSURLConnection - // and this challenge delegate method never would've been called - // anyway - - if (credential) { - // try the credential - [[challenge sender] useCredential:credential - forAuthenticationChallenge:challenge]; - return; - } - } - - // If we don't have credentials, or we've already failed auth 3x, - // report the error, putting the challenge as a value in the userInfo - // dictionary + // If we don't have credentials, or we've already failed auth 3x, + // report the error, putting the challenge as a value in the userInfo + // dictionary. #if DEBUG - NSAssert(!isCancellingChallenge_, @"isCancellingChallenge_ unexpected"); + NSAssert(!isCancellingChallenge_, @"isCancellingChallenge_ unexpected"); #endif - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:challenge - forKey:kGTMHTTPFetcherErrorChallengeKey]; - NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherErrorDomain - code:kGTMHTTPFetcherErrorAuthenticationChallengeFailed - userInfo:userInfo]; + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:challenge + forKey:kGTMHTTPFetcherErrorChallengeKey]; + NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherErrorDomain + code:kGTMHTTPFetcherErrorAuthenticationChallengeFailed + userInfo:userInfo]; - // cancelAuthenticationChallenge seems to indirectly call - // connection:didFailWithError: now, though that isn't documented - // - // we'll use an ivar to make the indirect invocation of the - // delegate method do nothing - isCancellingChallenge_ = YES; - [[challenge sender] cancelAuthenticationChallenge:challenge]; - isCancellingChallenge_ = NO; + // cancelAuthenticationChallenge seems to indirectly call + // connection:didFailWithError: now, though that isn't documented + // + // We'll use an ivar to make the indirect invocation of the + // delegate method do nothing. + isCancellingChallenge_ = YES; + [[challenge sender] cancelAuthenticationChallenge:challenge]; + isCancellingChallenge_ = NO; - [self connection:connection didFailWithError:error]; + [self connection:connection didFailWithError:error]; + } } - (void)invokeFetchCallbacksWithData:(NSData *)data @@ -885,7 +914,7 @@ CannotBeginFetch: data:(NSData *)data error:(NSError *)error { // This method is available to subclasses which may provide a customized - // target pointer + // target pointer. if (target && sel) { NSMethodSignature *sig = [target methodSignatureForSelector:sel]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; @@ -898,6 +927,34 @@ CannotBeginFetch: } } +- (void)invokeFetchCallbacksOnDelegateQueueWithData:(NSData *)data + error:(NSError *)error { + // This is called by methods that are not already on the delegateQueue + // (as NSURLConnection callbacks should already be, but other failures + // are not.) + if (!delegateQueue_) { + [self invokeFetchCallbacksWithData:data error:error]; + } + + // Values may be nil. + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:2]; + [dict setValue:data forKey:kCallbackData]; + [dict setValue:error forKey:kCallbackError]; + NSInvocationOperation *op = + [[[NSInvocationOperation alloc] initWithTarget:self + selector:@selector(invokeOnQueueWithDictionary:) + object:dict] autorelease]; + [delegateQueue_ addOperation:op]; +} + +- (void)invokeOnQueueWithDictionary:(NSDictionary *)dict { + NSData *data = [dict objectForKey:kCallbackData]; + NSError *error = [dict objectForKey:kCallbackError]; + + [self invokeFetchCallbacksWithData:data error:error]; +} + + - (void)invokeSentDataCallback:(SEL)sel target:(id)target didSendBodyData:(NSInteger)bytesWritten @@ -939,67 +996,69 @@ CannotBeginFetch: didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { - - SEL sel = [self sentDataSelector]; - [self invokeSentDataCallback:sel - target:delegate_ - didSendBodyData:bytesWritten - totalBytesWritten:totalBytesWritten - totalBytesExpectedToWrite:totalBytesExpectedToWrite]; + @synchronized(self) { + SEL sel = [self sentDataSelector]; + [self invokeSentDataCallback:sel + target:delegate_ + didSendBodyData:bytesWritten + totalBytesWritten:totalBytesWritten + totalBytesExpectedToWrite:totalBytesExpectedToWrite]; #if NS_BLOCKS_AVAILABLE - if (sentDataBlock_) { - sentDataBlock_(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); - } + if (sentDataBlock_) { + sentDataBlock_(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } #endif + } } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + @synchronized(self) { #if DEBUG - // the download file handle should be set before the fetch is started, not - // after - NSAssert((downloadFileHandle_ == nil) != (downloadedData_ == nil), - @"received data accumulates as NSData or NSFileHandle, not both"); + // The download file handle should be set before the fetch is started, not + // after + NSAssert((downloadFileHandle_ == nil) != (downloadedData_ == nil), + @"received data accumulates as NSData or NSFileHandle, not both"); #endif - if (downloadFileHandle_ != nil) { - // append to file - @try { - [downloadFileHandle_ writeData:data]; + if (downloadFileHandle_ != nil) { + // Append to file + @try { + [downloadFileHandle_ writeData:data]; - downloadedLength_ = [downloadFileHandle_ offsetInFile]; + downloadedLength_ = [downloadFileHandle_ offsetInFile]; + } + @catch (NSException *exc) { + // Couldn't write to file, probably due to a full disk + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[exc reason] + forKey:NSLocalizedDescriptionKey]; + NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherStatusDomain + code:kGTMHTTPFetcherErrorFileHandleException + userInfo:userInfo]; + [self connection:connection didFailWithError:error]; + return; + } + } else { + // append to mutable data + [downloadedData_ appendData:data]; + + downloadedLength_ = [downloadedData_ length]; } - @catch (NSException *exc) { - // couldn't write to file, probably due to a full disk - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[exc reason] - forKey:NSLocalizedDescriptionKey]; - NSError *error = [NSError errorWithDomain:kGTMHTTPFetcherStatusDomain - code:kGTMHTTPFetcherErrorFileHandleException - userInfo:userInfo]; - [self connection:connection didFailWithError:error]; - return; + + if (receivedDataSel_) { + [delegate_ performSelector:receivedDataSel_ + withObject:self + withObject:downloadedData_]; } - } else { - // append to mutable data - [downloadedData_ appendData:data]; - - downloadedLength_ = [downloadedData_ length]; - } - - if (receivedDataSel_) { - [delegate_ performSelector:receivedDataSel_ - withObject:self - withObject:downloadedData_]; - } #if NS_BLOCKS_AVAILABLE - if (receivedDataBlock_) { - receivedDataBlock_(downloadedData_); - } + if (receivedDataBlock_) { + receivedDataBlock_(downloadedData_); + } #endif + } } - // For error 304's ("Not Modified") where we've cached the data, return // status 200 ("OK") to the caller (but leave the fetcher status as 304) // and copy the cached data. @@ -1013,10 +1072,10 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { NSData *cachedData = [fetchHistory_ cachedDataForRequest:request_]; if (cachedData) { - // forge the status to pass on to the delegate + // Forge the status to pass on to the delegate status = 200; - // copy our stored data + // Copy our stored data if (downloadFileHandle_ != nil) { @try { // Downloading to a file handle won't save to the cache (the data is @@ -1041,123 +1100,127 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - // we no longer need to cancel the connection - hasConnectionEnded_ = YES; + @synchronized(self) { + // We no longer need to cancel the connection + hasConnectionEnded_ = YES; - // skip caching ETagged results when the data is being saved to a file - if (downloadFileHandle_ == nil) { - [fetchHistory_ updateFetchHistoryWithRequest:request_ - response:response_ - downloadedData:downloadedData_]; - } else { - [fetchHistory_ removeCachedDataForRequest:request_]; - } - - [[self retain] autorelease]; // in case the callback releases us - - [self logNowWithError:nil]; - - NSInteger status = [self statusAfterHandlingNotModifiedError]; - - // we want to send the stop notification before calling the delegate's - // callback selector, since the callback selector may release all of - // the fetcher properties that the client is using to track the fetches - // - // We'll also stop now so that, to any observers watching the notifications, - // it doesn't look like our wait for a retry (which may be long, - // 30 seconds or more) is part of the network activity - [self sendStopNotificationIfNeeded]; - - BOOL shouldStopFetching = YES; - NSError *error = nil; - - if (status >= 0 && status < 300) { - // success - if (downloadPath_) { - // avoid deleting the downloaded file when the fetch stops - [downloadFileHandle_ closeFile]; - self.downloadFileHandle = nil; - - NSFileManager *fileMgr = [self fileManager]; - [fileMgr removeItemAtPath:downloadPath_ - error:NULL]; - - if ([fileMgr moveItemAtPath:temporaryDownloadPath_ - toPath:downloadPath_ - error:&error]) { - self.temporaryDownloadPath = nil; - } - } - } else { - // status over 300; retry or notify the delegate of failure - if ([self shouldRetryNowForStatus:status error:nil]) { - // retrying - [self beginRetryTimer]; - shouldStopFetching = NO; + // Skip caching ETagged results when the data is being saved to a file + if (downloadFileHandle_ == nil) { + [fetchHistory_ updateFetchHistoryWithRequest:request_ + response:response_ + downloadedData:downloadedData_]; } else { - NSDictionary *userInfo = nil; - if ([downloadedData_ length] > 0) { - userInfo = [NSDictionary dictionaryWithObject:downloadedData_ - forKey:kGTMHTTPFetcherStatusDataKey]; - } - error = [NSError errorWithDomain:kGTMHTTPFetcherStatusDomain - code:status - userInfo:userInfo]; + [fetchHistory_ removeCachedDataForRequest:request_]; } - } - if (shouldStopFetching) { - // call the callbacks - [self invokeFetchCallbacksWithData:downloadedData_ - error:error]; + [[self retain] autorelease]; // in case the callback releases us - BOOL shouldRelease = [self shouldReleaseCallbacksUponCompletion]; - [self stopFetchReleasingCallbacks:shouldRelease]; + [self logNowWithError:nil]; + + NSInteger status = [self statusAfterHandlingNotModifiedError]; + + // We want to send the stop notification before calling the delegate's + // callback selector, since the callback selector may release all of + // the fetcher properties that the client is using to track the fetches. + // + // We'll also stop now so that, to any observers watching the notifications, + // it doesn't look like our wait for a retry (which may be long, + // 30 seconds or more) is part of the network activity. + [self sendStopNotificationIfNeeded]; + + BOOL shouldStopFetching = YES; + NSError *error = nil; + + if (status >= 0 && status < 300) { + // success + if (downloadPath_) { + // Avoid deleting the downloaded file when the fetch stops + [downloadFileHandle_ closeFile]; + self.downloadFileHandle = nil; + + NSFileManager *fileMgr = [NSFileManager defaultManager]; + [fileMgr removeItemAtPath:downloadPath_ + error:NULL]; + + if ([fileMgr moveItemAtPath:temporaryDownloadPath_ + toPath:downloadPath_ + error:&error]) { + self.temporaryDownloadPath = nil; + } + } + } else { + // Status over 300; retry or notify the delegate of failure + if ([self shouldRetryNowForStatus:status error:nil]) { + // retrying + [self beginRetryTimer]; + shouldStopFetching = NO; + } else { + NSDictionary *userInfo = nil; + if ([downloadedData_ length] > 0) { + userInfo = [NSDictionary dictionaryWithObject:downloadedData_ + forKey:kGTMHTTPFetcherStatusDataKey]; + } + error = [NSError errorWithDomain:kGTMHTTPFetcherStatusDomain + code:status + userInfo:userInfo]; + } + } + + if (shouldStopFetching) { + // Call the callbacks + [self invokeFetchCallbacksWithData:downloadedData_ + error:error]; + + BOOL shouldRelease = [self shouldReleaseCallbacksUponCompletion]; + [self stopFetchReleasingCallbacks:shouldRelease]; + } } } - (BOOL)shouldReleaseCallbacksUponCompletion { - // a subclass can override this to keep callbacks around after the + // A subclass can override this to keep callbacks around after the // connection has finished successfully return YES; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - // prevent the failure callback from being called twice, since the stopFetch - // call below (either the explicit one at the end of this method, or the - // implicit one when the retry occurs) will release the delegate - if (connection_ == nil) return; + @synchronized(self) { + // Prevent the failure callback from being called twice, since the stopFetch + // call below (either the explicit one at the end of this method, or the + // implicit one when the retry occurs) will release the delegate. + if (connection_ == nil) return; - // if this method was invoked indirectly by cancellation of an authentication - // challenge, defer this until it is called again with the proper error object - if (isCancellingChallenge_) return; + // If this method was invoked indirectly by cancellation of an authentication + // challenge, defer this until it is called again with the proper error object + if (isCancellingChallenge_) return; - // we no longer need to cancel the connection - hasConnectionEnded_ = YES; + // We no longer need to cancel the connection + hasConnectionEnded_ = YES; - [self logNowWithError:error]; + [self logNowWithError:error]; - // see comment about sendStopNotificationIfNeeded - // in connectionDidFinishLoading: - [self sendStopNotificationIfNeeded]; + // See comment about sendStopNotificationIfNeeded + // in connectionDidFinishLoading: + [self sendStopNotificationIfNeeded]; - if ([self shouldRetryNowForStatus:0 error:error]) { + if ([self shouldRetryNowForStatus:0 error:error]) { - [self beginRetryTimer]; + [self beginRetryTimer]; - } else { + } else { - [[self retain] autorelease]; // in case the callback releases us + [[self retain] autorelease]; // in case the callback releases us - [self invokeFetchCallbacksWithData:nil - error:error]; + [self invokeFetchCallbacksWithData:nil + error:error]; - [self stopFetchReleasingCallbacks:YES]; + [self stopFetchReleasingCallbacks:YES]; + } } } - (void)logNowWithError:(NSError *)error { - // if the logging category is available, then log the current request, + // If the logging category is available, then log the current request, // response, data, and error if ([self respondsToSelector:@selector(logFetchWithError:)]) { [self performSelector:@selector(logFetchWithError:) withObject:error]; @@ -1258,13 +1321,26 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { } - (void)beginRetryTimer { + @synchronized(self) { + if (delegateQueue_ != nil && ![NSThread isMainThread]) { + // A delegate queue is set, so the thread we're running on may not + // have a run loop. We'll defer creating and starting the timer + // until we're on the main thread to ensure it has a run loop. + // (If we weren't supporting 10.5, we could use dispatch_after instead + // of an NSTimer.) + [self performSelectorOnMainThread:_cmd + withObject:nil + waitUntilDone:NO]; + return; + } - NSTimeInterval nextInterval = [self nextRetryInterval]; - NSTimeInterval maxInterval = [self maxRetryInterval]; + NSTimeInterval nextInterval = [self nextRetryInterval]; + NSTimeInterval maxInterval = [self maxRetryInterval]; - NSTimeInterval newInterval = MIN(nextInterval, maxInterval); + NSTimeInterval newInterval = MIN(nextInterval, maxInterval); - [self primeRetryTimerWithNewTimeInterval:newInterval]; + [self primeRetryTimerWithNewTimeInterval:newInterval]; + } } - (void)primeRetryTimerWithNewTimeInterval:(NSTimeInterval)secs { @@ -1273,25 +1349,31 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { lastRetryInterval_ = secs; - retryTimer_ = [NSTimer scheduledTimerWithTimeInterval:secs - target:self - selector:@selector(retryTimerFired:) - userInfo:nil - repeats:NO]; + retryTimer_ = [NSTimer timerWithTimeInterval:secs + target:self + selector:@selector(retryTimerFired:) + userInfo:nil + repeats:NO]; [retryTimer_ retain]; + NSRunLoop *timerRL = (self.delegateQueue ? + [NSRunLoop mainRunLoop] : [NSRunLoop currentRunLoop]); + [timerRL addTimer:retryTimer_ + forMode:NSDefaultRunLoopMode]; + NSNotificationCenter *defaultNC = [NSNotificationCenter defaultCenter]; [defaultNC postNotificationName:kGTMHTTPFetcherRetryDelayStartedNotification object:self]; } - (void)retryTimerFired:(NSTimer *)timer { + @synchronized(self) { + [self destroyRetryTimer]; - [self destroyRetryTimer]; + retryCount_++; - retryCount_++; - - [self retryFetch]; + [self retryFetch]; + } } - (void)destroyRetryTimer { @@ -1311,8 +1393,8 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { } - (NSTimeInterval)nextRetryInterval { - // the next wait interval is the factor (2.0) times the last interval, - // but never less than the minimum interval + // The next wait interval is the factor (2.0) times the last interval, + // but never less than the minimum interval. NSTimeInterval secs = lastRetryInterval_ * retryFactor_; secs = MIN(secs, maxRetryInterval_); secs = MAX(secs, minRetryInterval_); @@ -1332,7 +1414,7 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { // However, this means min and max intervals for this fetcher are reset // as a side effect of calling setRetryEnabled. // - // make an initial retry interval random between 1.0 and 2.0 seconds + // Make an initial retry interval random between 1.0 and 2.0 seconds [self setMinRetryInterval:0.0]; [self setMaxRetryInterval:kUnsetMaxRetryInterval]; [self setRetryFactor:2.0]; @@ -1361,7 +1443,7 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { if (secs > 0) { minRetryInterval_ = secs; } else { - // set min interval to a random value between 1.0 and 2.0 seconds + // Set min interval to a random value between 1.0 and 2.0 seconds // so that if multiple clients start retrying at the same time, they'll // repeat at different times and avoid overloading the server minRetryInterval_ = 1.0 + ((double)(arc4random() & 0x0FFFF) / (double) 0x0FFFF); @@ -1403,6 +1485,7 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { downloadPath = downloadPath_, temporaryDownloadPath = temporaryDownloadPath_, downloadFileHandle = downloadFileHandle_, + delegateQueue = delegateQueue_, runLoopModes = runLoopModes_, comment = comment_, log = log_, @@ -1426,18 +1509,18 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { cookieStorageMethod_ = method; if (method == kGTMHTTPFetcherCookieStorageMethodSystemDefault) { - // system default + // System default [request_ setHTTPShouldHandleCookies:YES]; - // no need for a cookie storage object + // No need for a cookie storage object self.cookieStorage = nil; } else { - // not system default + // Not system default [request_ setHTTPShouldHandleCookies:NO]; if (method == kGTMHTTPFetcherCookieStorageMethodStatic) { - // store cookies in the static array + // Store cookies in the static array NSAssert(gGTMFetcherStaticCookieStorage != nil, @"cookie storage requires GTMHTTPFetchHistory"); @@ -1462,9 +1545,9 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { // available starting in iPhone OS 3.0 return (NSFoundationVersionNumber >= 678.47); #else - // per WebKit's MaxFoundationVersionWithoutdidSendBodyDataDelegate + // Per WebKit's MaxFoundationVersionWithoutdidSendBodyDataDelegate // - // indicates if NSURLConnection will invoke the didSendBodyData: delegate + // Indicates if NSURLConnection will invoke the didSendBodyData: delegate // method return (NSFoundationVersionNumber > 677.21); #endif @@ -1483,9 +1566,9 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { [self setCookieStorageMethod:kGTMHTTPFetcherCookieStorageMethodFetchHistory]; } else { - // the fetch history was removed + // The fetch history was removed if (cookieStorageMethod_ == kGTMHTTPFetcherCookieStorageMethodFetchHistory) { - // fall back to static storage + // Fall back to static storage [self setCookieStorageMethod:kGTMHTTPFetcherCookieStorageMethodStatic]; } } @@ -1565,14 +1648,14 @@ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...) { - // verify that the object's selector is implemented with the proper + // Verify that the object's selector is implemented with the proper // number and type of arguments #if DEBUG va_list argList; va_start(argList, sel); if (obj && sel) { - // check that the selector is implemented + // Check that the selector is implemented if (![obj respondsToSelector:sel]) { NSLog(@"\"%@\" selector \"%@\" is unimplemented or misnamed", NSStringFromClass([obj class]), @@ -1583,7 +1666,7 @@ void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...) { unsigned int argCount = 2; // skip self and _cmd NSMethodSignature *sig = [obj methodSignatureForSelector:sel]; - // check that each expected argument is present and of the correct type + // Check that each expected argument is present and of the correct type while ((expectedArgType = va_arg(argList, const char*)) != 0) { if ([sig numberOfArguments] > argCount) { @@ -1599,7 +1682,7 @@ void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...) { argCount++; } - // check that the proper number of arguments are present in the selector + // Check that the proper number of arguments are present in the selector if (argCount != [sig numberOfArguments]) { NSLog( @"\"%@\" selector \"%@\" should have %d arguments", NSStringFromClass([obj class]), @@ -1654,14 +1737,19 @@ NSString *GTMSystemVersionString(void) { #if TARGET_OS_MAC && !TARGET_OS_IPHONE // Mac build - SInt32 systemMajor = 0, systemMinor = 0, systemRelease = 0; - (void) Gestalt(gestaltSystemVersionMajor, &systemMajor); - (void) Gestalt(gestaltSystemVersionMinor, &systemMinor); - (void) Gestalt(gestaltSystemVersionBugFix, &systemRelease); - - systemString = [NSString stringWithFormat:@"MacOSX/%d.%d.%d", - (int)systemMajor, (int)systemMinor, (int)systemRelease]; - + static NSString *savedSystemString = nil; + if (savedSystemString == nil) { + // With Gestalt inexplicably deprecated in 10.8, we're reduced to reading + // the system plist file. + NSString *const kPath = @"/System/Library/CoreServices/SystemVersion.plist"; + NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:kPath]; + NSString *versString = [plist objectForKey:@"ProductVersion"]; + if ([versString length] == 0) { + versString = @"10.?.?"; + } + savedSystemString = [[NSString alloc] initWithFormat:@"MacOSX/%@", versString]; + } + systemString = savedSystemString; #elif TARGET_OS_IPHONE // Compiling against the iPhone SDK diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.m b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.m index 2b959830..84387ca6 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.m @@ -40,10 +40,13 @@ @end // If GTMNSJSONSerialization is available, it is used for formatting JSON +#if (TARGET_OS_MAC && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED < 1070)) || \ + (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED < 50000)) @interface GTMNSJSONSerialization : NSObject + (NSData *)dataWithJSONObject:(id)obj options:(NSUInteger)opt error:(NSError **)error; + (id)JSONObjectWithData:(NSData *)data options:(NSUInteger)opt error:(NSError **)error; @end +#endif // Otherwise, if SBJSON is available, it is used for formatting JSON @interface GTMFetcherSBJSON diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.h b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.h index e3837933..9c6cd754 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.h +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.h @@ -42,6 +42,7 @@ NSUInteger maxRunningFetchersPerHost_; GTMHTTPFetchHistory *fetchHistory_; + NSOperationQueue *delegateQueue_; NSArray *runLoopModes_; NSString *userAgent_; NSTimeInterval timeout_; @@ -83,12 +84,18 @@ - (NSUInteger)numberOfRunningFetchers; - (NSUInteger)numberOfDelayedFetchers; +// Search for running or delayed fetchers with the specified URL. +// +// Returns an array of fetcher objects found, or nil if none found. +- (NSArray *)issuedFetchersWithRequestURL:(NSURL *)requestURL; + - (void)stopAllFetchers; // Properties to be applied to each fetcher; // see GTMHTTPFetcher.h for descriptions @property (copy) NSString *userAgent; @property (assign) NSTimeInterval timeout; +@property (retain) NSOperationQueue *delegateQueue; @property (retain) NSArray *runLoopModes; @property (retain) NSURLCredential *credential; @property (retain) NSURLCredential *proxyCredential; diff --git a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m index 78c5f6f5..15909dbb 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m @@ -36,6 +36,7 @@ @synthesize maxRunningFetchersPerHost = maxRunningFetchersPerHost_, userAgent = userAgent_, timeout = timeout_, + delegateQueue = delegateQueue_, runLoopModes = runLoopModes_, credential = credential_, proxyCredential = proxyCredential_, @@ -63,6 +64,7 @@ [runningHosts_ release]; [fetchHistory_ release]; [userAgent_ release]; + [delegateQueue_ release]; [runLoopModes_ release]; [credential_ release]; [proxyCredential_ release]; @@ -78,6 +80,7 @@ GTMHTTPFetcher *fetcher = [fetcherClass fetcherWithRequest:request]; fetcher.fetchHistory = self.fetchHistory; + fetcher.delegateQueue = self.delegateQueue; fetcher.runLoopModes = self.runLoopModes; fetcher.cookieStorageMethod = self.cookieStorageMethod; fetcher.credential = self.credential; @@ -143,14 +146,13 @@ } - (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher { - BOOL isDelayed; @synchronized(self) { NSString *host = [[[fetcher mutableRequest] URL] host]; NSArray *delayedForHost = [delayedHosts_ objectForKey:host]; NSUInteger idx = [delayedForHost indexOfObjectIdenticalTo:fetcher]; - isDelayed = (delayedForHost != nil) && (idx != NSNotFound); + BOOL isDelayed = (delayedForHost != nil) && (idx != NSNotFound); + return isDelayed; } - return isDelayed; } - (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher { @@ -194,23 +196,32 @@ // Fetcher start and stop methods, invoked on the appropriate thread for // the fetcher +- (void)performSelector:(SEL)sel onStartThreadForFetcher:(GTMHTTPFetcher *)fetcher { + NSOperationQueue *delegateQueue = fetcher.delegateQueue; + NSThread *thread = fetcher.thread; + if (delegateQueue != nil || [thread isEqual:[NSThread currentThread]]) { + // The fetcher should run on the thread we're on now, or there's a delegate + // queue specified so it doesn't matter what thread the fetcher is started + // on, since it will call back on the queue. + [self performSelector:sel withObject:fetcher]; + } else { + // Fetcher must run on a specified thread (and that thread must have a + // run loop.) + [self performSelector:sel + onThread:thread + withObject:fetcher + waitUntilDone:NO]; + } +} + - (void)startFetcherOnCurrentThread:(GTMHTTPFetcher *)fetcher { [fetcher beginFetchMayDelay:NO mayAuthorize:YES]; } - (void)startFetcher:(GTMHTTPFetcher *)fetcher { - NSThread *thread = [fetcher thread]; - if ([thread isEqual:[NSThread currentThread]]) { - // Same thread - [self startFetcherOnCurrentThread:fetcher]; - } else { - // Different thread - [self performSelector:@selector(startFetcherOnCurrentThread:) - onThread:thread - withObject:fetcher - waitUntilDone:NO]; - } + [self performSelector:@selector(startFetcherOnCurrentThread:) + onStartThreadForFetcher:fetcher]; } - (void)stopFetcherOnCurrentThread:(GTMHTTPFetcher *)fetcher { @@ -218,17 +229,8 @@ } - (void)stopFetcher:(GTMHTTPFetcher *)fetcher { - NSThread *thread = [fetcher thread]; - if ([thread isEqual:[NSThread currentThread]]) { - // Same thread - [self stopFetcherOnCurrentThread:fetcher]; - } else { - // Different thread - [self performSelector:@selector(stopFetcherOnCurrentThread:) - onThread:thread - withObject:fetcher - waitUntilDone:NO]; - } + [self performSelector:@selector(stopFetcherOnCurrentThread:) + onStartThreadForFetcher:fetcher]; } - (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher { @@ -282,47 +284,88 @@ } - (NSUInteger)numberOfFetchers { - NSUInteger running = [self numberOfRunningFetchers]; - NSUInteger delayed = [self numberOfDelayedFetchers]; - return running + delayed; + @synchronized(self) { + NSUInteger running = [self numberOfRunningFetchers]; + NSUInteger delayed = [self numberOfDelayedFetchers]; + return running + delayed; + } } - (NSUInteger)numberOfRunningFetchers { - NSUInteger sum = 0; - for (NSString *host in runningHosts_) { - NSArray *fetchers = [runningHosts_ objectForKey:host]; - sum += [fetchers count]; + @synchronized(self) { + NSUInteger sum = 0; + for (NSString *host in runningHosts_) { + NSArray *fetchers = [runningHosts_ objectForKey:host]; + sum += [fetchers count]; + } + return sum; } - return sum; } - (NSUInteger)numberOfDelayedFetchers { - NSUInteger sum = 0; - for (NSString *host in delayedHosts_) { - NSArray *fetchers = [delayedHosts_ objectForKey:host]; - sum += [fetchers count]; + @synchronized(self) { + NSUInteger sum = 0; + for (NSString *host in delayedHosts_) { + NSArray *fetchers = [delayedHosts_ objectForKey:host]; + sum += [fetchers count]; + } + return sum; + } +} + +- (NSArray *)issuedFetchersWithRequestURL:(NSURL *)requestURL { + @synchronized(self) { + NSMutableArray *array = nil; + NSString *host = [requestURL host]; + if ([host length] == 0) return nil; + + NSURL *absRequestURL = [requestURL absoluteURL]; + + NSArray *runningForHost = [runningHosts_ objectForKey:host]; + for (GTMHTTPFetcher *fetcher in runningForHost) { + NSURL *fetcherURL = [[[fetcher mutableRequest] URL] absoluteURL]; + if ([fetcherURL isEqual:absRequestURL]) { + if (array == nil) { + array = [NSMutableArray array]; + } + [array addObject:fetcher]; + } + } + + NSArray *delayedForHost = [delayedHosts_ objectForKey:host]; + for (GTMHTTPFetcher *fetcher in delayedForHost) { + NSURL *fetcherURL = [[[fetcher mutableRequest] URL] absoluteURL]; + if ([fetcherURL isEqual:absRequestURL]) { + if (array == nil) { + array = [NSMutableArray array]; + } + [array addObject:fetcher]; + } + } + return array; } - return sum; } - (void)stopAllFetchers { - // Remove fetchers from the delayed list to avoid fetcherDidStop: from - // starting more fetchers running as a side effect of stopping one - NSArray *delayedForHosts = [delayedHosts_ allValues]; - [delayedHosts_ removeAllObjects]; + @synchronized(self) { + // Remove fetchers from the delayed list to avoid fetcherDidStop: from + // starting more fetchers running as a side effect of stopping one + NSArray *delayedForHosts = [delayedHosts_ allValues]; + [delayedHosts_ removeAllObjects]; - for (NSArray *delayedForHost in delayedForHosts) { - for (GTMHTTPFetcher *fetcher in delayedForHost) { - [self stopFetcher:fetcher]; + for (NSArray *delayedForHost in delayedForHosts) { + for (GTMHTTPFetcher *fetcher in delayedForHost) { + [self stopFetcher:fetcher]; + } } - } - NSArray *runningForHosts = [runningHosts_ allValues]; - [runningHosts_ removeAllObjects]; + NSArray *runningForHosts = [runningHosts_ allValues]; + [runningHosts_ removeAllObjects]; - for (NSArray *runningForHost in runningForHosts) { - for (GTMHTTPFetcher *fetcher in runningForHost) { - [self stopFetcher:fetcher]; + for (NSArray *runningForHost in runningForHosts) { + for (GTMHTTPFetcher *fetcher in runningForHost) { + [self stopFetcher:fetcher]; + } } } } @@ -370,13 +413,19 @@ - (void)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds { NSDate* giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; + BOOL isMainThread = [NSThread isMainThread]; while ([self numberOfFetchers] > 0 && [giveUpDate timeIntervalSinceNow] > 0) { // Run the current run loop 1/1000 of a second to give the networking // code a chance to work - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; + if (isMainThread || delegateQueue_ == nil) { + NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; + [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; + } else { + // Sleep on the delegate queue's background thread. + [NSThread sleepForTimeInterval:0.001]; + } } } diff --git a/External/google-plus-ios-sdk/OpenSource/GTMLogger.m b/External/google-plus-ios-sdk/OpenSource/GTMLogger.m index 0263aa1f..4b40747b 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMLogger.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMLogger.m @@ -24,6 +24,16 @@ #import +#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) +// Some versions of GCC (4.2 and below AFAIK) aren't great about supporting +// -Wmissing-format-attribute +// when the function is anything more complex than foo(NSString *fmt, ...). +// You see the error inside the function when you turn ... into va_args and +// attempt to call another function (like vsprintf for example). +// So we just shut off the warning for this file. We reenable it at the end. +#pragma GCC diagnostic ignored "-Wmissing-format-attribute" +#endif // !__clang__ + // Reference to the shared GTMLogger instance. This is not a singleton, it's // just an easy reference to one shared instance. static GTMLogger *gSharedLogger = nil; @@ -265,7 +275,6 @@ static GTMLogger *gSharedLogger = nil; @end // GTMLogger - @implementation GTMLogger (GTMLoggerMacroHelpers) - (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... { @@ -298,7 +307,6 @@ static GTMLogger *gSharedLogger = nil; @end // GTMLoggerMacroHelpers - @implementation GTMLogger (PrivateMethods) - (void)logInternalFunc:(const char *)func @@ -596,3 +604,9 @@ static BOOL IsVerboseLoggingEnabled(void) { } @end // GTMLogMaximumLevelFilter + +#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) +// See comment at top of file. +#pragma GCC diagnostic error "-Wmissing-format-attribute" +#endif // !__clang__ + diff --git a/External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.m b/External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.m index 801278cb..bbf2cf47 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.m @@ -54,9 +54,11 @@ static BOOL ConformsToNSObjectProtocol(Class cls) { return YES; } -// iPhone SDK does not define the |Object| class, so we instead test for the -// |NSObject| class. -#if GTM_IPHONE_SDK + // iPhone and Mac OS X 10.8 with Obj-C 2 SDKs do not define the |Object| + // class, so we instead test for the |NSObject| class. +#if GTM_IPHONE_SDK || \ + (__OBJC2__ && defined(MAC_OS_X_VERSION_10_8) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8) // Iterate through all the protocols |cls| supports looking for NSObject. if (cls == [NSObject class] || class_conformsToProtocol(cls, @protocol(NSObject))) { diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.m b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.m index 6c067f6b..b3f74075 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.m @@ -44,9 +44,12 @@ static NSString *const kTokenFetchSelectorKey = @"sel"; static NSString *const kRefreshFetchArgsKey = @"requestArgs"; // If GTMNSJSONSerialization is available, it is used for formatting JSON +#if (TARGET_OS_MAC && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED < 1070)) || \ + (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED < 50000)) @interface GTMNSJSONSerialization : NSObject + (id)JSONObjectWithData:(NSData *)data options:(NSUInteger)opt error:(NSError **)error; @end +#endif @interface GTMOAuth2ParserClass : NSObject // just enough of SBJSON to be able to parse @@ -524,10 +527,24 @@ finishedRefreshWithFetcher:(GTMHTTPFetcher *)fetcher NSThread *targetThread = args.thread; BOOL isSameThread = [targetThread isEqual:[NSThread currentThread]]; - [self performSelector:@selector(invokeCallbackArgs:) - onThread:targetThread - withObject:args - waitUntilDone:isSameThread]; + if (isSameThread) { + [self invokeCallbackArgs:args]; + } else { + SEL sel = @selector(invokeCallbackArgs:); + NSOperationQueue *delegateQueue = self.fetcherService.delegateQueue; + if (delegateQueue) { + NSInvocationOperation *op; + op = [[[NSInvocationOperation alloc] initWithTarget:self + selector:sel + object:args] autorelease]; + [delegateQueue addOperation:op]; + } else { + [self performSelector:sel + onThread:targetThread + withObject:args + waitUntilDone:NO]; + } + } } BOOL didAuth = (args.error == nil); diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.h b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.h index a09be13c..90ccf397 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.h +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.h @@ -154,9 +154,17 @@ #pragma mark - -// Revocation of an authorized token from Google #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT +// Revocation of an authorized token from Google + (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth; + +// Create a fetcher for obtaining the user's Google email address or profile, +// according to the current auth scopes. +// +// The auth object must have been created with appropriate scopes. +// +// The fetcher's response data can be parsed with NSJSONSerialization. ++ (GTMHTTPFetcher *)userInfoFetcherWithAuth:(GTMOAuth2Authentication *)auth; #endif #pragma mark - diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.m b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.m index f1a11ee5..9755febd 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.m @@ -539,22 +539,15 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher } #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT -- (void)fetchGoogleUserInfo { - // fetch the user's email address ++ (GTMHTTPFetcher *)userInfoFetcherWithAuth:(GTMOAuth2Authentication *)auth { + // create a fetcher for obtaining the user's email or profile NSURL *infoURL = [[self class] googleUserInfoURL]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:infoURL]; - GTMOAuth2Authentication *auth = self.authentication; - NSString *userAgent = [auth userAgent]; [request setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - [request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; - // we can do a synchronous authorization since this method is called - // only immediately after a fresh access token has been obtained - [auth authorizeRequest:request]; - GTMHTTPFetcher *fetcher; id fetcherService = auth.fetcherService; if (fetcherService) { @@ -562,10 +555,17 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher } else { fetcher = [GTMHTTPFetcher fetcherWithRequest:request]; } + fetcher.authorizer = auth; fetcher.retryEnabled = YES; fetcher.maxRetryInterval = 15.0; fetcher.comment = @"user info"; + return fetcher; +} +- (void)fetchGoogleUserInfo { + // fetch the user's email address or profile + GTMOAuth2Authentication *auth = self.authentication; + GTMHTTPFetcher *fetcher = [[self class] userInfoFetcherWithAuth:auth]; [fetcher beginFetchWithDelegate:self didFinishSelector:@selector(infoFetcher:finishedWithData:error:)]; diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.h b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.h index 0037ab30..d20b3307 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.h +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.h @@ -53,6 +53,7 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com @private UIButton *backButton_; UIButton *forwardButton_; + UIActivityIndicatorView *initialActivityIndicator_; UIView *navButtonsView_; UIBarButtonItem *rightBarButtonItem_; UIWebView *webView_; @@ -73,6 +74,8 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com #if NS_BLOCKS_AVAILABLE void (^completionBlock_)(GTMOAuth2ViewControllerTouch *, GTMOAuth2Authentication *, NSError *); + + void (^popViewBlock_)(void); #endif NSString *keychainItemName_; @@ -82,6 +85,10 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com // of the web view NSString *initialHTMLString_; + // set to 1 or -1 if the user sets the showsInitialActivityIndicator + // property + int mustShowActivityIndicator_; + // if non-nil, the URL for which cookies will be deleted when the // browser view is dismissed NSURL *browserCookiesURL_; @@ -89,10 +96,12 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com id userData_; NSMutableDictionary *properties_; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 // We delegate the decision to our owning NavigationController (if any). // But, the NavigationController will call us back, and ask us. // BOOL keeps us from infinite looping. BOOL isInsideShouldAutorotateToInterfaceOrientation_; +#endif // YES, when view first shown in this signIn session. BOOL isViewShown_; @@ -132,6 +141,11 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com // initial view color @property (nonatomic, copy) NSString *initialHTMLString; +// an activity indicator shows during initial webview load when no initial HTML +// string is specified, but the activity indicator can be forced to be shown +// with this property +@property (nonatomic, assign) BOOL showsInitialActivityIndicator; + // the underlying object to hold authentication tokens and authorize http // requests @property (nonatomic, retain, readonly) GTMOAuth2Authentication *authentication; @@ -142,10 +156,17 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com // user interface elements @property (nonatomic, retain) IBOutlet UIButton *backButton; @property (nonatomic, retain) IBOutlet UIButton *forwardButton; +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView *initialActivityIndicator; @property (nonatomic, retain) IBOutlet UIView *navButtonsView; @property (nonatomic, retain) IBOutlet UIBarButtonItem *rightBarButtonItem; @property (nonatomic, retain) IBOutlet UIWebView *webView; +#if NS_BLOCKS_AVAILABLE +// An optional block to be called when the view should be popped. If not set, +// the view controller will use its navigation controller to pop the view. +@property (nonatomic, copy) void (^popViewBlock)(void); +#endif + // the default timeout for an unreachable network during display of the // sign-in page is 10 seconds; set this to 0 to have no timeout @property (nonatomic, assign) NSTimeInterval networkLossTimeoutInterval; @@ -244,10 +265,6 @@ _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler; #endif -// Override default in UIViewController. If we have a navigationController, ask -// it. else default result (i.e., Portrait mode only). -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; - // subclasses may override authNibName to specify a custom name + (NSString *)authNibName; diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.m b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.m index 99952b0b..037e5676 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.m +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.m @@ -55,7 +55,8 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth forwardButton = forwardButton_, navButtonsView = navButtonsView_, rightBarButtonItem = rightBarButtonItem_, - webView = webView_; + webView = webView_, + initialActivityIndicator = initialActivityIndicator_; @synthesize keychainItemName = keychainItemName_, keychainItemAccessibility = keychainItemAccessibility_, @@ -65,6 +66,10 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth userData = userData_, properties = properties_; +#if NS_BLOCKS_AVAILABLE +@synthesize popViewBlock = popViewBlock_; +#endif + #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT + (id)controllerWithScope:(NSString *)scope clientID:(NSString *)clientID @@ -153,7 +158,7 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth authorizationURL:authorizationURL keychainItemName:keychainItemName delegate:delegate - finishedSelector:finishedSelector] autorelease]; + finishedSelector:finishedSelector] autorelease]; } - (id)initWithAuthentication:(GTMOAuth2Authentication *)auth @@ -178,7 +183,7 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth delegate:self webRequestSelector:@selector(signIn:displayRequest:) finishedSelector:@selector(signIn:finishedWithAuth:error:)]; - + // if the user is signing in to a Google service, we'll delete the // Google authentication browser cookies upon completion // @@ -230,6 +235,7 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth [backButton_ release]; [forwardButton_ release]; + [initialActivityIndicator_ release]; [navButtonsView_ release]; [rightBarButtonItem_ release]; [webView_ release]; @@ -238,6 +244,7 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth [delegate_ release]; #if NS_BLOCKS_AVAILABLE [completionBlock_ release]; + [popViewBlock_ release]; #endif [keychainItemName_ release]; [initialHTMLString_ release]; @@ -358,26 +365,32 @@ finishedWithAuth:(GTMOAuth2Authentication *)auth - (void)viewDidLoad { - // the app may prefer some html other than blank white to be displayed - // before the sign-in web page loads - NSString *html = self.initialHTMLString; - if ([html length] > 0) { - [[self webView] loadHTMLString:html baseURL:nil]; - } - rightBarButtonItem_.customView = navButtonsView_; self.navigationItem.rightBarButtonItem = rightBarButtonItem_; } - (void)popView { - if (self.navigationController.topViewController == self) { - if (!self.view.isHidden) { +#if NS_BLOCKS_AVAILABLE + void (^popViewBlock)() = self.popViewBlock; +#else + id popViewBlock = nil; +#endif + + if (popViewBlock || self.navigationController.topViewController == self) { + if (!self.view.hidden) { // Set the flag to our viewWillDisappear method so it knows // this is a disappearance initiated by the sign-in object, // not the user cancelling via the navigation controller didDismissSelf_ = YES; - [self.navigationController popViewControllerAnimated:YES]; + if (popViewBlock) { +#if NS_BLOCKS_AVAILABLE + popViewBlock(); + self.popViewBlock = nil; +#endif + } else { + [self.navigationController popViewControllerAnimated:YES]; + } self.view.hidden = YES; } } @@ -488,6 +501,14 @@ static Class gSignInClass = Nil; return ([name length] > 0); } +- (BOOL)showsInitialActivityIndicator { + return (mustShowActivityIndicator_ == 1 || initialHTMLString_ == nil); +} + +- (void)setShowsInitialActivityIndicator:(BOOL)flag { + mustShowActivityIndicator_ = (flag ? 1 : -1); +} + #pragma mark User Properties - (void)setProperty:(id)obj forKey:(NSString *)key { @@ -514,8 +535,9 @@ static Class gSignInClass = Nil; #pragma mark SignIn callbacks - (void)signIn:(GTMOAuth2SignIn *)signIn displayRequest:(NSURLRequest *)request { - // this is the signIn object's webRequest method, telling the controller - // to either display the request in the webview, or close the window + // This is the signIn object's webRequest method, telling the controller + // to either display the request in the webview, or if the request is nil, + // to close the window. // // All web requests and all window closing goes through this routine @@ -535,12 +557,24 @@ static Class gSignInClass = Nil; if (isDateValid) { // Display the request. self.request = request; - BOOL shouldWaitForHTML = ([self.initialHTMLString length] > 0); - if (shouldWaitForHTML) { - [self.webView performSelector:@selector(loadRequest:) - withObject:request - afterDelay:0.05]; + // The app may prefer some html other than blank white to be displayed + // before the sign-in web page loads. + // The first fetch might be slow, so the client programmer may want + // to show a local "loading" message. + // On iOS 5+, UIWebView will ignore loadHTMLString: if it's followed by + // a loadRequest: call, so if there is a "loading" message we defer + // the loadRequest: until after after we've drawn the "loading" message. + // + // If there is no initial html string, we show the activity indicator + // unless the user set showsInitialActivityIndicator to NO; if there + // is an initial html string, we hide the indicator unless the user set + // showsInitialActivityIndicator to YES. + NSString *html = self.initialHTMLString; + if ([html length] > 0) { + [initialActivityIndicator_ setHidden:(mustShowActivityIndicator_ < 1)]; + [self.webView loadHTMLString:html baseURL:nil]; } else { + [initialActivityIndicator_ setHidden:(mustShowActivityIndicator_ < 0)]; [self.webView loadRequest:request]; } } else { @@ -673,6 +707,10 @@ static Class gSignInClass = Nil; // this will indirectly call our signIn:finishedWithAuth:error: method // for us [signIn_ windowWasClosed]; + +#if NS_BLOCKS_AVAILABLE + self.popViewBlock = nil; +#endif } // prevent the next sign-in from showing in the WebView that the user is @@ -724,9 +762,16 @@ static Class gSignInClass = Nil; #endif } - [signIn_ cookiesChanged:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; + if (self.request && [self.initialHTMLString length] > 0) { + // The request was pending. + [self setInitialHTMLString:nil]; + [self.webView loadRequest:self.request]; + } else { + [initialActivityIndicator_ setHidden:YES]; + [signIn_ cookiesChanged:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; - [self updateUI]; + [self updateUI]; + } } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { @@ -762,6 +807,17 @@ static Class gSignInClass = Nil; } } +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 +// When running on a device with an OS version < 6, this gets called. +// +// Since it is never called in iOS 6 or greater, if your min deployment +// target is iOS6 or greater, then you don't need to have this method compiled +// into your app. +// +// When running on a device with an OS version 6 or greater, this code is +// not called. - (NSUInteger)supportedInterfaceOrientations; would be called, +// if it existed. Since it is absent, +// Allow the default orientations: All for iPad, all but upside down for iPhone. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { BOOL value = YES; if (!isInsideShouldAutorotateToInterfaceOrientation_) { @@ -776,6 +832,8 @@ static Class gSignInClass = Nil; } return value; } +#endif + @end diff --git a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewTouch.xib b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewTouch.xib index f3f65e32..12d6834d 100644 --- a/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewTouch.xib +++ b/External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewTouch.xib @@ -1,32 +1,32 @@ - 768 - 10J869 - 851 - 1038.35 - 461.00 + 1024 + 12C60 + 2843 + 1187.34 + 625.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 141 + 1929 - + YES - - + IBProxyObject + IBUIActivityIndicatorView + IBUIBarButtonItem + IBUIButton + IBUINavigationItem + IBUIView + IBUIWebView YES com.apple.InterfaceBuilder.IBCocoaTouchPlugin - YES - - YES - - - YES - + PluginDependencyRecalculationVersion + YES @@ -56,16 +56,13 @@ 292 {30, 30} + + NO NO IBCocoaTouchFramework 0 0 - - Helvetica-Bold - 24 - 16 - {0, -2} @@ -81,18 +78,30 @@ 3 MC41AA + + Helvetica-Bold + Helvetica + 2 + 24 + + + Helvetica-Bold + 24 + 16 + 292 {{30, 0}, {30, 30}} + + NO NO IBCocoaTouchFramework 0 0 - {0, -2} @@ -102,10 +111,14 @@ + + {60, 30} + + 3 MSAwAA @@ -113,6 +126,7 @@ NO NO + 3 3 IBCocoaTouchFramework @@ -127,6 +141,8 @@ 274 {320, 460} + + 1 MSAxIDEAA @@ -137,9 +153,25 @@ 1 YES + + + 292 + {{150, 115}, {20, 20}} + + + + _NS:9 + NO + IBCocoaTouchFramework + NO + YES + 2 + {320, 460} + + 3 MQA @@ -153,40 +185,6 @@ YES - - - delegate - - - - 9 - - - - rightBarButtonItem - - - - 14 - - - - goBack - - - 7 - - 18 - - - - goForward - - - 7 - - 19 - rightBarButtonItem @@ -235,13 +233,57 @@ 29 + + + initialActivityIndicator + + + + 33 + + + + delegate + + + + 9 + + + + rightBarButtonItem + + + + 14 + + + + goBack + + + 7 + + 18 + + + + goForward + + + 7 + + 19 + YES 0 - + + YES + @@ -295,6 +337,7 @@ YES + @@ -303,6 +346,11 @@ + + 31 + + + @@ -310,27 +358,29 @@ YES -1.CustomClassName + -1.IBPluginDependency -2.CustomClassName + -2.IBPluginDependency 10.IBPluginDependency - 15.IBEditorWindowLastContentRect 15.IBPluginDependency 16.IBPluginDependency 17.IBPluginDependency - 27.IBEditorWindowLastContentRect 27.IBPluginDependency + 31.IBPluginDependency 4.IBPluginDependency 6.IBPluginDependency - + YES GTMOAuth2ViewControllerTouch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{34, 1031}, {60, 30}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{214, 696}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -339,20 +389,16 @@ YES - - YES - + YES - - YES - + - 29 + 33 @@ -365,21 +411,19 @@ YES backButton - delegate_ forwardButton + initialActivityIndicator navButtonsView rightBarButtonItem - userData_ webView - + YES UIButton - id UIButton + UIActivityIndicatorView UIView UIBarButtonItem - id UIWebView @@ -388,27 +432,26 @@ YES backButton - delegate_ forwardButton + initialActivityIndicator navButtonsView rightBarButtonItem - userData_ webView - + YES backButton UIButton - - delegate_ - id - forwardButton UIButton + + initialActivityIndicator + UIActivityIndicatorView + navButtonsView UIView @@ -417,10 +460,6 @@ rightBarButtonItem UIBarButtonItem - - userData_ - id - webView UIWebView @@ -429,7 +468,7 @@ IBProjectSource - Touch/GTMOAuth2ViewControllerTouch.h + ./Classes/GTMOAuth2ViewControllerTouch.h @@ -438,19 +477,18 @@ IBCocoaTouchFramework com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 YES - ../GTMOAuth2.xcodeproj 3 - 141 + 1929 diff --git a/External/google-plus-ios-sdk/README b/External/google-plus-ios-sdk/README index 749afdf6..d6aafb23 100644 --- a/External/google-plus-ios-sdk/README +++ b/External/google-plus-ios-sdk/README @@ -7,10 +7,12 @@ README -- This file. Changelog -- The versions and changes of the SDK. lib/ -- Header files and libraries. - GooglePlusShare.h -- Header file to include for sharing with Google+. - GooglePlusSignIn.h -- Header file to include for signing into Google+. - GooglePlusSignInButton.h -- Header file to include for showing a button to - sign in with Google+. + GPPDeepLink.h -- Header file to include for sharing with Google+ with content + deep linking. + GPPShare.h -- Header file to include for sharing with Google+. + GPPSignIn.h -- Header file to include for signing into Google+. + GPPSignInButton.h -- Header file to include for showing a button to + sign in with Google+. libGooglePlus.a -- Static library built for iOS device to link into your app. libGooglePlusUniversal.a -- Static library built for both iOS device and simulator to link into your app. @@ -23,7 +25,7 @@ OpenSource/ -- Google open source files used by the SDK. Add all files in this e.g. Add Moments. Resources/ -- Resources that can be used in your app. - For |GooglePlusSignInButton|, the google_plus_sign_in*.png images + For |GPPSignInButton|, the google_plus_sign_in*.png images are required. google_plus_share.png -- 82x24 Google+ share button image. google_plus_share_large.png -- 112x32 Google+ share button image. diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.pbxproj b/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.pbxproj index c8d5eff4..a9e8f15d 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.pbxproj +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.pbxproj @@ -17,7 +17,6 @@ D973B402158ABC1F0083A4B5 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D973B401158ABC1F0083A4B5 /* MessageUI.framework */; }; D98254A815990D8D0060CA47 /* Icon_2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D98254A615990D8D0060CA47 /* Icon_2x.png */; }; D98254A915990D8D0060CA47 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = D98254A715990D8D0060CA47 /* Icon.png */; }; - D98254F2159937730060CA47 /* GTLPlusPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = D98254F1159937730060CA47 /* GTLPlusPerson.m */; }; D9EE743D158A8BD400EC1D05 /* google_plus_share_large.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7435158A8BD400EC1D05 /* google_plus_share_large.png */; }; D9EE743E158A8BD400EC1D05 /* google_plus_share_large@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7436158A8BD400EC1D05 /* google_plus_share_large@2x.png */; }; D9EE743F158A8BD400EC1D05 /* google_plus_share.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7437158A8BD400EC1D05 /* google_plus_share.png */; }; @@ -79,14 +78,13 @@ 00F70E98158007D90077799E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 00F70E9A158008040077799E /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 0C52D6F7158BAB1F001510E6 /* button_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background.png; path = Resources/button_background.png; sourceTree = SOURCE_ROOT; }; + 294FD685163B67F500A9D5CA /* GPPDeepLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPPDeepLink.h; path = ../lib/GPPDeepLink.h; sourceTree = ""; }; D973B401158ABC1F0083A4B5 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; D98254A615990D8D0060CA47 /* Icon_2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_2x.png; path = Resources/Icon_2x.png; sourceTree = SOURCE_ROOT; }; D98254A715990D8D0060CA47 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icon.png; sourceTree = SOURCE_ROOT; }; - D98254F0159937730060CA47 /* GTLPlusPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusPerson.h; sourceTree = ""; }; - D98254F1159937730060CA47 /* GTLPlusPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusPerson.m; sourceTree = ""; }; - D9EE7431158A8BAE00EC1D05 /* GooglePlusShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusShare.h; path = ../lib/GooglePlusShare.h; sourceTree = ""; }; - D9EE7432158A8BAE00EC1D05 /* GooglePlusSignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusSignIn.h; path = ../lib/GooglePlusSignIn.h; sourceTree = ""; }; - D9EE7433158A8BAE00EC1D05 /* GooglePlusSignInButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusSignInButton.h; path = ../lib/GooglePlusSignInButton.h; sourceTree = ""; }; + D9EE7431158A8BAE00EC1D05 /* GPPShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPPShare.h; path = ../lib/GPPShare.h; sourceTree = ""; }; + D9EE7432158A8BAE00EC1D05 /* GPPSignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPPSignIn.h; path = ../lib/GPPSignIn.h; sourceTree = ""; }; + D9EE7433158A8BAE00EC1D05 /* GPPSignInButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPPSignInButton.h; path = ../lib/GPPSignInButton.h; sourceTree = ""; }; D9EE7435158A8BD400EC1D05 /* google_plus_share_large.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_share_large.png; path = ../Resources/google_plus_share_large.png; sourceTree = ""; }; D9EE7436158A8BD400EC1D05 /* google_plus_share_large@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "google_plus_share_large@2x.png"; path = "../Resources/google_plus_share_large@2x.png"; sourceTree = ""; }; D9EE7437158A8BD400EC1D05 /* google_plus_share.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_share.png; path = ../Resources/google_plus_share.png; sourceTree = ""; }; @@ -279,9 +277,10 @@ D9EE7434158A8BB500EC1D05 /* GooglePlusSDK */ = { isa = PBXGroup; children = ( - D9EE7431158A8BAE00EC1D05 /* GooglePlusShare.h */, - D9EE7432158A8BAE00EC1D05 /* GooglePlusSignIn.h */, - D9EE7433158A8BAE00EC1D05 /* GooglePlusSignInButton.h */, + D9EE7431158A8BAE00EC1D05 /* GPPShare.h */, + 294FD685163B67F500A9D5CA /* GPPDeepLink.h */, + D9EE7432158A8BAE00EC1D05 /* GPPSignIn.h */, + D9EE7433158A8BAE00EC1D05 /* GPPSignInButton.h */, D9EE74AD158A8D1E00EC1D05 /* libGooglePlus.a */, D9EE74AE158A8D1E00EC1D05 /* libGooglePlusUniversal.a */, D9EE7445158A8BDB00EC1D05 /* Resources */, @@ -386,8 +385,6 @@ D9EE745E158A8C0E00EC1D05 /* GTLPlusItemScope.m */, D9EE745F158A8C0E00EC1D05 /* GTLPlusMoment.h */, D9EE7460158A8C0E00EC1D05 /* GTLPlusMoment.m */, - D98254F0159937730060CA47 /* GTLPlusPerson.h */, - D98254F1159937730060CA47 /* GTLPlusPerson.m */, D9EE7463158A8C0E00EC1D05 /* GTLQueryPlus.h */, D9EE7464158A8C0E00EC1D05 /* GTLQueryPlus.m */, D9EE7465158A8C0E00EC1D05 /* GTLServicePlus.h */, @@ -510,7 +507,6 @@ D9EE74C5158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m in Sources */, D9EE74C7158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m in Sources */, D9EE74C9158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m in Sources */, - D98254F2159937730060CA47 /* GTLPlusPerson.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.xcworkspace/xcuserdata/xiangtian.xcuserdatad/UserInterfaceState.xcuserstate b/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.xcworkspace/xcuserdata/xiangtian.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index c4253c19..00000000 Binary files a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.xcworkspace/xcuserdata/xiangtian.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/GooglePlusSample.xcscheme b/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/GooglePlusSample.xcscheme deleted file mode 100644 index da367a26..00000000 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/GooglePlusSample.xcscheme +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/xcschememanagement.plist b/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index b6fa4a06..00000000 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/xcuserdata/xiangtian.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - GooglePlusSample.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - 0043C7991580045B000DF02E - - primary - - - - - diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.h b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.h index 7da9a72a..6bde1282 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.h +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.h @@ -18,8 +18,8 @@ #import -@class GooglePlusShare; -@class GooglePlusSignInButton; +@class GPPShare; +@class GPPSignInButton; @class GTMOAuth2Authentication; @interface GooglePlusSampleAppDelegate : UIResponder @@ -29,11 +29,14 @@ // The navigation controller. @property (retain, nonatomic) UINavigationController *navigationController; // The Google+ sign-in button to handle the URL redirect. -@property (retain, nonatomic) GooglePlusSignInButton *signInButton; +@property (retain, nonatomic) GPPSignInButton *signInButton; // The OAuth 2.0 authentication used in the application. @property (retain, nonatomic) GTMOAuth2Authentication *auth; // The Google+ share object to handle the URL redirect. -@property (retain, nonatomic) GooglePlusShare *share; +@property (retain, nonatomic) GPPShare *share; +// Whether or not to use Google+ history's +// https://www.googleapis.com/auth/plus.moments.write scope. +@property (assign, nonatomic) BOOL plusMomentsWriteScope; // The OAuth 2.0 client ID to be used for Google+ sign-in, share, and moments. + (NSString *)clientID; diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.m b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.m index f4024ad1..e79023b5 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.m +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.m @@ -19,8 +19,9 @@ #import "GooglePlusSampleAppDelegate.h" #import "GooglePlusSampleMasterViewController.h" -#import "GooglePlusSignIn.h" -#import "GooglePlusSignInButton.h" +#import "GPPDeepLink.h" +#import "GPPSignIn.h" +#import "GPPSignInButton.h" @implementation GooglePlusSampleAppDelegate @@ -29,11 +30,12 @@ @synthesize signInButton = signInButton_; @synthesize auth = auth_; @synthesize share = share_; +@synthesize plusMomentsWriteScope = plusMomentsWriteScope_; // DO NOT USE THIS CLIENT ID. IT WILL NOT WORK FOR YOUR APP. // Please use the client ID created for you by Google. -static NSString * const kClientID = @"571459971810-" - @"2bpoda566pap5kkc0aqljqfjki8tgeb6.apps.googleusercontent.com"; +static NSString * const kClientID = + @"122385832599-2mcvobo565un3ab7d6d06m6fjemocto9.apps.googleusercontent.com"; + (NSString *)clientID { return kClientID; @@ -52,6 +54,8 @@ static NSString * const kClientID = @"571459971810-" - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + plusMomentsWriteScope_ = YES; + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; GooglePlusSampleMasterViewController *masterViewController = @@ -63,6 +67,18 @@ static NSString * const kClientID = @"571459971810-" initWithRootViewController:masterViewController] autorelease]; self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; + + // Read Google+ deep-link data. + GPPDeepLink *deepLink = [GPPDeepLink readDeepLinkAfterInstall]; + if (deepLink) { + UIAlertView *alert = [[[UIAlertView alloc] + initWithTitle:@"Read Deep-link Data" + message:[deepLink deepLinkID] + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil] autorelease]; + [alert show]; + } return YES; } @@ -83,6 +99,20 @@ static NSString * const kClientID = @"571459971810-" annotation:annotation]) { return YES; } + + // Handle Google+ deep-link data URL. + GPPDeepLink *deepLink = [GPPDeepLink handleURL:url + sourceApplication:sourceApplication + annotation:annotation]; + if (deepLink) { + UIAlertView *alert = [[[UIAlertView alloc] + initWithTitle:@"Handle Deep-link Data" + message:[deepLink deepLinkID] + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil] autorelease]; + [alert show]; + } return NO; } diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.m b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.m index b15ab22a..1c34ee65 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.m +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.m @@ -18,6 +18,7 @@ #import "GooglePlusSampleMasterViewController.h" +#import "GooglePlusSampleAppDelegate.h" #import "GooglePlusSampleShareViewController.h" #import "GooglePlusSampleSignInViewController.h" #import "GooglePlusSampleMomentsViewController.h" @@ -25,10 +26,19 @@ static const int kNumViewControllers = 3; static NSString * const kMenuOptions[kNumViewControllers] = { @"Sign In", @"Share", @"Moments" }; +static NSString * const kUnselectableMenuOptions[kNumViewControllers] = { + @"", @"", @"Sign in to use moments" }; static NSString * const kNibNames[kNumViewControllers] = { @"GooglePlusSampleSignInViewController", @"GooglePlusSampleShareViewController", @"GooglePlusSampleMomentsViewController" }; +static const int kMomentsIndex = 2; + +@interface GooglePlusSampleMasterViewController () { + NSIndexPath *momentsIndexPath_; +} +- (BOOL)isSelectable:(NSIndexPath *)indexPath; +@end @implementation GooglePlusSampleMasterViewController @@ -47,6 +57,11 @@ static NSString * const kNibNames[kNumViewControllers] = { return self; } +- (void)dealloc { + [momentsIndexPath_ release]; + [super dealloc]; +} + #pragma mark - View lifecycle - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) @@ -58,6 +73,15 @@ static NSString * const kNibNames[kNumViewControllers] = { return YES; } +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + if (momentsIndexPath_) { + [self.tableView + reloadRowsAtIndexPaths:[NSArray arrayWithObject:momentsIndexPath_] + withRowAnimation:UITableViewRowAnimationFade]; + } +} + #pragma mark - UITableViewDelegate/UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -71,22 +95,32 @@ static NSString * const kNibNames[kNumViewControllers] = { - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString * const kCellIdentifier = @"Cell"; + BOOL selectable = [self isSelectable:indexPath]; + NSString * const kCellIdentifier = selectable ? @"Cell" : @"GreyCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + if (selectable) { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } else { + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.textColor = [UIColor lightGrayColor]; + } } + cell.textLabel.text = (selectable ? kMenuOptions : kUnselectableMenuOptions) + [indexPath.row]; - cell.textLabel.text = kMenuOptions[indexPath.row]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (![self isSelectable:indexPath]) { + return; + } Class nibClass = NSClassFromString(kNibNames[indexPath.row]); UIViewController *controller = [[[nibClass alloc] initWithNibName:nil bundle:nil] autorelease]; @@ -95,4 +129,19 @@ static NSString * const kNibNames[kNumViewControllers] = { [self.navigationController pushViewController:controller animated:YES]; } +#pragma mark - Helper methods + +- (BOOL)isSelectable:(NSIndexPath *)indexPath { + if (indexPath.row == kMomentsIndex) { + if (!momentsIndexPath_) { + momentsIndexPath_ = [indexPath retain]; + } + // To use Google+ History API, you need to sign in. + GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) + [[UIApplication sharedApplication] delegate]; + return appDelegate.auth && appDelegate.plusMomentsWriteScope; + } + return YES; +} + @end diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.m b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.m index d4a5172f..64d3e0fd 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.m +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.m @@ -19,6 +19,7 @@ #import "GooglePlusSampleMomentsViewController.h" #import +#import "GooglePlusSampleAppDelegate.h" #import "GTLPlus.h" #import "GTLPlusConstants.h" #import "GTLPlusItemScope.h" @@ -27,7 +28,6 @@ #import "GTLServicePlus.h" #import "GTMLogger.h" #import "GTMOAuth2Authentication.h" -#import "GooglePlusSampleAppDelegate.h" @interface GooglePlusSampleMomentsViewController () - (GTLPlusItemScope *)resultFor:(NSString *)selectedMoment; @@ -162,7 +162,7 @@ static NSString * const kMomentURLFormat = NSString *selectedMoment = kMomentTypes[selectedRow]; GTLPlusMoment *moment = [[[GTLPlusMoment alloc] init] autorelease]; - moment.type = [NSString stringWithFormat:@"https://schemas.google.com/%@", + moment.type = [NSString stringWithFormat:@"http://schemas.google.com/%@", selectedMoment]; GTLPlusItemScope *target = [[[GTLPlusItemScope alloc] init] autorelease]; target.url = momentURL_.text; @@ -258,8 +258,8 @@ static NSString * const kMomentURLFormat = GTLPlusItemScope *result = [[[GTLPlusItemScope alloc] init] autorelease]; if ([selectedMoment isEqualToString:@"CommentActivity"]) { result.type = @"http://schema.org/Comment"; - result.url = - @"https://developers.google.com/+/plugins/snippet/examples/blog-entry#comment-1"; + result.url = @"https://developers.google.com/+/plugins/snippet/" + @"examples/blog-entry#comment-1"; result.name = @"This is amazing!"; result.text = @"I can't wait to use it on my site :)"; return result; @@ -272,16 +272,15 @@ static NSString * const kMomentURLFormat = result.type = @"http://schema.org/Review"; result.name = @"A Humble Review of Widget"; result.url = - @"https://developers.google.com/+/plugins/snippet/examples/review"; + @"https://developers.google.com/+/plugins/snippet/examples/review"; result.text = - @"It's amazingly effective at whatever it is that it's supposed to do."; + @"It's amazingly effective at whatever it is that it's supposed to do."; GTLPlusItemScope *rating = [[[GTLPlusItemScope alloc] init] autorelease]; rating.type = @"http://schema.org/Rating"; rating.ratingValue = @"100"; rating.bestRating = @"100"; rating.worstRating = @"0"; - result.reviewRating = - [[[NSArray alloc] initWithObjects:rating, nil] autorelease]; + result.reviewRating = rating; return result; } return nil; diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.h b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.h index 3feca972..0ead54ba 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.h +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.h @@ -19,18 +19,22 @@ #import #import #import -#import "GooglePlusShare.h" +#import "GPPShare.h" // A view controller for the Google+ share dialog which contains a text field // to prefill the user comment, and a text field for an optional URL to share. // A Google+ share button is provided to launch the share dialog. @interface GooglePlusSampleShareViewController : UIViewController< - GooglePlusShareDelegate, + GPPShareDelegate, UITextFieldDelegate, UIActionSheetDelegate, MFMailComposeViewControllerDelegate> { // The Google+ share object to manage the share dialog. - GooglePlusShare *share_; + GPPShare *share_; + // Whether the keyboard is visible or not. + BOOL keyboardVisible_; + // The text field being edited. + UITextField *activeField_; } // The text to prefill the user comment in the share dialog. @@ -41,7 +45,36 @@ @property (retain, nonatomic) IBOutlet UILabel *shareStatus; // A toolbar to share via Google+ or email. @property (retain, nonatomic) IBOutlet UIToolbar *shareToolbar; +// A switch to toggle Google+ share with deep linking. +@property (retain, nonatomic) IBOutlet UISwitch *attachDeepLinkSwitch; +// The deep-link ID to be attached with the Google+ share to qualify as +// a deep-link share. +@property (retain, nonatomic) IBOutlet UITextField *deepLinkID; +// The share's title. +@property (retain, nonatomic) IBOutlet UITextField *deepLinkTitle; +// The share's description. +@property (retain, nonatomic) IBOutlet UITextField *deepLinkDescription; +// The share's thumbnail URL. +@property (retain, nonatomic) IBOutlet UITextField *deepLinkThumbnailURL; +// The share view. +@property (retain, nonatomic) IBOutlet UIScrollView *shareScrollView; +@property (retain, nonatomic) IBOutlet UIView *shareView; +// Labels for Google+ share sample. +@property (retain, nonatomic) IBOutlet UILabel *attachDeepLinkDataLabel; +@property (retain, nonatomic) IBOutlet UILabel *urlToShareLabel; +@property (retain, nonatomic) IBOutlet UILabel *prefillTextLabel; +@property (retain, nonatomic) IBOutlet UILabel *deepLinkIDLabel; +@property (retain, nonatomic) IBOutlet UILabel *deepLinkTitleLabel; +@property (retain, nonatomic) IBOutlet UILabel *deepLinkDescriptionLabel; +@property (retain, nonatomic) IBOutlet UILabel *deepLinkThumbnailURLLabel; +@property (retain, nonatomic) IBOutlet UIButton *shareButton; +@property (retain, nonatomic) IBOutlet UISwitch *urlForDeepLinkMetadataSwitch; +@property (retain, nonatomic) IBOutlet UILabel *urlForDeepLinkMetadataLabel; +// Called when the switch for deep-link data is toggled. +- (IBAction)deepLinkSwitchToggle:(id)sender; +// Called when the switch for metadata from URL preview is toggled. +- (IBAction)urlForDeepLinkMetadataSwitchToggle:(id)sender; // Called when the share button is pressed. - (IBAction)shareButton:(id)sender; // Called when the toolbar share button is pressed. diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.m b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.m index 2e93562e..ab2f4782 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.m +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.m @@ -20,19 +20,61 @@ #import "GooglePlusSampleAppDelegate.h" +@interface GooglePlusSampleShareViewController() +- (void)animateKeyboard:(NSNotification *)notification + shouldShow:(BOOL)shouldShow; +- (void)layout; +- (void)placeView:(UIView *)view x:(CGFloat)x y:(CGFloat)y; +- (void)populateTextFields; +@end + @implementation GooglePlusSampleShareViewController +@synthesize attachDeepLinkSwitch = attachDeepLinkSwitch_; +@synthesize deepLinkDescription = deepLinkDescription_; +@synthesize deepLinkID = deepLinkID_; +@synthesize deepLinkTitle = deepLinkTitle_; +@synthesize deepLinkThumbnailURL = deepLinkThumbnailURL_; @synthesize sharePrefillText = sharePrefillText_; @synthesize shareURL = shareURL_; @synthesize shareStatus = shareStatus_; @synthesize shareToolbar = shareToolbar_; +@synthesize shareScrollView = shareScrollView_; +@synthesize shareView = shareView_; +@synthesize attachDeepLinkDataLabel = attachDeepLinkDataLabel_; +@synthesize urlToShareLabel = urlToShareLabel_; +@synthesize prefillTextLabel = prefillTextLabel_; +@synthesize deepLinkIDLabel = deepLinkIDLabel_; +@synthesize deepLinkTitleLabel = deepLinkTitleLabel_; +@synthesize deepLinkDescriptionLabel = deepLinkDescriptionLabel_; +@synthesize deepLinkThumbnailURLLabel = deepLinkThumbnailURLLabel_; +@synthesize shareButton = shareButton_; +@synthesize urlForDeepLinkMetadataSwitch = urlForDeepLinkMetadataSwitch_; +@synthesize urlForDeepLinkMetadataLabel = urlForDeepLinkMetadataLabel_; - (void)dealloc { + [attachDeepLinkSwitch_ release]; + [deepLinkID_ release]; + [deepLinkTitle_ release]; + [deepLinkDescription_ release]; + [deepLinkThumbnailURL_ release]; [sharePrefillText_ release]; [shareURL_ release]; [shareStatus_ release]; [share_ release]; [shareToolbar_ release]; + [shareScrollView_ release]; + [shareView_ release]; + [attachDeepLinkDataLabel_ release]; + [urlToShareLabel_ release]; + [prefillTextLabel_ release]; + [deepLinkIDLabel_ release]; + [deepLinkTitleLabel_ release]; + [deepLinkDescriptionLabel_ release]; + [deepLinkThumbnailURLLabel_ release]; + [shareButton_ release]; + [urlForDeepLinkMetadataSwitch_ release]; + [urlForDeepLinkMetadataLabel_ release]; [super dealloc]; } @@ -43,10 +85,14 @@ GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) [[UIApplication sharedApplication] delegate]; NSString *clientID = [GooglePlusSampleAppDelegate clientID]; - share_ = [[GooglePlusShare alloc] initWithClientID:clientID]; + share_ = [[GPPShare alloc] initWithClientID:clientID]; share_.delegate = self; appDelegate.share = share_; + [attachDeepLinkSwitch_ setOn:NO]; + + [self layout]; + [self populateTextFields]; [super viewDidLoad]; } @@ -57,10 +103,69 @@ share_.delegate = nil; [share_ release]; share_ = nil; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; + [self setAttachDeepLinkSwitch:nil]; + [self setDeepLinkID:nil]; + [self setDeepLinkTitle:nil]; + [self setDeepLinkDescription:nil]; + [self setDeepLinkThumbnailURL:nil]; + [self setShareScrollView:nil]; + [self setShareView:nil]; + [self setShareToolbar:nil]; + [self setAttachDeepLinkDataLabel:nil]; + [self setUrlToShareLabel:nil]; + [self setPrefillTextLabel:nil]; + [self setDeepLinkIDLabel:nil]; + [self setDeepLinkTitleLabel:nil]; + [self setDeepLinkDescriptionLabel:nil]; + [self setDeepLinkThumbnailURLLabel:nil]; + [self setShareButton:nil]; + [self setUrlForDeepLinkMetadataSwitch:nil]; + [self setUrlForDeepLinkMetadataLabel:nil]; [super viewDidUnload]; } +- (void)viewWillAppear:(BOOL)animated { + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){ + shareScrollView_.frame = self.view.frame; + } + [super viewWillAppear:animated]; + + // Register for keyboard notifications while visible. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + // Unregister for keyboard notifications while not visible. + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; + + [super viewWillDisappear:animated]; +} + #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { @@ -68,7 +173,15 @@ return YES; } -#pragma mark - GooglePlusShareDelegate +- (void)textFieldDidBeginEditing:(UITextField *)textField { + activeField_ = textField; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + activeField_ = nil; +} + +#pragma mark - GPPShareDelegate - (void)finishedSharing:(BOOL)shared { NSString *text = shared ? @"Success" : @"Canceled"; @@ -120,15 +233,49 @@ [self dismissModalViewControllerAnimated:YES]; } +#pragma mark - UIKeyboard + +- (void)keyboardWillShow:(NSNotification *)notification { + [self animateKeyboard:notification shouldShow:YES]; +} + +- (void)keyboardWillHide:(NSNotification *)notification { + [self animateKeyboard:notification shouldShow:NO]; +} + #pragma mark - IBActions - (IBAction)shareButton:(id)sender { + shareStatus_.text = @"Status: Sharing..."; + id shareBuilder = [share_ shareDialog]; + NSString *inputURL = shareURL_.text; NSURL *urlToShare = [inputURL length] ? [NSURL URLWithString:inputURL] : nil; + if (urlToShare) { + shareBuilder = [shareBuilder setURLToShare:urlToShare]; + } + + if ([deepLinkID_ text]) { + shareBuilder = [shareBuilder setContentDeepLinkID:[deepLinkID_ text]]; + NSString *title = [deepLinkTitle_ text]; + NSString *description = [deepLinkDescription_ text]; + if (title && description) { + NSURL *thumbnailURL = [NSURL URLWithString:[deepLinkThumbnailURL_ text]]; + shareBuilder = [shareBuilder setTitle:title + description:description + thumbnailURL:thumbnailURL]; + } + } + NSString *inputText = sharePrefillText_.text; NSString *text = [inputText length] ? inputText : nil; - shareStatus_.text = @"Status: Sharing..."; - [[[[share_ shareDialog] setURLToShare:urlToShare] setPrefillText:text] open]; + if (text) { + shareBuilder = [shareBuilder setPrefillText:text]; + } + + if (![shareBuilder open]) { + shareStatus_.text = @"Status: Error (see console)."; + } } - (IBAction)shareToolbar:(id)sender { @@ -142,4 +289,210 @@ [actionSheet showFromToolbar:shareToolbar_]; } +- (IBAction)urlForDeepLinkMetadataSwitchToggle:(id)sender { + [self layout]; + [self populateTextFields]; +} + +- (IBAction)deepLinkSwitchToggle:(id)sender { + if (!attachDeepLinkSwitch_.on) { + [urlForDeepLinkMetadataSwitch_ setOn:YES]; + } + [self layout]; + [self populateTextFields]; +} + +#pragma mark - helper methods + +- (void) placeView:(UIView *)view x:(CGFloat)x y:(CGFloat)y { + CGSize frameSize = view.frame.size; + view.frame = CGRectMake(x, y, frameSize.width, frameSize.height); +} + +- (void) layout { + CGFloat originX = 20.0; + CGFloat originY = 20.0; + CGFloat yPadding = 20.0; + CGFloat currentY = originY; + CGFloat middleX = 150; + + // Place the switch for attaching deep-link data. + [self placeView:attachDeepLinkDataLabel_ x:originX y:currentY]; + [self placeView:attachDeepLinkSwitch_ x:middleX + 50 y:currentY]; + CGSize frameSize = attachDeepLinkSwitch_.frame.size; + currentY += frameSize.height + yPadding; + + // Place the switch for preview URL. + if (attachDeepLinkSwitch_.on) { + [self placeView:urlForDeepLinkMetadataLabel_ x:originX y:currentY]; + [self placeView:urlForDeepLinkMetadataSwitch_ x:middleX + 50 y:currentY]; + frameSize = urlForDeepLinkMetadataSwitch_.frame.size; + currentY += frameSize.height + yPadding; + urlForDeepLinkMetadataSwitch_.hidden = NO; + urlForDeepLinkMetadataLabel_.hidden = NO; + } else { + urlForDeepLinkMetadataSwitch_.hidden = YES; + urlForDeepLinkMetadataLabel_.hidden = YES; + } + + // Place the field for URL to share. + if (urlForDeepLinkMetadataSwitch_.on) { + [self placeView:urlToShareLabel_ x:originX y:currentY]; + frameSize = urlToShareLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + + [self placeView:shareURL_ x:originX y:currentY]; + frameSize = shareURL_.frame.size; + currentY += frameSize.height + yPadding; + urlToShareLabel_.hidden = NO; + shareURL_.hidden = NO; + } else { + urlToShareLabel_.hidden = YES; + shareURL_.hidden = YES; + } + + // Place the field for prefill text. + [self placeView:prefillTextLabel_ x:originX y:currentY]; + frameSize = prefillTextLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + [self placeView:sharePrefillText_ x:originX y:currentY]; + frameSize = sharePrefillText_.frame.size; + currentY += frameSize.height + yPadding; + + // Place the content deep-link ID field. + if (attachDeepLinkSwitch_.on) { + [self placeView:deepLinkIDLabel_ x:originX y:currentY]; + frameSize = deepLinkIDLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + [self placeView:deepLinkID_ x:originX y:currentY]; + frameSize = deepLinkID_.frame.size; + currentY += frameSize.height + yPadding; + deepLinkIDLabel_.hidden = NO; + deepLinkID_.hidden = NO; + } else { + deepLinkIDLabel_.hidden = YES; + deepLinkID_.hidden = YES; + } + + // Place fields for content deep-link metadata. + if (attachDeepLinkSwitch_.on && !urlForDeepLinkMetadataSwitch_.on) { + [self placeView:deepLinkTitleLabel_ x:originX y:currentY]; + frameSize = deepLinkTitleLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + [self placeView:deepLinkTitle_ x:originX y:currentY]; + frameSize = deepLinkTitle_.frame.size; + currentY += frameSize.height + yPadding; + + [self placeView:deepLinkDescriptionLabel_ x:originX y:currentY]; + frameSize = deepLinkDescriptionLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + [self placeView:deepLinkDescription_ x:originX y:currentY]; + frameSize = deepLinkDescription_.frame.size; + currentY += frameSize.height + yPadding; + + [self placeView:deepLinkThumbnailURLLabel_ x:originX y:currentY]; + frameSize = deepLinkThumbnailURLLabel_.frame.size; + currentY += frameSize.height + 0.5 * yPadding; + [self placeView:deepLinkThumbnailURL_ x:originX y:currentY]; + frameSize = deepLinkThumbnailURL_.frame.size; + currentY += frameSize.height + yPadding; + + deepLinkTitle_.hidden = NO; + deepLinkTitleLabel_.hidden = NO; + deepLinkDescriptionLabel_.hidden = NO; + deepLinkDescription_.hidden = NO; + deepLinkThumbnailURLLabel_.hidden = NO; + deepLinkThumbnailURL_.hidden = NO; + } else { + deepLinkTitle_.hidden = YES; + deepLinkTitleLabel_.hidden = YES; + deepLinkDescriptionLabel_.hidden = YES; + deepLinkDescription_.hidden = YES; + deepLinkThumbnailURLLabel_.hidden = YES; + deepLinkThumbnailURL_.hidden = YES; + } + + // Place the share button and status. + [self placeView:shareButton_ x:originX y:currentY]; + frameSize = shareButton_.frame.size; + currentY += frameSize.height + yPadding; + + [self placeView:shareStatus_ x:originX y:currentY]; + frameSize = shareStatus_.frame.size; + currentY += frameSize.height + yPadding; + + shareScrollView_.contentSize = + CGSizeMake(shareScrollView_.frame.size.width, currentY); +} + +- (void)populateTextFields { + // Pre-populate text fields for Google+ share sample. + if (sharePrefillText_.hidden) { + sharePrefillText_.text = @""; + } else { + sharePrefillText_.text = @"Welcome to Google+ Platform"; + } + + if (shareURL_.hidden) { + shareURL_.text = @""; + } else { + shareURL_.text = @"http://developers.google.com"; + } + + if (deepLinkID_.hidden) { + deepLinkID_.text = @""; + } else { + deepLinkID_.text = @"reviews/314159265358"; + } + + if (deepLinkTitle_.hidden) { + deepLinkTitle_.text = @""; + } else { + deepLinkTitle_.text = @"Joe's Diner Review"; + } + + if (deepLinkDescription_.hidden) { + deepLinkDescription_.text = @""; + } else { + deepLinkDescription_.text = @"Check out my review of the awesome toast!"; + } + + if (deepLinkThumbnailURL_.hidden) { + deepLinkThumbnailURL_.text = @""; + } else { + deepLinkThumbnailURL_.text = + @"http://www.google.com/logos/2012/childrensday-2012-hp.jpg"; + } +} + +- (void)animateKeyboard:(NSNotification *)notification + shouldShow:(BOOL)shouldShow { + if (!shouldShow) { + UIEdgeInsets contentInsets = UIEdgeInsetsZero; + shareScrollView_.contentInset = contentInsets; + shareScrollView_.scrollIndicatorInsets = contentInsets; + return; + } + + NSDictionary *userInfo = [notification userInfo]; + CGRect kbFrame = + [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + CGSize kbSize = kbFrame.size; + UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); + shareScrollView_.contentInset = contentInsets; + shareScrollView_.scrollIndicatorInsets = contentInsets; + + // If active text field is hidden by keyboard, scroll so it's visible. + CGRect aRect = self.view.frame; + aRect.size.height -= kbSize.height; + CGPoint bottomLeft = + CGPointMake(0.0, activeField_.frame.origin.y + + activeField_.frame.size.height + 10); + if (!CGRectContainsPoint(aRect, bottomLeft)) { + CGPoint scrollPoint = CGPointMake(0.0, bottomLeft.y - aRect.size.height); + [shareScrollView_ setContentOffset:scrollPoint animated:YES]; + } + return; +} + @end diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.xib b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.xib index de51b338..b9118564 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.xib +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.xib @@ -1,23 +1,25 @@ - 1280 - 10K549 - 1938 - 1038.36 - 461.00 + 1296 + 12C60 + 2549 + 1187.34 + 625.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 + 1498 - IBUIView IBProxyObject - IBUILabel - IBUIToolbar IBUIBarButtonItem - IBUITextField IBUIButton + IBUILabel + IBUIScrollView + IBUISwitch + IBUITextField + IBUIToolbar + IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -39,173 +41,453 @@ 274 - + - 292 - {{20, 55}, {280, 31}} - - - - NO - YES - IBCocoaTouchFramework - 0 - http://developers.google.com/ - 3 - - 3 - MAA - - 2 + 268 + + + + 292 + {{26, 126}, {280, 31}} + + + + NO + YES + IBCocoaTouchFramework + 0 + http://developers.google.com/ + 3 + + 3 + MAA + + 2 + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + 1 + 14 + + + Helvetica + 14 + 16 + - - YES - 17 - - IBCocoaTouchFramework - - - 1 - 14 - - - Helvetica - 14 - 16 - - - - - 292 - {{20, 144}, {280, 31}} + + + 292 + {{26, 89}, {179, 21}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + URL to share (optional) + + 1 + MCAwIDAAA + + + 1 + 10 + + 1 + 17 + + + Helvetica + 17 + 16 + + + + + 292 + {{31, 255}, {112, 32}} + + + + NO + IBCocoaTouchFramework + 0 + 0 + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + NSImage + google_plus_share_large.png + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 292 + {{26, 165}, {156, 21}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + Prefill text (optional) + + + 1 + 10 + + + + + + 290 + {{38, 306}, {268, 21}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + Status: + + + 1 + 15 + + + + + + 292 + {{194, 31}, {94, 27}} + + + + NO + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{20, 31}, {172, 21}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + Attach deep-link data + + + 1 + 10 + + + + + + 292 + {{26, 198}, {280, 31}} + + + + NO + YES + IBCocoaTouchFramework + 0 + Welcome to Google+ Platform + 3 + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + + + + + 292 + {{26, 247}, {280, 30}} + + + + _NS:9 + NO + YES + IBCocoaTouchFramework + 0 + + 3 + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + + + + + 292 + {{26, 292}, {246, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Content deep-link ID (required) + + + 0 + + + NO + + + + 292 + {{26, 335}, {171, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Title (required) + + + 0 + + + NO + + + + 292 + {{26, 402}, {280, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Description (required) + + + 0 + + + NO + + + + 292 + {{24, 469}, {194, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Thumbnail URL (optional) + + + 0 + + + NO + + + + 292 + {{26, 431}, {280, 30}} + + + + _NS:9 + NO + YES + IBCocoaTouchFramework + 0 + + 3 + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + + + + + 292 + {{26, 498}, {280, 30}} + + + + _NS:9 + NO + YES + IBCocoaTouchFramework + 0 + + 3 + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + + + + + 292 + {{26, 364}, {280, 30}} + + + + _NS:9 + NO + YES + IBCocoaTouchFramework + 0 + + 3 + + 3 + MAA + + + YES + 17 + + IBCocoaTouchFramework + + 3 + + + + + + 292 + {{194, 66}, {94, 27}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{20, 66}, {172, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Use URL for preview + + + 0 + + + NO + + + {320, 372} - - NO + + _NS:9 YES + YES IBCocoaTouchFramework - 0 - Welcome to Google+ Platform - 3 - - 3 - MAA - - - YES - 17 - - IBCocoaTouchFramework - - - - - - - 292 - {{20, 26}, {179, 21}} - - - - NO - YES - 7 - NO - IBCocoaTouchFramework - URL to Share (optional) - - 1 - MCAwIDAAA - - - 1 - 10 - - 1 - 17 - - - Helvetica - 17 - 16 - - - - - 292 - {{20, 115}, {156, 21}} - - - - NO - YES - 7 - NO - IBCocoaTouchFramework - Prefill Text (optional) - - - 1 - 10 - - - - - - 292 - {{21, 209}, {112, 32}} - - - - NO - IBCocoaTouchFramework - 0 - 0 - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - NSImage - google_plus_share_large.png - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - - 290 - {{20, 283}, {280, 21}} - - - - NO - YES - 7 - NO - IBCocoaTouchFramework - Status: - - - 1 - 15 - - @@ -213,7 +495,6 @@ {{0, 372}, {320, 44}} - NO NO IBCocoaTouchFramework @@ -235,7 +516,7 @@ {{0, 64}, {320, 416}} - + 3 MQA @@ -258,6 +539,70 @@ 3 + + + shareView + + + + 42 + + + + shareToolbar + + + + 43 + + + + deepLinkThumbnailURLLabel + + + + 58 + + + + attachDeepLinkDataLabel + + + + 52 + + + + shareButton + + + + 59 + + + + deepLinkTitle + + + + 49 + + + + urlToShareLabel + + + + 53 + + + + deepLinkDescriptionLabel + + + + 57 + sharePrefillText @@ -266,6 +611,70 @@ 11 + + + deepLinkTitleLabel + + + + 56 + + + + urlForDeepLinkMetadataLabel + + + + 64 + + + + deepLinkThumbnailURL + + + + 51 + + + + shareURL + + + + 21 + + + + deepLinkDescription + + + + 50 + + + + prefillTextLabel + + + + 54 + + + + attachDeepLinkSwitch + + + + 28 + + + + shareScrollView + + + + 41 + shareStatus @@ -276,19 +685,27 @@ - shareToolbar + deepLinkIDLabel - + - 19 + 55 - shareURL + urlForDeepLinkMetadataSwitch - + - 21 + 62 + + + + deepLinkID + + + + 48 @@ -323,6 +740,56 @@ 20 + + + deepLinkSwitchToggle: + + + 13 + + 31 + + + + delegate + + + + 44 + + + + delegate + + + + 46 + + + + delegate + + + + 47 + + + + delegate + + + + 45 + + + + urlForDeepLinkMetadataSwitchToggle: + + + 13 + + 63 + @@ -336,13 +803,8 @@ 1 - - - - - - + @@ -357,36 +819,6 @@ - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 13 - - - 15 @@ -406,6 +838,121 @@ + + 32 + + + + + + + + + + + + + + + + + + + + + + + + + 6 + + + + + 8 + + + + + 5 + + + + + 39 + + + + + 37 + + + + + 38 + + + + + 36 + + + + + 40 + + + + + 9 + + + + + 13 + + + + + 26 + + + + + 29 + + + + + 7 + + + + + 34 + + + + + 35 + + + + + 60 + + + + + 61 + + + + + 33 + + + @@ -418,8 +965,23 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -428,7 +990,7 @@ - 23 + 64 @@ -436,10 +998,16 @@ GooglePlusSampleShareViewController UIViewController + id id id + id + + deepLinkSwitchToggle: + id + shareButton: id @@ -448,18 +1016,91 @@ shareToolbar: id + + urlForDeepLinkMetadataSwitchToggle: + id + + UILabel + UISwitch + UITextField + UILabel + UITextField + UILabel + UITextField + UILabel + UITextField + UILabel + UILabel + UIButton UITextField + UIScrollView UILabel UIToolbar UITextField + UIView + UILabel + UISwitch + UILabel + + attachDeepLinkDataLabel + UILabel + + + attachDeepLinkSwitch + UISwitch + + + deepLinkDescription + UITextField + + + deepLinkDescriptionLabel + UILabel + + + deepLinkID + UITextField + + + deepLinkIDLabel + UILabel + + + deepLinkThumbnailURL + UITextField + + + deepLinkThumbnailURLLabel + UILabel + + + deepLinkTitle + UITextField + + + deepLinkTitleLabel + UILabel + + + prefillTextLabel + UILabel + + + shareButton + UIButton + sharePrefillText UITextField + + shareScrollView + UIScrollView + shareStatus UILabel @@ -472,6 +1113,22 @@ shareURL UITextField + + shareView + UIView + + + urlForDeepLinkMetadataLabel + UILabel + + + urlForDeepLinkMetadataSwitch + UISwitch + + + urlToShareLabel + UILabel + IBProjectSource @@ -482,12 +1139,16 @@ 0 IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + YES 3 google_plus_share_large.png {112, 32} - 933 + 1498 diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.h b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.h index 942fbb75..cd6a4c41 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.h +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.h @@ -1,5 +1,5 @@ // -// GooglePlusSignInViewController.h +// GooglePlusSampleSignInViewController.h // // Copyright 2012 Google Inc. // @@ -17,24 +17,39 @@ // #import -#import "GooglePlusSignIn.h" +#import "GPPSignIn.h" -@class GooglePlusSignInButton; +@class GPPSignInButton; // A view controller for the Google+ sign-in button which initiates a standard // OAuth 2.0 flow and provides an access token and a refresh token. A "Sign out" // button is provided to allow users to sign out of this application. @interface GooglePlusSampleSignInViewController : UIViewController< - GooglePlusSignInDelegate> + GPPSignInDelegate> // The button that handles Google+ sign-in. -@property (retain, nonatomic) IBOutlet GooglePlusSignInButton *signInButton; +@property (retain, nonatomic) IBOutlet GPPSignInButton *signInButton; // A label to display the result of the sign-in action. @property (retain, nonatomic) IBOutlet UILabel *signInAuthStatus; +// A label to display the signed-in user's display name. +@property (retain, nonatomic) IBOutlet UILabel *signInDisplayName; // A button to sign out of this application. @property (retain, nonatomic) IBOutlet UIButton *signOutButton; +// A switch for whether to request for Google+ History's +// https://www.googleapis.com/auth/plus.moments.write scope. +@property (retain, nonatomic) IBOutlet UISwitch *plusMomentsWriteScope; +// A switch for whether to request +// https://www.googleapis.com/auth/userinfo.email scope to get user's email +// address after the sign-in action. +@property (retain, nonatomic) IBOutlet UISwitch *userinfoEmailScope; // Called when the user presses the "Sign out" button. - (IBAction)signOut:(id)sender; +// Called when the user toggles Google+ History's +// https://www.googleapis.com/auth/plus.moments.write scope. +- (IBAction)plusMomentsWriteScopeToggle:(id)sender; +// Called when the user toggles the +// https://www.googleapis.com/auth/userinfo.email scope. +- (IBAction)userinfoEmailScopeToggle:(id)sender; @end diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.m b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.m index a9e78412..5d95cdcd 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.m +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.m @@ -1,5 +1,5 @@ // -// GooglePlusSignInViewController.m +// GooglePlusSampleSignInViewController.m // // Copyright 2012 Google Inc. // @@ -20,36 +20,50 @@ #import #import "GooglePlusSampleAppDelegate.h" -#import "GooglePlusSignIn.h" -#import "GooglePlusSignInButton.h" +#import "GPPSignIn.h" +#import "GPPSignInButton.h" +#import "GTLPlus.h" +#import "GTLPlusConstants.h" +#import "GTLQueryPlus.h" +#import "GTLServicePlus.h" +#import "GTMLogger.h" +#import "GTMOAuth2Authentication.h" + +@interface GooglePlusSampleSignInViewController () { + // Saved state of |userinfoEmailScope_.on|. + BOOL savedUserinfoEmailScopeState_; +} +- (GooglePlusSampleAppDelegate *)appDelegate; +- (void)setSignInScopes; +- (void)enableSignInSettings:(BOOL)enable; +- (void)reportAuthStatus; +- (void)retrieveUserInfo; +@end @implementation GooglePlusSampleSignInViewController @synthesize signInButton = signInButton_; @synthesize signInAuthStatus = signInAuthStatus_; +@synthesize signInDisplayName = signInDisplayName_; @synthesize signOutButton = signOutButton_; +@synthesize plusMomentsWriteScope = plusMomentsWriteScope_; +@synthesize userinfoEmailScope = userinfoEmailScope_; - (void)dealloc { [signInButton_ release]; [signInAuthStatus_ release]; + [signInDisplayName_ release]; [signOutButton_ release]; [super dealloc]; } #pragma mark - View lifecycle -- (void)reportAuthStatus { - GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) - [[UIApplication sharedApplication] delegate]; - if (appDelegate.auth) { - signInAuthStatus_.text = @"Status: Authenticated"; - } else { - // To authenticate, use Google+ sign-in button. - signInAuthStatus_.text = @"Status: Not authenticated"; - } -} - - (void)viewDidLoad { + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; + plusMomentsWriteScope_.on = appDelegate.plusMomentsWriteScope; + userinfoEmailScope_.on = savedUserinfoEmailScopeState_; + // Set up sign-out button. [[signOutButton_ layer] setCornerRadius:5]; [[signOutButton_ layer] setMasksToBounds:YES]; @@ -60,27 +74,28 @@ // Set up sample view of Google+ sign-in. signInButton_.delegate = self; + signInButton_.shouldFetchGoogleUserEmail = userinfoEmailScope_.on; signInButton_.clientID = [GooglePlusSampleAppDelegate clientID]; - signInButton_.scope = [NSArray arrayWithObjects: - @"https://www.googleapis.com/auth/plus.moments.write", - @"https://www.googleapis.com/auth/plus.me", - nil]; + [self setSignInScopes]; - GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) - [[UIApplication sharedApplication] delegate]; appDelegate.signInButton = signInButton_; [self reportAuthStatus]; [super viewDidLoad]; } +- (void)viewWillDisappear:(BOOL)animated { + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; + appDelegate.plusMomentsWriteScope = plusMomentsWriteScope_.on; + savedUserinfoEmailScopeState_ = userinfoEmailScope_.on; +} + - (void)viewDidUnload { - GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) - [[UIApplication sharedApplication] delegate]; + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; appDelegate.signInButton = nil; [super viewDidUnload]; } -#pragma mark - GooglePlusSignInDelegate +#pragma mark - GPPSignInDelegate - (void)finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error { @@ -89,22 +104,78 @@ [NSString stringWithFormat:@"Status: Authentication error: %@", error]; return; } - GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) - [[UIApplication sharedApplication] delegate]; + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; appDelegate.auth = auth; [self reportAuthStatus]; } +#pragma mark - Helper methods + +- (GooglePlusSampleAppDelegate *)appDelegate { + return (GooglePlusSampleAppDelegate *) + [[UIApplication sharedApplication] delegate]; +} + +- (void)setSignInScopes { + signInButton_.scope = plusMomentsWriteScope_.on ? + [NSArray arrayWithObjects: + @"https://www.googleapis.com/auth/plus.moments.write", + @"https://www.googleapis.com/auth/plus.me", + nil] : + [NSArray arrayWithObjects: + @"https://www.googleapis.com/auth/plus.me", + nil]; +} + +- (void)enableSignInSettings:(BOOL)enable { + plusMomentsWriteScope_.enabled = enable; + userinfoEmailScope_.enabled = enable && !plusMomentsWriteScope_.on; +} + +- (void)reportAuthStatus { + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; + if (appDelegate.auth) { + signInAuthStatus_.text = @"Status: Authenticated"; + [self retrieveUserInfo]; + [self enableSignInSettings:NO]; + } else { + // To authenticate, use Google+ sign-in button. + signInAuthStatus_.text = @"Status: Not authenticated"; + [self enableSignInSettings:YES]; + } +} + +- (void)retrieveUserInfo { + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; + if (appDelegate.auth.userEmail) { + signInDisplayName_.text = appDelegate.auth.userEmail; + } else { + signInDisplayName_.text = @""; + } +} + #pragma mark - IBActions - (IBAction)signOut:(id)sender { [[signInButton_ googlePlusSignIn] signOut]; - GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *) - [[UIApplication sharedApplication] delegate]; + GooglePlusSampleAppDelegate *appDelegate = [self appDelegate]; appDelegate.auth = nil; [self reportAuthStatus]; + signInDisplayName_.text = @""; +} + +- (IBAction)plusMomentsWriteScopeToggle:(id)sender { + [self setSignInScopes]; + userinfoEmailScope_.enabled = !plusMomentsWriteScope_.on; + if (plusMomentsWriteScope_.on) { + userinfoEmailScope_.on = NO; + } +} + +- (IBAction)userinfoEmailScopeToggle:(id)sender { + signInButton_.shouldFetchGoogleUserEmail = userinfoEmailScope_.on; } @end diff --git a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.xib b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.xib index e4e828f7..d5f869d5 100644 --- a/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.xib +++ b/External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.xib @@ -1,20 +1,21 @@ - 1280 - 10K549 - 1938 - 1038.36 - 461.00 + 1536 + 12C54 + 2843 + 1187.34 + 625.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 + 1929 - IBUIButton - IBUIView - IBUILabel IBProxyObject + IBUIButton + IBUILabel + IBUISwitch + IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -39,7 +40,7 @@ 292 - {{19, 93}, {119, 35}} + {{19, 218}, {119, 35}} @@ -77,7 +78,7 @@ 292 - {{18, 34}, {118, 32}} + {{18, 159}, {118, 32}} @@ -93,33 +94,144 @@ 290 - {{20, 163}, {280, 21}} + {{20, 288}, {280, 21}} - + NO YES 7 NO IBCocoaTouchFramework Status: - + 1 MCAwIDAAA + darkTextColor 1 13 - + 1 17 - + Helvetica 17 16 + + + 290 + {{20, 317}, {280, 21}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + + + + 1 + 13 + + + + + + 292 + {{191, 99}, {94, 27}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{18, 20}, {273, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Scopes setting (sign out to change) + + + 0 + + + NO + + + + 292 + {{20, 99}, {177, 27}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + plus.moments.write + + + 0 + + + NO + + + + 292 + {{19, 58}, {178, 27}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + userinfo.email + + + 0 + + + NO + + + + 292 + {{191, 58}, {94, 27}} + + + _NS:9 + NO + IBCocoaTouchFramework + NO + 0 + 0 + {{0, 20}, {320, 460}} @@ -168,6 +280,30 @@ 24 + + + signInDisplayName + + + + 28 + + + + plusMomentsWriteScope + + + + 35 + + + + userinfoEmailScope + + + + 39 + signOut: @@ -177,6 +313,24 @@ 26 + + + plusMomentsWriteScopeToggle: + + + 13 + + 36 + + + + userinfoEmailScopeToggle: + + + 13 + + 40 + @@ -193,6 +347,12 @@ + + + + + + @@ -222,6 +382,36 @@ + + 27 + + + + + 29 + + + + + 30 + + + + + 34 + + + + + 37 + + + + + 38 + + + @@ -231,26 +421,108 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - GooglePlusSignInButton + GPPSignInButton com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 26 + 40 + + + + + GPPSignInButton + UIView + + IBProjectSource + ./Classes/GPPSignInButton.h + + + + GooglePlusSampleSignInViewController + UIViewController + + id + id + id + + + + plusMomentsWriteScopeToggle: + id + + + signOut: + id + + + userinfoEmailScopeToggle: + id + + + + UISwitch + UILabel + GPPSignInButton + UILabel + UIButton + UISwitch + + + + plusMomentsWriteScope + UISwitch + + + signInAuthStatus + UILabel + + + signInButton + GPPSignInButton + + + signInDisplayName + UILabel + + + signOutButton + UIButton + + + userinfoEmailScope + UISwitch + + + + IBProjectSource + ./Classes/GooglePlusSampleSignInViewController.h + + + - 0 IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + YES 3 button_background.png {1, 1} - 933 + 1929 diff --git a/External/google-plus-ios-sdk/lib/GPPDeepLink.h b/External/google-plus-ios-sdk/lib/GPPDeepLink.h new file mode 100644 index 00000000..b8174b94 --- /dev/null +++ b/External/google-plus-ios-sdk/lib/GPPDeepLink.h @@ -0,0 +1,39 @@ +// +// GPPDeepLink.h +// Google+ iOS SDK +// +// Copyright 2012 Google Inc. +// +// Usage of this SDK is subject to the Google+ Platform Terms of Service: +// https://developers.google.com/+/terms +// + +#import + +@interface GPPDeepLink : NSObject + +// Returns a |GPPDeepLink| for your app to handle, or |nil| if not found. The +// deep-link ID can be obtained from |GPPDeepLink|. It is stored when a user +// clicks a link to your app from a Google+ post, but hasn't yet installed your +// app. The user will be redirected to the App Store to install your app. This +// method should be called on or near your app launch to take the user to +// deep-link ID within your app. ++ (GPPDeepLink *)readDeepLinkAfterInstall; + +// This method should be called from your |UIApplicationDelegate|'s +// |application:openURL:sourceApplication:annotation|. Returns +// |GooglePlusDeepLink| if |GooglePlusDeepLink| handled this URL, |nil| +// otherwise. ++ (GPPDeepLink *)handleURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation; + +// The deep-link ID in |GPPDeepLink| that was passed to the app. +- (NSString *)deepLinkID; + +// This indicates where the user came from before arriving in your app. This is +// provided for you to collect engagement metrics. For the possible values, +// see our developer docs at http://developers.google.com/+/mobile/ios/. +- (NSString *)source; + +@end diff --git a/External/google-plus-ios-sdk/lib/GooglePlusShare.h b/External/google-plus-ios-sdk/lib/GPPShare.h similarity index 63% rename from External/google-plus-ios-sdk/lib/GooglePlusShare.h rename to External/google-plus-ios-sdk/lib/GPPShare.h index 90fe2ae9..37f2fca9 100644 --- a/External/google-plus-ios-sdk/lib/GooglePlusShare.h +++ b/External/google-plus-ios-sdk/lib/GPPShare.h @@ -1,5 +1,5 @@ // -// GooglePlusShare.h +// GPPShare.h // Google+ iOS SDK // // Copyright 2012 Google Inc. @@ -15,14 +15,13 @@ // client ID as "Installed application" with the type "iOS", and // register the bundle ID of your application. // -// 1. Initialize a GooglePlusShare instance with your registered client ID: +// 1. Initialize a GPPShare instance with your registered client ID: // -// GooglePlusShare *googlePlusShare = -// [[GooglePlusShare alloc] initWithClientID:myClientID]; +// GPPShare *gppShare = [[GPPShare alloc] initWithClientID:myClientID]; // // 2. In the code where the share dialog is to be opened: // -// [[googlePlusShare shareDialog] open]; +// [[gppShare shareDialog] open]; // // You may optionally call |setURLToShare:| and/or |setPrefillText:| before // calling |open|, if there is a particular URL resource to be shared, or @@ -30,7 +29,7 @@ // // NSURL *urlToShare = [NSURL URLWithString:@"http://www.google.com/"]; // NSString *prefillText = @"You probably already know this site..."; -// [[[[googlePlusShare shareDialog] setURLToShare:urlToShare] +// [[[[gppShare shareDialog] setURLToShare:urlToShare] // setPrefillText:prefillText] open]; // // 3. In the 'YourApp-info.plist' settings for your application, add a URL @@ -42,30 +41,30 @@ // openURL:(NSURL *)url // sourceApplication:(NSString*)sourceApplication // annotation:(id)annotation { -// if ([googlePlusShare handleURL:url -// sourceApplication:sourceApplication -// annotation:annotation]) { +// if ([gppShare handleURL:url +// sourceApplication:sourceApplication +// annotation:annotation]) { // return YES; // } // // Other handling code here... // } // // 5. Optionally, if you want to be notified of the result of the share action, -// have a delegate class implement |GooglePlusShareDelegate|, e.g. +// have a delegate class implement |GPPShareDelegate|, e.g. // -// @interface MyDelegateClass : NSObject; +// @interface MyDelegateClass : NSObject; // // - (void)finishedSharing:(BOOL)shared { // // The share action was successful if |shared| is YES. // } // // MyDelegateClass *myDelegate = [[MyDelegateClass alloc] init]; -// googlePlusShare.delegate = myDelegate; +// gppShare.delegate = myDelegate; #import // Protocol to receive the result of the share action. -@protocol GooglePlusShareDelegate +@protocol GPPShareDelegate // Reports the status of the share action, |shared| is |YES| if user has // successfully shared her post, |NO| otherwise, e.g. user canceled the post. @@ -74,24 +73,38 @@ @end // The builder protocol to open the share dialog. -@protocol GooglePlusShareBuilder +@protocol GPPShareBuilder // Sets the URL resource to be shared. -- (id)setURLToShare:(NSURL *)urlToShare; +- (id)setURLToShare:(NSURL *)urlToShare; // Sets the text to prefill user comment in the share dialog. -- (id)setPrefillText:(NSString *)prefillText; +- (id)setPrefillText:(NSString *)prefillText; -// Opens the share dialog. -- (void)open; +// Sets the title, description, and thumbnail URL of the shared content preview +// in the share dialog. Only set these fields if you are sharing with a content +// deep link and don't have a URL resource. Title and description are required +// fields. +- (id)setTitle:(NSString *)title + description:(NSString *)description + thumbnailURL:(NSURL *)thumbnailURL; + +// Sets the content deep-link ID that takes the user straight to your shared +// content. Only set this field if you want the content deep-linking feature. +// The content deep-link ID can either be a fully qualified URI, or URI path, +// which can be up to 64 characters in length. +- (id)setContentDeepLinkID:(NSString *)contentDeepLinkID; + +// Opens the share dialog. Returns |NO| if there was an error, |YES| otherwise. +- (BOOL)open; @end // The primary class for the share action on Google+. -@interface GooglePlusShare : NSObject +@interface GPPShare : NSObject // The object to be notified when the share action has finished. -@property (nonatomic, assign) id delegate; +@property (nonatomic, assign) id delegate; // All Google+ objects must be initialized with a client ID registered // in the Google APIs console, https://code.google.com/apis/console/ @@ -100,11 +113,11 @@ // Returns a share dialog builder instance. Call its |open| method to // create the dialog after setting the parameters as needed. -- (id)shareDialog; +- (id)shareDialog; // This method should be called from your |UIApplicationDelegate|'s // |application:openURL:sourceApplication:annotation|. Returns |YES| if -// |GooglePlusShare| handled this URL. +// |GPPShare| handled this URL. - (BOOL)handleURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; diff --git a/External/google-plus-ios-sdk/lib/GooglePlusSignIn.h b/External/google-plus-ios-sdk/lib/GPPSignIn.h similarity index 76% rename from External/google-plus-ios-sdk/lib/GooglePlusSignIn.h rename to External/google-plus-ios-sdk/lib/GPPSignIn.h index d68edc67..10507e6f 100644 --- a/External/google-plus-ios-sdk/lib/GooglePlusSignIn.h +++ b/External/google-plus-ios-sdk/lib/GPPSignIn.h @@ -1,5 +1,5 @@ // -// GooglePlusSignIn.h +// GPPSignIn.h // Google+ iOS SDK // // Copyright 2012 Google Inc. @@ -13,10 +13,10 @@ @class GTMOAuth2Authentication; @class GTMOAuth2ViewControllerTouch; -// Protocol implemented by the client of GooglePlusSignIn to receive a refresh +// Protocol implemented by the client of GPPSignIn to receive a refresh // token or an error. It is up to the client to present the OAuth 2.0 view // controller if single sign-on is disabled via |attemptSSO| in |authenticate|. -@protocol GooglePlusSignInDelegate +@protocol GPPSignInDelegate // Authorization has finished and is successful if |error| is |nil|. - (void)finishedWithAuth:(GTMOAuth2Authentication *)auth @@ -24,11 +24,11 @@ @end -// |GooglePlusSignIn| signs the user in with Google+. It provides single sign-on +// |GPPSignIn| signs the user in with Google+. It provides single sign-on // via the Google+ app, if installed, or Mobile Safari. -// Here is sample code to use GooglePlusSignIn: -// 1) GooglePlusSignIn *signIn = -// [[GooglePlusSignIn alloc] initForClientID:clientID +// Here is sample code to use GPPSignIn: +// 1) GPPSignIn *signIn = +// [[GPPSignIn alloc] initForClientID:clientID // language:@"en" // scope:@"https://www.googleapis.com/auth/plus.me" // keychainName:nil]; @@ -36,10 +36,14 @@ // 2) Setup delegate methods |finishedWithAuth|, etc. // 3) Call |handleURL| from |application:openUrl:...| in your app delegate. // 4) [auth authenticate:YES]; -@interface GooglePlusSignIn : NSObject +@interface GPPSignIn : NSObject // The object to be notified when authentication is finished. -@property (nonatomic, assign) id delegate; +@property (nonatomic, assign) id delegate; + +// Whether or not to fetch user email after signing in. The email is saved in +// the |GTMOAuth2Authentication| object. +@property (nonatomic, assign) BOOL shouldFetchGoogleUserEmail; // Initializes with your |clientID| from the Google APIs console. Set |scope| to // an array of your API scopes. Set |keychainName| to |nil| to use the default @@ -56,7 +60,7 @@ // This method should be called from your |UIApplicationDelegate|'s // |application:openURL:sourceApplication:annotation|. Returns |YES| if -// |GooglePlusSignIn| handled this URL. +// |GPPSignIn| handled this URL. - (BOOL)handleURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; diff --git a/External/google-plus-ios-sdk/lib/GooglePlusSignInButton.h b/External/google-plus-ios-sdk/lib/GPPSignInButton.h similarity index 63% rename from External/google-plus-ios-sdk/lib/GooglePlusSignInButton.h rename to External/google-plus-ios-sdk/lib/GPPSignInButton.h index b73f8c83..aa2719e2 100644 --- a/External/google-plus-ios-sdk/lib/GooglePlusSignInButton.h +++ b/External/google-plus-ios-sdk/lib/GPPSignInButton.h @@ -1,5 +1,5 @@ // -// GooglePlusSignInButton.h +// GPPSignInButton.h // Google+ iOS SDK // // Copyright 2012 Google Inc. @@ -10,41 +10,45 @@ #import -@class GooglePlusSignIn; -@protocol GooglePlusSignInDelegate; +@class GPPSignIn; +@protocol GPPSignInDelegate; -// The various visual styles supported by the GooglePlusSignInButton. +// The various visual styles supported by the GPPSignInButton. typedef enum { - kGooglePlusSignInButtonStyleNormal, - kGooglePlusSignInButtonStyleWide -} GooglePlusSignInButtonStyle; + kGPPSignInButtonStyleNormal, + kGPPSignInButtonStyleWide +} GPPSignInButtonStyle; // A view that displays the Google+ sign-in button. You can instantiate this // class programmatically or from a NIB file. Once instantiated, you should // set the client ID and delegate properties and add this view to your own view // hierarchy. -@interface GooglePlusSignInButton : UIView +@interface GPPSignInButton : UIView // The OAuth 2.0 client ID of the application. @property(nonatomic, copy) NSString *clientID; -// See GooglePlusSignIn.h for details on this delegate. -@property(nonatomic, assign) id delegate; +// See GPPSignIn.h for details on this delegate. +@property(nonatomic, assign) id delegate; // Actually does the work of signing in with Google+. -@property(nonatomic, readonly) GooglePlusSignIn *googlePlusSignIn; +@property(nonatomic, readonly) GPPSignIn *googlePlusSignIn; // The OAuth 2.0 scopes for the APIs that you are using. This is used to fetch // an OAuth 2.0 token. By default, this is set to the // https://www.googleapis.com/auth/plus.me scope. @property(nonatomic, copy) NSArray *scope; +// Whether or not to fetch user email after signing in. The email is saved in +// the |GTMOAuth2Authentication| object. +@property (nonatomic, assign) BOOL shouldFetchGoogleUserEmail; + // Sets the sign-in button. The default style is normal. -- (void)setStyle:(GooglePlusSignInButtonStyle)style; +- (void)setStyle:(GPPSignInButtonStyle)style; // This method should be called from your |UIApplicationDelegate|'s // |application:openURL:sourceApplication:annotation|. Returns |YES| if -// |GooglePlusSignInButton| handled this URL. +// |GPPSignInButton| handled this URL. - (BOOL)handleURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; diff --git a/External/google-plus-ios-sdk/lib/libGooglePlus.a b/External/google-plus-ios-sdk/lib/libGooglePlus.a index 1824ec72..f4ebc720 100644 Binary files a/External/google-plus-ios-sdk/lib/libGooglePlus.a and b/External/google-plus-ios-sdk/lib/libGooglePlus.a differ diff --git a/External/google-plus-ios-sdk/lib/libGooglePlusUniversal.a b/External/google-plus-ios-sdk/lib/libGooglePlusUniversal.a index 47d4862b..f6f5ab81 100644 Binary files a/External/google-plus-ios-sdk/lib/libGooglePlusUniversal.a and b/External/google-plus-ios-sdk/lib/libGooglePlusUniversal.a differ diff --git a/Google+/Google+.plist b/Google+/Google+.plist new file mode 100644 index 00000000..2bd16346 --- /dev/null +++ b/Google+/Google+.plist @@ -0,0 +1,8 @@ + + + + + ClientID + + + diff --git a/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword-iOS.xcodeproj/project.pbxproj index d396c6c9..65db9bb8 100644 --- a/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -55,39 +55,7 @@ DA46826F15AB843200FB09E7 /* tip_basic_black_bottom_right.png in Resources */ = {isa = PBXBuildFile; fileRef = DA46826D15AB843200FB09E7 /* tip_basic_black_bottom_right.png */; }; DA46827015AB843200FB09E7 /* tip_basic_black_bottom_right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA46826E15AB843200FB09E7 /* tip_basic_black_bottom_right@2x.png */; }; DA497B9815E8C90E00B52167 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; - DA497BED15E8C94300B52167 /* GTLBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BA915E8C94300B52167 /* GTLBase64.m */; }; - DA497BEE15E8C94300B52167 /* GTLBatchQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BAB15E8C94300B52167 /* GTLBatchQuery.m */; }; - DA497BEF15E8C94300B52167 /* GTLBatchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BAD15E8C94300B52167 /* GTLBatchResult.m */; }; - DA497BF015E8C94300B52167 /* GTLDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BAF15E8C94300B52167 /* GTLDateTime.m */; }; - DA497BF115E8C94300B52167 /* GTLErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BB215E8C94300B52167 /* GTLErrorObject.m */; }; - DA497BF215E8C94300B52167 /* GTLFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BB415E8C94300B52167 /* GTLFramework.m */; }; - DA497BF315E8C94300B52167 /* GTLJSONParser.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BB615E8C94300B52167 /* GTLJSONParser.m */; }; - DA497BF415E8C94300B52167 /* GTLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BB815E8C94300B52167 /* GTLObject.m */; }; - DA497BF515E8C94300B52167 /* GTLPlusConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BBC15E8C94300B52167 /* GTLPlusConstants.m */; }; - DA497BF615E8C94300B52167 /* GTLPlusItemScope.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BBE15E8C94300B52167 /* GTLPlusItemScope.m */; }; - DA497BF715E8C94300B52167 /* GTLPlusMoment.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BC015E8C94300B52167 /* GTLPlusMoment.m */; }; - DA497BF815E8C94300B52167 /* GTLPlusPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BC215E8C94300B52167 /* GTLPlusPerson.m */; }; - DA497BF915E8C94300B52167 /* GTLQueryPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BC415E8C94300B52167 /* GTLQueryPlus.m */; }; - DA497BFA15E8C94300B52167 /* GTLServicePlus.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BC615E8C94300B52167 /* GTLServicePlus.m */; }; - DA497BFB15E8C94300B52167 /* GTLQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BC815E8C94300B52167 /* GTLQuery.m */; }; - DA497BFC15E8C94300B52167 /* GTLRuntimeCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BCA15E8C94300B52167 /* GTLRuntimeCommon.m */; }; - DA497BFD15E8C94300B52167 /* GTLService.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BCC15E8C94300B52167 /* GTLService.m */; }; - DA497BFE15E8C94300B52167 /* GTLUploadParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BCF15E8C94300B52167 /* GTLUploadParameters.m */; }; - DA497BFF15E8C94300B52167 /* GTLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BD115E8C94300B52167 /* GTLUtilities.m */; }; - DA497C0015E8C94300B52167 /* GTMHTTPFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BD515E8C94300B52167 /* GTMHTTPFetcher.m */; }; - DA497C0115E8C94300B52167 /* GTMHTTPFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BD715E8C94300B52167 /* GTMHTTPFetcherLogging.m */; }; - DA497C0215E8C94300B52167 /* GTMHTTPFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BD915E8C94300B52167 /* GTMHTTPFetcherService.m */; }; - DA497C0315E8C94300B52167 /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BDB15E8C94300B52167 /* GTMHTTPFetchHistory.m */; }; - DA497C0415E8C94300B52167 /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BDD15E8C94300B52167 /* GTMLogger.m */; }; - DA497C0515E8C94300B52167 /* GTMMethodCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BDF15E8C94300B52167 /* GTMMethodCheck.m */; }; - DA497C0615E8C94300B52167 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BE115E8C94300B52167 /* GTMNSDictionary+URLArguments.m */; }; - DA497C0715E8C94300B52167 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BE315E8C94300B52167 /* GTMNSString+URLArguments.m */; }; - DA497C0815E8C94300B52167 /* GTMOAuth2Authentication.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BE515E8C94300B52167 /* GTMOAuth2Authentication.m */; }; - DA497C0915E8C94300B52167 /* GTMOAuth2SignIn.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BE715E8C94300B52167 /* GTMOAuth2SignIn.m */; }; - DA497C0A15E8C94300B52167 /* GTMOAuth2ViewControllerTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BE915E8C94300B52167 /* GTMOAuth2ViewControllerTouch.m */; }; - DA497C0B15E8C94300B52167 /* GTMObjC2Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = DA497BEC15E8C94300B52167 /* GTMObjC2Runtime.m */; }; DA497C0C15E8C95700B52167 /* libGoogle+.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA497B9715E8C90E00B52167 /* libGoogle+.a */; }; - DA497C0F15E8C9CF00B52167 /* libGooglePlusUniversal.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5587FC15E8B7B200860B4F /* libGooglePlusUniversal.a */; }; DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6326C148680650075AEA5 /* libjrswizzle.a */; }; DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */; }; DA4DA1DB1564475E00F6F596 /* libscryptenc-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA79A9BB1557DB6F00BAA07A /* libscryptenc-ios.a */; }; @@ -102,14 +70,6 @@ DA5587F015E83C3200860B4F /* social-twitter@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5587EA15E83C3200860B4F /* social-twitter@2x.png */; }; DA5587F415E8418200860B4F /* iTunesArtwork-Rounded-73@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5587F115E8418200860B4F /* iTunesArtwork-Rounded-73@2x.png */; }; DA5587F615E8418200860B4F /* iTunesArtwork-Rounded.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5587F315E8418200860B4F /* iTunesArtwork-Rounded.png */; }; - DA55888415E8C0BA00860B4F /* google_plus_share.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55887C15E8C0BA00860B4F /* google_plus_share.png */; }; - DA55888515E8C0BA00860B4F /* google_plus_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55887D15E8C0BA00860B4F /* google_plus_share@2x.png */; }; - DA55888615E8C0BA00860B4F /* google_plus_share_large.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55887E15E8C0BA00860B4F /* google_plus_share_large.png */; }; - DA55888715E8C0BA00860B4F /* google_plus_share_large@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55887F15E8C0BA00860B4F /* google_plus_share_large@2x.png */; }; - DA55888815E8C0BA00860B4F /* google_plus_sign_in.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55888015E8C0BA00860B4F /* google_plus_sign_in.png */; }; - DA55888915E8C0BA00860B4F /* google_plus_sign_in@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55888115E8C0BA00860B4F /* google_plus_sign_in@2x.png */; }; - DA55888A15E8C0BA00860B4F /* google_plus_sign_in_wide.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55888215E8C0BA00860B4F /* google_plus_sign_in_wide.png */; }; - DA55888B15E8C0BA00860B4F /* google_plus_sign_in_wide@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA55888315E8C0BA00860B4F /* google_plus_sign_in_wide@2x.png */; }; DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA48147E415C00F98B1E /* UIKit.framework */; }; DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4C147E415C00F98B1E /* CoreGraphics.framework */; }; @@ -134,6 +94,39 @@ DA6701E016406BB400B61001 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA6701DF16406BB400B61001 /* AdSupport.framework */; settings = {ATTRIBUTES = (Required, ); }; }; DA672D2F14F92C6B004A189C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA672D2E14F92C6B004A189C /* libz.dylib */; }; DA672D3014F9413D004A189C /* libPearl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC77CAD148291A600BCF976 /* libPearl.a */; }; + DA692D9E16BB057500F14463 /* libGooglePlus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA692D5716BB057500F14463 /* libGooglePlus.a */; }; + DA692D9F16BB057500F14463 /* libGooglePlusUniversal.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA692D5816BB057500F14463 /* libGooglePlusUniversal.a */; }; + DA692DA016BB057500F14463 /* GTLBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D5C16BB057500F14463 /* GTLBase64.m */; }; + DA692DA116BB057500F14463 /* GTLBatchQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D5E16BB057500F14463 /* GTLBatchQuery.m */; }; + DA692DA216BB057500F14463 /* GTLBatchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6016BB057500F14463 /* GTLBatchResult.m */; }; + DA692DA316BB057500F14463 /* GTLDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6216BB057500F14463 /* GTLDateTime.m */; }; + DA692DA416BB057500F14463 /* GTLErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6516BB057500F14463 /* GTLErrorObject.m */; }; + DA692DA516BB057500F14463 /* GTLFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6716BB057500F14463 /* GTLFramework.m */; }; + DA692DA616BB057500F14463 /* GTLJSONParser.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6916BB057500F14463 /* GTLJSONParser.m */; }; + DA692DA716BB057500F14463 /* GTLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6B16BB057500F14463 /* GTLObject.m */; }; + DA692DA816BB057500F14463 /* GTLPlusConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D6F16BB057500F14463 /* GTLPlusConstants.m */; }; + DA692DA916BB057500F14463 /* GTLPlusItemScope.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7116BB057500F14463 /* GTLPlusItemScope.m */; }; + DA692DAA16BB057500F14463 /* GTLPlusMoment.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7316BB057500F14463 /* GTLPlusMoment.m */; }; + DA692DAB16BB057500F14463 /* GTLQueryPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7516BB057500F14463 /* GTLQueryPlus.m */; }; + DA692DAC16BB057500F14463 /* GTLServicePlus.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7716BB057500F14463 /* GTLServicePlus.m */; }; + DA692DAD16BB057500F14463 /* GTLQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7916BB057500F14463 /* GTLQuery.m */; }; + DA692DAE16BB057500F14463 /* GTLRuntimeCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7B16BB057500F14463 /* GTLRuntimeCommon.m */; }; + DA692DAF16BB057500F14463 /* GTLService.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D7D16BB057500F14463 /* GTLService.m */; }; + DA692DB016BB057500F14463 /* GTLUploadParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8016BB057500F14463 /* GTLUploadParameters.m */; }; + DA692DB116BB057500F14463 /* GTLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8216BB057500F14463 /* GTLUtilities.m */; }; + DA692DB216BB057500F14463 /* GTMHTTPFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8616BB057500F14463 /* GTMHTTPFetcher.m */; }; + DA692DB316BB057500F14463 /* GTMHTTPFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8816BB057500F14463 /* GTMHTTPFetcherLogging.m */; }; + DA692DB416BB057500F14463 /* GTMHTTPFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8A16BB057500F14463 /* GTMHTTPFetcherService.m */; }; + DA692DB516BB057500F14463 /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8C16BB057500F14463 /* GTMHTTPFetchHistory.m */; }; + DA692DB616BB057500F14463 /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D8E16BB057500F14463 /* GTMLogger.m */; }; + DA692DB716BB057500F14463 /* GTMMethodCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9016BB057500F14463 /* GTMMethodCheck.m */; }; + DA692DB816BB057500F14463 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9216BB057500F14463 /* GTMNSDictionary+URLArguments.m */; }; + DA692DB916BB057500F14463 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9416BB057500F14463 /* GTMNSString+URLArguments.m */; }; + DA692DBA16BB057500F14463 /* GTMOAuth2Authentication.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9616BB057500F14463 /* GTMOAuth2Authentication.m */; }; + DA692DBB16BB057500F14463 /* GTMOAuth2SignIn.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9816BB057500F14463 /* GTMOAuth2SignIn.m */; }; + DA692DBC16BB057500F14463 /* GTMOAuth2ViewControllerTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9A16BB057500F14463 /* GTMOAuth2ViewControllerTouch.m */; }; + DA692DBD16BB057500F14463 /* GTMObjC2Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = DA692D9D16BB057500F14463 /* GTMObjC2Runtime.m */; }; + DA692DBF16BB191100F14463 /* Google+.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA692DBE16BB191100F14463 /* Google+.plist */; }; DA81253516B8546A00F4732F /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA81253416B8546A00F4732F /* MPElementEntity.m */; }; DA81253816B8546B00F4732F /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA81253716B8546B00F4732F /* MPElementStoredEntity.m */; }; DA81253B16B8546B00F4732F /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA81253A16B8546B00F4732F /* MPUserEntity.m */; }; @@ -1043,74 +1036,6 @@ DA46826D15AB843200FB09E7 /* tip_basic_black_bottom_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tip_basic_black_bottom_right.png; sourceTree = ""; }; DA46826E15AB843200FB09E7 /* tip_basic_black_bottom_right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tip_basic_black_bottom_right@2x.png"; sourceTree = ""; }; DA497B9715E8C90E00B52167 /* libGoogle+.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libGoogle+.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - DA497BA815E8C94300B52167 /* GTLBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBase64.h; sourceTree = ""; }; - DA497BA915E8C94300B52167 /* GTLBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBase64.m; sourceTree = ""; }; - DA497BAA15E8C94300B52167 /* GTLBatchQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchQuery.h; sourceTree = ""; }; - DA497BAB15E8C94300B52167 /* GTLBatchQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchQuery.m; sourceTree = ""; }; - DA497BAC15E8C94300B52167 /* GTLBatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchResult.h; sourceTree = ""; }; - DA497BAD15E8C94300B52167 /* GTLBatchResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchResult.m; sourceTree = ""; }; - DA497BAE15E8C94300B52167 /* GTLDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDateTime.h; sourceTree = ""; }; - DA497BAF15E8C94300B52167 /* GTLDateTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLDateTime.m; sourceTree = ""; }; - DA497BB015E8C94300B52167 /* GTLDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDefines.h; sourceTree = ""; }; - DA497BB115E8C94300B52167 /* GTLErrorObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLErrorObject.h; sourceTree = ""; }; - DA497BB215E8C94300B52167 /* GTLErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLErrorObject.m; sourceTree = ""; }; - DA497BB315E8C94300B52167 /* GTLFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLFramework.h; sourceTree = ""; }; - DA497BB415E8C94300B52167 /* GTLFramework.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLFramework.m; sourceTree = ""; }; - DA497BB515E8C94300B52167 /* GTLJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLJSONParser.h; sourceTree = ""; }; - DA497BB615E8C94300B52167 /* GTLJSONParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLJSONParser.m; sourceTree = ""; }; - DA497BB715E8C94300B52167 /* GTLObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLObject.h; sourceTree = ""; }; - DA497BB815E8C94300B52167 /* GTLObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLObject.m; sourceTree = ""; }; - DA497BBA15E8C94300B52167 /* GTLPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlus.h; sourceTree = ""; }; - DA497BBB15E8C94300B52167 /* GTLPlusConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusConstants.h; sourceTree = ""; }; - DA497BBC15E8C94300B52167 /* GTLPlusConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusConstants.m; sourceTree = ""; }; - DA497BBD15E8C94300B52167 /* GTLPlusItemScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusItemScope.h; sourceTree = ""; }; - DA497BBE15E8C94300B52167 /* GTLPlusItemScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusItemScope.m; sourceTree = ""; }; - DA497BBF15E8C94300B52167 /* GTLPlusMoment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusMoment.h; sourceTree = ""; }; - DA497BC015E8C94300B52167 /* GTLPlusMoment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusMoment.m; sourceTree = ""; }; - DA497BC115E8C94300B52167 /* GTLPlusPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusPerson.h; sourceTree = ""; }; - DA497BC215E8C94300B52167 /* GTLPlusPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusPerson.m; sourceTree = ""; }; - DA497BC315E8C94300B52167 /* GTLQueryPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQueryPlus.h; sourceTree = ""; }; - DA497BC415E8C94300B52167 /* GTLQueryPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQueryPlus.m; sourceTree = ""; }; - DA497BC515E8C94300B52167 /* GTLServicePlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLServicePlus.h; sourceTree = ""; }; - DA497BC615E8C94300B52167 /* GTLServicePlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLServicePlus.m; sourceTree = ""; }; - DA497BC715E8C94300B52167 /* GTLQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQuery.h; sourceTree = ""; }; - DA497BC815E8C94300B52167 /* GTLQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQuery.m; sourceTree = ""; }; - DA497BC915E8C94300B52167 /* GTLRuntimeCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLRuntimeCommon.h; sourceTree = ""; }; - DA497BCA15E8C94300B52167 /* GTLRuntimeCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLRuntimeCommon.m; sourceTree = ""; }; - DA497BCB15E8C94300B52167 /* GTLService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLService.h; sourceTree = ""; }; - DA497BCC15E8C94300B52167 /* GTLService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLService.m; sourceTree = ""; }; - DA497BCD15E8C94300B52167 /* GTLTargetNamespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLTargetNamespace.h; sourceTree = ""; }; - DA497BCE15E8C94300B52167 /* GTLUploadParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUploadParameters.h; sourceTree = ""; }; - DA497BCF15E8C94300B52167 /* GTLUploadParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUploadParameters.m; sourceTree = ""; }; - DA497BD015E8C94300B52167 /* GTLUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUtilities.h; sourceTree = ""; }; - DA497BD115E8C94300B52167 /* GTLUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUtilities.m; sourceTree = ""; }; - DA497BD215E8C94300B52167 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; - DA497BD315E8C94300B52167 /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = ""; }; - DA497BD415E8C94300B52167 /* GTMHTTPFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcher.h; sourceTree = ""; }; - DA497BD515E8C94300B52167 /* GTMHTTPFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcher.m; sourceTree = ""; }; - DA497BD615E8C94300B52167 /* GTMHTTPFetcherLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherLogging.h; sourceTree = ""; }; - DA497BD715E8C94300B52167 /* GTMHTTPFetcherLogging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherLogging.m; sourceTree = ""; }; - DA497BD815E8C94300B52167 /* GTMHTTPFetcherService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherService.h; sourceTree = ""; }; - DA497BD915E8C94300B52167 /* GTMHTTPFetcherService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherService.m; sourceTree = ""; }; - DA497BDA15E8C94300B52167 /* GTMHTTPFetchHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetchHistory.h; sourceTree = ""; }; - DA497BDB15E8C94300B52167 /* GTMHTTPFetchHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetchHistory.m; sourceTree = ""; }; - DA497BDC15E8C94300B52167 /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = ""; }; - DA497BDD15E8C94300B52167 /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = ""; }; - DA497BDE15E8C94300B52167 /* GTMMethodCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMMethodCheck.h; sourceTree = ""; }; - DA497BDF15E8C94300B52167 /* GTMMethodCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMMethodCheck.m; sourceTree = ""; }; - DA497BE015E8C94300B52167 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSDictionary+URLArguments.h"; sourceTree = ""; }; - DA497BE115E8C94300B52167 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSDictionary+URLArguments.m"; sourceTree = ""; }; - DA497BE215E8C94300B52167 /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSString+URLArguments.h"; sourceTree = ""; }; - DA497BE315E8C94300B52167 /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+URLArguments.m"; sourceTree = ""; }; - DA497BE415E8C94300B52167 /* GTMOAuth2Authentication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2Authentication.h; sourceTree = ""; }; - DA497BE515E8C94300B52167 /* GTMOAuth2Authentication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2Authentication.m; sourceTree = ""; }; - DA497BE615E8C94300B52167 /* GTMOAuth2SignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2SignIn.h; sourceTree = ""; }; - DA497BE715E8C94300B52167 /* GTMOAuth2SignIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2SignIn.m; sourceTree = ""; }; - DA497BE815E8C94300B52167 /* GTMOAuth2ViewControllerTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2ViewControllerTouch.h; sourceTree = ""; }; - DA497BE915E8C94300B52167 /* GTMOAuth2ViewControllerTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2ViewControllerTouch.m; sourceTree = ""; }; - DA497BEA15E8C94300B52167 /* GTMOAuth2ViewTouch.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GTMOAuth2ViewTouch.xib; sourceTree = ""; }; - DA497BEB15E8C94300B52167 /* GTMObjC2Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMObjC2Runtime.h; sourceTree = ""; }; - DA497BEC15E8C94300B52167 /* GTMObjC2Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMObjC2Runtime.m; sourceTree = ""; }; DA4ECA26160D94A80012ABB9 /* libTestFlight.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libTestFlight.a; sourceTree = ""; }; DA4ECA27160D94A80012ABB9 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; DA4ECA28160D94A80012ABB9 /* release_notes.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = release_notes.md; sourceTree = ""; }; @@ -1125,19 +1050,6 @@ DA5587EA15E83C3200860B4F /* social-twitter@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "social-twitter@2x.png"; sourceTree = ""; }; DA5587F115E8418200860B4F /* iTunesArtwork-Rounded-73@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork-Rounded-73@2x.png"; sourceTree = ""; }; DA5587F315E8418200860B4F /* iTunesArtwork-Rounded.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork-Rounded.png"; sourceTree = ""; }; - DA5587F815E8B7B200860B4F /* GooglePlusShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusShare.h; sourceTree = ""; }; - DA5587F915E8B7B200860B4F /* GooglePlusSignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSignIn.h; sourceTree = ""; }; - DA5587FA15E8B7B200860B4F /* GooglePlusSignInButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSignInButton.h; sourceTree = ""; }; - DA5587FB15E8B7B200860B4F /* libGooglePlus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGooglePlus.a; sourceTree = ""; }; - DA5587FC15E8B7B200860B4F /* libGooglePlusUniversal.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGooglePlusUniversal.a; sourceTree = ""; }; - DA55887C15E8C0BA00860B4F /* google_plus_share.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = google_plus_share.png; sourceTree = ""; }; - DA55887D15E8C0BA00860B4F /* google_plus_share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "google_plus_share@2x.png"; sourceTree = ""; }; - DA55887E15E8C0BA00860B4F /* google_plus_share_large.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = google_plus_share_large.png; sourceTree = ""; }; - DA55887F15E8C0BA00860B4F /* google_plus_share_large@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "google_plus_share_large@2x.png"; sourceTree = ""; }; - DA55888015E8C0BA00860B4F /* google_plus_sign_in.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = google_plus_sign_in.png; sourceTree = ""; }; - DA55888115E8C0BA00860B4F /* google_plus_sign_in@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "google_plus_sign_in@2x.png"; sourceTree = ""; }; - DA55888215E8C0BA00860B4F /* google_plus_sign_in_wide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = google_plus_sign_in_wide.png; sourceTree = ""; }; - DA55888315E8C0BA00860B4F /* google_plus_sign_in_wide@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "google_plus_sign_in_wide@2x.png"; sourceTree = ""; }; DA5BFA44147E415C00F98B1E /* MasterPassword.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MasterPassword.app; sourceTree = BUILT_PRODUCTS_DIR; }; DA5BFA48147E415C00F98B1E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; DA5BFA4A147E415C00F98B1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -1164,6 +1076,79 @@ DA6701DD16406B7300B61001 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; }; DA6701DF16406BB400B61001 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; DA672D2E14F92C6B004A189C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + DA692D5316BB057500F14463 /* GPPDeepLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPPDeepLink.h; sourceTree = ""; }; + DA692D5416BB057500F14463 /* GPPShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPPShare.h; sourceTree = ""; }; + DA692D5516BB057500F14463 /* GPPSignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPPSignIn.h; sourceTree = ""; }; + DA692D5616BB057500F14463 /* GPPSignInButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPPSignInButton.h; sourceTree = ""; }; + DA692D5716BB057500F14463 /* libGooglePlus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGooglePlus.a; sourceTree = ""; }; + DA692D5816BB057500F14463 /* libGooglePlusUniversal.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libGooglePlusUniversal.a; sourceTree = ""; }; + DA692D5B16BB057500F14463 /* GTLBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBase64.h; sourceTree = ""; }; + DA692D5C16BB057500F14463 /* GTLBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBase64.m; sourceTree = ""; }; + DA692D5D16BB057500F14463 /* GTLBatchQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchQuery.h; sourceTree = ""; }; + DA692D5E16BB057500F14463 /* GTLBatchQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchQuery.m; sourceTree = ""; }; + DA692D5F16BB057500F14463 /* GTLBatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchResult.h; sourceTree = ""; }; + DA692D6016BB057500F14463 /* GTLBatchResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchResult.m; sourceTree = ""; }; + DA692D6116BB057500F14463 /* GTLDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDateTime.h; sourceTree = ""; }; + DA692D6216BB057500F14463 /* GTLDateTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLDateTime.m; sourceTree = ""; }; + DA692D6316BB057500F14463 /* GTLDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDefines.h; sourceTree = ""; }; + DA692D6416BB057500F14463 /* GTLErrorObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLErrorObject.h; sourceTree = ""; }; + DA692D6516BB057500F14463 /* GTLErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLErrorObject.m; sourceTree = ""; }; + DA692D6616BB057500F14463 /* GTLFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLFramework.h; sourceTree = ""; }; + DA692D6716BB057500F14463 /* GTLFramework.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLFramework.m; sourceTree = ""; }; + DA692D6816BB057500F14463 /* GTLJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLJSONParser.h; sourceTree = ""; }; + DA692D6916BB057500F14463 /* GTLJSONParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLJSONParser.m; sourceTree = ""; }; + DA692D6A16BB057500F14463 /* GTLObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLObject.h; sourceTree = ""; }; + DA692D6B16BB057500F14463 /* GTLObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLObject.m; sourceTree = ""; }; + DA692D6D16BB057500F14463 /* GTLPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlus.h; sourceTree = ""; }; + DA692D6E16BB057500F14463 /* GTLPlusConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusConstants.h; sourceTree = ""; }; + DA692D6F16BB057500F14463 /* GTLPlusConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusConstants.m; sourceTree = ""; }; + DA692D7016BB057500F14463 /* GTLPlusItemScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusItemScope.h; sourceTree = ""; }; + DA692D7116BB057500F14463 /* GTLPlusItemScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusItemScope.m; sourceTree = ""; }; + DA692D7216BB057500F14463 /* GTLPlusMoment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusMoment.h; sourceTree = ""; }; + DA692D7316BB057500F14463 /* GTLPlusMoment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusMoment.m; sourceTree = ""; }; + DA692D7416BB057500F14463 /* GTLQueryPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQueryPlus.h; sourceTree = ""; }; + DA692D7516BB057500F14463 /* GTLQueryPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQueryPlus.m; sourceTree = ""; }; + DA692D7616BB057500F14463 /* GTLServicePlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLServicePlus.h; sourceTree = ""; }; + DA692D7716BB057500F14463 /* GTLServicePlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLServicePlus.m; sourceTree = ""; }; + DA692D7816BB057500F14463 /* GTLQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQuery.h; sourceTree = ""; }; + DA692D7916BB057500F14463 /* GTLQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQuery.m; sourceTree = ""; }; + DA692D7A16BB057500F14463 /* GTLRuntimeCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLRuntimeCommon.h; sourceTree = ""; }; + DA692D7B16BB057500F14463 /* GTLRuntimeCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLRuntimeCommon.m; sourceTree = ""; }; + DA692D7C16BB057500F14463 /* GTLService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLService.h; sourceTree = ""; }; + DA692D7D16BB057500F14463 /* GTLService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLService.m; sourceTree = ""; }; + DA692D7E16BB057500F14463 /* GTLTargetNamespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLTargetNamespace.h; sourceTree = ""; }; + DA692D7F16BB057500F14463 /* GTLUploadParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUploadParameters.h; sourceTree = ""; }; + DA692D8016BB057500F14463 /* GTLUploadParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUploadParameters.m; sourceTree = ""; }; + DA692D8116BB057500F14463 /* GTLUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUtilities.h; sourceTree = ""; }; + DA692D8216BB057500F14463 /* GTLUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUtilities.m; sourceTree = ""; }; + DA692D8316BB057500F14463 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; + DA692D8416BB057500F14463 /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = ""; }; + DA692D8516BB057500F14463 /* GTMHTTPFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcher.h; sourceTree = ""; }; + DA692D8616BB057500F14463 /* GTMHTTPFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcher.m; sourceTree = ""; }; + DA692D8716BB057500F14463 /* GTMHTTPFetcherLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherLogging.h; sourceTree = ""; }; + DA692D8816BB057500F14463 /* GTMHTTPFetcherLogging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherLogging.m; sourceTree = ""; }; + DA692D8916BB057500F14463 /* GTMHTTPFetcherService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherService.h; sourceTree = ""; }; + DA692D8A16BB057500F14463 /* GTMHTTPFetcherService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherService.m; sourceTree = ""; }; + DA692D8B16BB057500F14463 /* GTMHTTPFetchHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetchHistory.h; sourceTree = ""; }; + DA692D8C16BB057500F14463 /* GTMHTTPFetchHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetchHistory.m; sourceTree = ""; }; + DA692D8D16BB057500F14463 /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = ""; }; + DA692D8E16BB057500F14463 /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = ""; }; + DA692D8F16BB057500F14463 /* GTMMethodCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMMethodCheck.h; sourceTree = ""; }; + DA692D9016BB057500F14463 /* GTMMethodCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMMethodCheck.m; sourceTree = ""; }; + DA692D9116BB057500F14463 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSDictionary+URLArguments.h"; sourceTree = ""; }; + DA692D9216BB057500F14463 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSDictionary+URLArguments.m"; sourceTree = ""; }; + DA692D9316BB057500F14463 /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSString+URLArguments.h"; sourceTree = ""; }; + DA692D9416BB057500F14463 /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+URLArguments.m"; sourceTree = ""; }; + DA692D9516BB057500F14463 /* GTMOAuth2Authentication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2Authentication.h; sourceTree = ""; }; + DA692D9616BB057500F14463 /* GTMOAuth2Authentication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2Authentication.m; sourceTree = ""; }; + DA692D9716BB057500F14463 /* GTMOAuth2SignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2SignIn.h; sourceTree = ""; }; + DA692D9816BB057500F14463 /* GTMOAuth2SignIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2SignIn.m; sourceTree = ""; }; + DA692D9916BB057500F14463 /* GTMOAuth2ViewControllerTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2ViewControllerTouch.h; sourceTree = ""; }; + DA692D9A16BB057500F14463 /* GTMOAuth2ViewControllerTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2ViewControllerTouch.m; sourceTree = ""; }; + DA692D9B16BB057500F14463 /* GTMOAuth2ViewTouch.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GTMOAuth2ViewTouch.xib; sourceTree = ""; }; + DA692D9C16BB057500F14463 /* GTMObjC2Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMObjC2Runtime.h; sourceTree = ""; }; + DA692D9D16BB057500F14463 /* GTMObjC2Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMObjC2Runtime.m; sourceTree = ""; }; + DA692DBE16BB191100F14463 /* Google+.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Google+.plist"; path = "Google+/Google+.plist"; sourceTree = SOURCE_ROOT; }; DA79A9BB1557DB6F00BAA07A /* libscryptenc-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libscryptenc-ios.a"; sourceTree = ""; }; DA79A9BD1557DDC700BAA07A /* scrypt.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = scrypt.xcodeproj; path = External/Pearl/External/iOSPorts/ports/security/scrypt/scrypt.xcodeproj; sourceTree = ""; }; DA81252E16B8544400F4732F /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = ""; }; @@ -2054,7 +2039,8 @@ buildActionMask = 2147483647; files = ( DA497B9815E8C90E00B52167 /* Foundation.framework in Frameworks */, - DA497C0F15E8C9CF00B52167 /* libGooglePlusUniversal.a in Frameworks */, + DA692D9E16BB057500F14463 /* libGooglePlus.a in Frameworks */, + DA692D9F16BB057500F14463 /* libGooglePlusUniversal.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2172,129 +2158,17 @@ path = External/iCloudStoreManager/iCloudStoreManager; sourceTree = ""; }; - DA497BA615E8C94300B52167 /* OpenSource */ = { - isa = PBXGroup; - children = ( - DA497BA715E8C94300B52167 /* GTL */, - DA497BD215E8C94300B52167 /* GTMDefines.h */, - DA497BD315E8C94300B52167 /* GTMGarbageCollection.h */, - DA497BD415E8C94300B52167 /* GTMHTTPFetcher.h */, - DA497BD515E8C94300B52167 /* GTMHTTPFetcher.m */, - DA497BD615E8C94300B52167 /* GTMHTTPFetcherLogging.h */, - DA497BD715E8C94300B52167 /* GTMHTTPFetcherLogging.m */, - DA497BD815E8C94300B52167 /* GTMHTTPFetcherService.h */, - DA497BD915E8C94300B52167 /* GTMHTTPFetcherService.m */, - DA497BDA15E8C94300B52167 /* GTMHTTPFetchHistory.h */, - DA497BDB15E8C94300B52167 /* GTMHTTPFetchHistory.m */, - DA497BDC15E8C94300B52167 /* GTMLogger.h */, - DA497BDD15E8C94300B52167 /* GTMLogger.m */, - DA497BDE15E8C94300B52167 /* GTMMethodCheck.h */, - DA497BDF15E8C94300B52167 /* GTMMethodCheck.m */, - DA497BE015E8C94300B52167 /* GTMNSDictionary+URLArguments.h */, - DA497BE115E8C94300B52167 /* GTMNSDictionary+URLArguments.m */, - DA497BE215E8C94300B52167 /* GTMNSString+URLArguments.h */, - DA497BE315E8C94300B52167 /* GTMNSString+URLArguments.m */, - DA497BE415E8C94300B52167 /* GTMOAuth2Authentication.h */, - DA497BE515E8C94300B52167 /* GTMOAuth2Authentication.m */, - DA497BE615E8C94300B52167 /* GTMOAuth2SignIn.h */, - DA497BE715E8C94300B52167 /* GTMOAuth2SignIn.m */, - DA497BE815E8C94300B52167 /* GTMOAuth2ViewControllerTouch.h */, - DA497BE915E8C94300B52167 /* GTMOAuth2ViewControllerTouch.m */, - DA497BEA15E8C94300B52167 /* GTMOAuth2ViewTouch.xib */, - DA497BEB15E8C94300B52167 /* GTMObjC2Runtime.h */, - DA497BEC15E8C94300B52167 /* GTMObjC2Runtime.m */, - ); - name = OpenSource; - path = "External/google-plus-ios-sdk/OpenSource"; - sourceTree = SOURCE_ROOT; - }; - DA497BA715E8C94300B52167 /* GTL */ = { - isa = PBXGroup; - children = ( - DA497BA815E8C94300B52167 /* GTLBase64.h */, - DA497BA915E8C94300B52167 /* GTLBase64.m */, - DA497BAA15E8C94300B52167 /* GTLBatchQuery.h */, - DA497BAB15E8C94300B52167 /* GTLBatchQuery.m */, - DA497BAC15E8C94300B52167 /* GTLBatchResult.h */, - DA497BAD15E8C94300B52167 /* GTLBatchResult.m */, - DA497BAE15E8C94300B52167 /* GTLDateTime.h */, - DA497BAF15E8C94300B52167 /* GTLDateTime.m */, - DA497BB015E8C94300B52167 /* GTLDefines.h */, - DA497BB115E8C94300B52167 /* GTLErrorObject.h */, - DA497BB215E8C94300B52167 /* GTLErrorObject.m */, - DA497BB315E8C94300B52167 /* GTLFramework.h */, - DA497BB415E8C94300B52167 /* GTLFramework.m */, - DA497BB515E8C94300B52167 /* GTLJSONParser.h */, - DA497BB615E8C94300B52167 /* GTLJSONParser.m */, - DA497BB715E8C94300B52167 /* GTLObject.h */, - DA497BB815E8C94300B52167 /* GTLObject.m */, - DA497BB915E8C94300B52167 /* GTLPlus */, - DA497BC715E8C94300B52167 /* GTLQuery.h */, - DA497BC815E8C94300B52167 /* GTLQuery.m */, - DA497BC915E8C94300B52167 /* GTLRuntimeCommon.h */, - DA497BCA15E8C94300B52167 /* GTLRuntimeCommon.m */, - DA497BCB15E8C94300B52167 /* GTLService.h */, - DA497BCC15E8C94300B52167 /* GTLService.m */, - DA497BCD15E8C94300B52167 /* GTLTargetNamespace.h */, - DA497BCE15E8C94300B52167 /* GTLUploadParameters.h */, - DA497BCF15E8C94300B52167 /* GTLUploadParameters.m */, - DA497BD015E8C94300B52167 /* GTLUtilities.h */, - DA497BD115E8C94300B52167 /* GTLUtilities.m */, - ); - path = GTL; - sourceTree = ""; - }; - DA497BB915E8C94300B52167 /* GTLPlus */ = { - isa = PBXGroup; - children = ( - DA497BBA15E8C94300B52167 /* GTLPlus.h */, - DA497BBB15E8C94300B52167 /* GTLPlusConstants.h */, - DA497BBC15E8C94300B52167 /* GTLPlusConstants.m */, - DA497BBD15E8C94300B52167 /* GTLPlusItemScope.h */, - DA497BBE15E8C94300B52167 /* GTLPlusItemScope.m */, - DA497BBF15E8C94300B52167 /* GTLPlusMoment.h */, - DA497BC015E8C94300B52167 /* GTLPlusMoment.m */, - DA497BC115E8C94300B52167 /* GTLPlusPerson.h */, - DA497BC215E8C94300B52167 /* GTLPlusPerson.m */, - DA497BC315E8C94300B52167 /* GTLQueryPlus.h */, - DA497BC415E8C94300B52167 /* GTLQueryPlus.m */, - DA497BC515E8C94300B52167 /* GTLServicePlus.h */, - DA497BC615E8C94300B52167 /* GTLServicePlus.m */, - ); - path = GTLPlus; - sourceTree = ""; - }; DA5587F715E8B7B200860B4F /* Google+ */ = { isa = PBXGroup; children = ( - DA497BA615E8C94300B52167 /* OpenSource */, - DA55887B15E8C0BA00860B4F /* Resources */, - DA5587F815E8B7B200860B4F /* GooglePlusShare.h */, - DA5587F915E8B7B200860B4F /* GooglePlusSignIn.h */, - DA5587FA15E8B7B200860B4F /* GooglePlusSignInButton.h */, - DA5587FB15E8B7B200860B4F /* libGooglePlus.a */, - DA5587FC15E8B7B200860B4F /* libGooglePlusUniversal.a */, + DA692DBE16BB191100F14463 /* Google+.plist */, + DA692D5216BB057500F14463 /* lib */, + DA692D5916BB057500F14463 /* OpenSource */, ); name = "Google+"; path = "External/google-plus-ios-sdk/lib"; sourceTree = ""; }; - DA55887B15E8C0BA00860B4F /* Resources */ = { - isa = PBXGroup; - children = ( - DA55887C15E8C0BA00860B4F /* google_plus_share.png */, - DA55887D15E8C0BA00860B4F /* google_plus_share@2x.png */, - DA55887E15E8C0BA00860B4F /* google_plus_share_large.png */, - DA55887F15E8C0BA00860B4F /* google_plus_share_large@2x.png */, - DA55888015E8C0BA00860B4F /* google_plus_sign_in.png */, - DA55888115E8C0BA00860B4F /* google_plus_sign_in@2x.png */, - DA55888215E8C0BA00860B4F /* google_plus_sign_in_wide.png */, - DA55888315E8C0BA00860B4F /* google_plus_sign_in_wide@2x.png */, - ); - name = Resources; - path = "External/google-plus-ios-sdk/Resources"; - sourceTree = SOURCE_ROOT; - }; DA5BFA39147E415C00F98B1E = { isa = PBXGroup; children = ( @@ -2395,6 +2269,109 @@ path = MasterPassword; sourceTree = ""; }; + DA692D5216BB057500F14463 /* lib */ = { + isa = PBXGroup; + children = ( + DA692D5316BB057500F14463 /* GPPDeepLink.h */, + DA692D5416BB057500F14463 /* GPPShare.h */, + DA692D5516BB057500F14463 /* GPPSignIn.h */, + DA692D5616BB057500F14463 /* GPPSignInButton.h */, + DA692D5716BB057500F14463 /* libGooglePlus.a */, + DA692D5816BB057500F14463 /* libGooglePlusUniversal.a */, + ); + name = lib; + sourceTree = ""; + }; + DA692D5916BB057500F14463 /* OpenSource */ = { + isa = PBXGroup; + children = ( + DA692D5A16BB057500F14463 /* GTL */, + DA692D8316BB057500F14463 /* GTMDefines.h */, + DA692D8416BB057500F14463 /* GTMGarbageCollection.h */, + DA692D8516BB057500F14463 /* GTMHTTPFetcher.h */, + DA692D8616BB057500F14463 /* GTMHTTPFetcher.m */, + DA692D8716BB057500F14463 /* GTMHTTPFetcherLogging.h */, + DA692D8816BB057500F14463 /* GTMHTTPFetcherLogging.m */, + DA692D8916BB057500F14463 /* GTMHTTPFetcherService.h */, + DA692D8A16BB057500F14463 /* GTMHTTPFetcherService.m */, + DA692D8B16BB057500F14463 /* GTMHTTPFetchHistory.h */, + DA692D8C16BB057500F14463 /* GTMHTTPFetchHistory.m */, + DA692D8D16BB057500F14463 /* GTMLogger.h */, + DA692D8E16BB057500F14463 /* GTMLogger.m */, + DA692D8F16BB057500F14463 /* GTMMethodCheck.h */, + DA692D9016BB057500F14463 /* GTMMethodCheck.m */, + DA692D9116BB057500F14463 /* GTMNSDictionary+URLArguments.h */, + DA692D9216BB057500F14463 /* GTMNSDictionary+URLArguments.m */, + DA692D9316BB057500F14463 /* GTMNSString+URLArguments.h */, + DA692D9416BB057500F14463 /* GTMNSString+URLArguments.m */, + DA692D9516BB057500F14463 /* GTMOAuth2Authentication.h */, + DA692D9616BB057500F14463 /* GTMOAuth2Authentication.m */, + DA692D9716BB057500F14463 /* GTMOAuth2SignIn.h */, + DA692D9816BB057500F14463 /* GTMOAuth2SignIn.m */, + DA692D9916BB057500F14463 /* GTMOAuth2ViewControllerTouch.h */, + DA692D9A16BB057500F14463 /* GTMOAuth2ViewControllerTouch.m */, + DA692D9B16BB057500F14463 /* GTMOAuth2ViewTouch.xib */, + DA692D9C16BB057500F14463 /* GTMObjC2Runtime.h */, + DA692D9D16BB057500F14463 /* GTMObjC2Runtime.m */, + ); + name = OpenSource; + path = "External/google-plus-ios-sdk/OpenSource"; + sourceTree = SOURCE_ROOT; + }; + DA692D5A16BB057500F14463 /* GTL */ = { + isa = PBXGroup; + children = ( + DA692D5B16BB057500F14463 /* GTLBase64.h */, + DA692D5C16BB057500F14463 /* GTLBase64.m */, + DA692D5D16BB057500F14463 /* GTLBatchQuery.h */, + DA692D5E16BB057500F14463 /* GTLBatchQuery.m */, + DA692D5F16BB057500F14463 /* GTLBatchResult.h */, + DA692D6016BB057500F14463 /* GTLBatchResult.m */, + DA692D6116BB057500F14463 /* GTLDateTime.h */, + DA692D6216BB057500F14463 /* GTLDateTime.m */, + DA692D6316BB057500F14463 /* GTLDefines.h */, + DA692D6416BB057500F14463 /* GTLErrorObject.h */, + DA692D6516BB057500F14463 /* GTLErrorObject.m */, + DA692D6616BB057500F14463 /* GTLFramework.h */, + DA692D6716BB057500F14463 /* GTLFramework.m */, + DA692D6816BB057500F14463 /* GTLJSONParser.h */, + DA692D6916BB057500F14463 /* GTLJSONParser.m */, + DA692D6A16BB057500F14463 /* GTLObject.h */, + DA692D6B16BB057500F14463 /* GTLObject.m */, + DA692D6C16BB057500F14463 /* GTLPlus */, + DA692D7816BB057500F14463 /* GTLQuery.h */, + DA692D7916BB057500F14463 /* GTLQuery.m */, + DA692D7A16BB057500F14463 /* GTLRuntimeCommon.h */, + DA692D7B16BB057500F14463 /* GTLRuntimeCommon.m */, + DA692D7C16BB057500F14463 /* GTLService.h */, + DA692D7D16BB057500F14463 /* GTLService.m */, + DA692D7E16BB057500F14463 /* GTLTargetNamespace.h */, + DA692D7F16BB057500F14463 /* GTLUploadParameters.h */, + DA692D8016BB057500F14463 /* GTLUploadParameters.m */, + DA692D8116BB057500F14463 /* GTLUtilities.h */, + DA692D8216BB057500F14463 /* GTLUtilities.m */, + ); + path = GTL; + sourceTree = ""; + }; + DA692D6C16BB057500F14463 /* GTLPlus */ = { + isa = PBXGroup; + children = ( + DA692D6D16BB057500F14463 /* GTLPlus.h */, + DA692D6E16BB057500F14463 /* GTLPlusConstants.h */, + DA692D6F16BB057500F14463 /* GTLPlusConstants.m */, + DA692D7016BB057500F14463 /* GTLPlusItemScope.h */, + DA692D7116BB057500F14463 /* GTLPlusItemScope.m */, + DA692D7216BB057500F14463 /* GTLPlusMoment.h */, + DA692D7316BB057500F14463 /* GTLPlusMoment.m */, + DA692D7416BB057500F14463 /* GTLQueryPlus.h */, + DA692D7516BB057500F14463 /* GTLQueryPlus.m */, + DA692D7616BB057500F14463 /* GTLServicePlus.h */, + DA692D7716BB057500F14463 /* GTLServicePlus.m */, + ); + path = GTLPlus; + sourceTree = ""; + }; DA79A9BE1557DDC700BAA07A /* Products */ = { isa = PBXGroup; children = ( @@ -4591,14 +4568,6 @@ DA5587F015E83C3200860B4F /* social-twitter@2x.png in Resources */, DA5587F415E8418200860B4F /* iTunesArtwork-Rounded-73@2x.png in Resources */, DA5587F615E8418200860B4F /* iTunesArtwork-Rounded.png in Resources */, - DA55888415E8C0BA00860B4F /* google_plus_share.png in Resources */, - DA55888515E8C0BA00860B4F /* google_plus_share@2x.png in Resources */, - DA55888615E8C0BA00860B4F /* google_plus_share_large.png in Resources */, - DA55888715E8C0BA00860B4F /* google_plus_share_large@2x.png in Resources */, - DA55888815E8C0BA00860B4F /* google_plus_sign_in.png in Resources */, - DA55888915E8C0BA00860B4F /* google_plus_sign_in@2x.png in Resources */, - DA55888A15E8C0BA00860B4F /* google_plus_sign_in_wide.png in Resources */, - DA55888B15E8C0BA00860B4F /* google_plus_sign_in_wide@2x.png in Resources */, DA350A0615F11F9400C14A8E /* pull-down.png in Resources */, DA350A0715F11F9400C14A8E /* pull-down@2x.png in Resources */, DA350A0815F11F9400C14A8E /* pull-up.png in Resources */, @@ -4612,6 +4581,7 @@ DA3EE946160145C700C68F6D /* Default-568h.png in Resources */, DA3EE947160145C700C68F6D /* Default-568h@2x.png in Resources */, DA4ECA2E160D94A80012ABB9 /* TestFlight.plist in Resources */, + DA692DBF16BB191100F14463 /* Google+.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4684,37 +4654,36 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA497BED15E8C94300B52167 /* GTLBase64.m in Sources */, - DA497BEE15E8C94300B52167 /* GTLBatchQuery.m in Sources */, - DA497BEF15E8C94300B52167 /* GTLBatchResult.m in Sources */, - DA497BF015E8C94300B52167 /* GTLDateTime.m in Sources */, - DA497BF115E8C94300B52167 /* GTLErrorObject.m in Sources */, - DA497BF215E8C94300B52167 /* GTLFramework.m in Sources */, - DA497BF315E8C94300B52167 /* GTLJSONParser.m in Sources */, - DA497BF415E8C94300B52167 /* GTLObject.m in Sources */, - DA497BF515E8C94300B52167 /* GTLPlusConstants.m in Sources */, - DA497BF615E8C94300B52167 /* GTLPlusItemScope.m in Sources */, - DA497BF715E8C94300B52167 /* GTLPlusMoment.m in Sources */, - DA497BF815E8C94300B52167 /* GTLPlusPerson.m in Sources */, - DA497BF915E8C94300B52167 /* GTLQueryPlus.m in Sources */, - DA497BFA15E8C94300B52167 /* GTLServicePlus.m in Sources */, - DA497BFB15E8C94300B52167 /* GTLQuery.m in Sources */, - DA497BFC15E8C94300B52167 /* GTLRuntimeCommon.m in Sources */, - DA497BFD15E8C94300B52167 /* GTLService.m in Sources */, - DA497BFE15E8C94300B52167 /* GTLUploadParameters.m in Sources */, - DA497BFF15E8C94300B52167 /* GTLUtilities.m in Sources */, - DA497C0015E8C94300B52167 /* GTMHTTPFetcher.m in Sources */, - DA497C0115E8C94300B52167 /* GTMHTTPFetcherLogging.m in Sources */, - DA497C0215E8C94300B52167 /* GTMHTTPFetcherService.m in Sources */, - DA497C0315E8C94300B52167 /* GTMHTTPFetchHistory.m in Sources */, - DA497C0415E8C94300B52167 /* GTMLogger.m in Sources */, - DA497C0515E8C94300B52167 /* GTMMethodCheck.m in Sources */, - DA497C0615E8C94300B52167 /* GTMNSDictionary+URLArguments.m in Sources */, - DA497C0715E8C94300B52167 /* GTMNSString+URLArguments.m in Sources */, - DA497C0815E8C94300B52167 /* GTMOAuth2Authentication.m in Sources */, - DA497C0915E8C94300B52167 /* GTMOAuth2SignIn.m in Sources */, - DA497C0A15E8C94300B52167 /* GTMOAuth2ViewControllerTouch.m in Sources */, - DA497C0B15E8C94300B52167 /* GTMObjC2Runtime.m in Sources */, + DA692DA016BB057500F14463 /* GTLBase64.m in Sources */, + DA692DA116BB057500F14463 /* GTLBatchQuery.m in Sources */, + DA692DA216BB057500F14463 /* GTLBatchResult.m in Sources */, + DA692DA316BB057500F14463 /* GTLDateTime.m in Sources */, + DA692DA416BB057500F14463 /* GTLErrorObject.m in Sources */, + DA692DA516BB057500F14463 /* GTLFramework.m in Sources */, + DA692DA616BB057500F14463 /* GTLJSONParser.m in Sources */, + DA692DA716BB057500F14463 /* GTLObject.m in Sources */, + DA692DA816BB057500F14463 /* GTLPlusConstants.m in Sources */, + DA692DA916BB057500F14463 /* GTLPlusItemScope.m in Sources */, + DA692DAA16BB057500F14463 /* GTLPlusMoment.m in Sources */, + DA692DAB16BB057500F14463 /* GTLQueryPlus.m in Sources */, + DA692DAC16BB057500F14463 /* GTLServicePlus.m in Sources */, + DA692DAD16BB057500F14463 /* GTLQuery.m in Sources */, + DA692DAE16BB057500F14463 /* GTLRuntimeCommon.m in Sources */, + DA692DAF16BB057500F14463 /* GTLService.m in Sources */, + DA692DB016BB057500F14463 /* GTLUploadParameters.m in Sources */, + DA692DB116BB057500F14463 /* GTLUtilities.m in Sources */, + DA692DB216BB057500F14463 /* GTMHTTPFetcher.m in Sources */, + DA692DB316BB057500F14463 /* GTMHTTPFetcherLogging.m in Sources */, + DA692DB416BB057500F14463 /* GTMHTTPFetcherService.m in Sources */, + DA692DB516BB057500F14463 /* GTMHTTPFetchHistory.m in Sources */, + DA692DB616BB057500F14463 /* GTMLogger.m in Sources */, + DA692DB716BB057500F14463 /* GTMMethodCheck.m in Sources */, + DA692DB816BB057500F14463 /* GTMNSDictionary+URLArguments.m in Sources */, + DA692DB916BB057500F14463 /* GTMNSString+URLArguments.m in Sources */, + DA692DBA16BB057500F14463 /* GTMOAuth2Authentication.m in Sources */, + DA692DBB16BB057500F14463 /* GTMOAuth2SignIn.m in Sources */, + DA692DBC16BB057500F14463 /* GTMOAuth2ViewControllerTouch.m in Sources */, + DA692DBD16BB057500F14463 /* GTMObjC2Runtime.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5056,7 +5025,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = armv7; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_WARN_CXX0X_EXTENSIONS = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -5119,7 +5088,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = armv7; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_WARN_CXX0X_EXTENSIONS = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -5271,7 +5240,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = armv7; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_WARN_CXX0X_EXTENSIONS = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -5359,7 +5328,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; DSTROOT = /tmp/Pearl.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Pearl/Pearl-Prefix.pch"; HEADER_SEARCH_PATHS = "$(SRCROOT)/External/Pearl/External/iOSPorts/include/**"; LIBRARY_SEARCH_PATHS = ( @@ -5460,7 +5428,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; DSTROOT = /tmp/Pearl.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Pearl/Pearl-Prefix.pch"; HEADER_SEARCH_PATHS = "$(SRCROOT)/External/Pearl/External/iOSPorts/include/**"; LIBRARY_SEARCH_PATHS = ( @@ -5478,7 +5445,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; DSTROOT = /tmp/Pearl.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Pearl/Pearl-Prefix.pch"; HEADER_SEARCH_PATHS = "$(SRCROOT)/External/Pearl/External/iOSPorts/include/**"; LIBRARY_SEARCH_PATHS = ( diff --git a/MasterPassword/MPAppDelegate_Shared.h b/MasterPassword/MPAppDelegate_Shared.h index 49daec45..13b39e51 100644 --- a/MasterPassword/MPAppDelegate_Shared.h +++ b/MasterPassword/MPAppDelegate_Shared.h @@ -18,8 +18,6 @@ @property (strong, nonatomic) MPUserEntity *activeUser; @property (strong, nonatomic) MPKey *key; -+ (MPAppDelegate_Shared *)get; - - (MPUserEntity *)activeUserInContext:(NSManagedObjectContext *)moc; @end diff --git a/MasterPassword/MPConfig.h b/MasterPassword/MPConfig.h index 2a7b6032..80472c82 100644 --- a/MasterPassword/MPConfig.h +++ b/MasterPassword/MPConfig.h @@ -16,6 +16,4 @@ @property (nonatomic, retain) NSNumber *iCloud; @property (nonatomic, retain) NSNumber *iCloudDecided; -+ (MPConfig *)get; - @end diff --git a/MasterPassword/Mac/MPAppDelegate.h b/MasterPassword/Mac/MPAppDelegate.h index 719eb5c3..3491123d 100644 --- a/MasterPassword/Mac/MPAppDelegate.h +++ b/MasterPassword/Mac/MPAppDelegate.h @@ -23,8 +23,6 @@ @property (nonatomic, weak) IBOutlet NSMenuItem *createUserItem; @property (nonatomic, weak) IBOutlet NSMenuItem *usersItem; -+ (MPAppDelegate *)get; - - (IBAction)activate:(id)sender; - (IBAction)togglePreference:(NSMenuItem *)sender; - (IBAction)newUser:(NSMenuItem *)sender; diff --git a/MasterPassword/Mac/MPMacConfig.h b/MasterPassword/Mac/MPMacConfig.h index 556ae1f4..1e7ae6dc 100644 --- a/MasterPassword/Mac/MPMacConfig.h +++ b/MasterPassword/Mac/MPMacConfig.h @@ -12,6 +12,4 @@ @property (nonatomic, retain) NSString *usedUserName; -+ (MPMacConfig *)get; - @end diff --git a/MasterPassword/iOS/MPAppDelegate.h b/MasterPassword/iOS/MPAppDelegate.h index ca74207d..02d548d6 100644 --- a/MasterPassword/iOS/MPAppDelegate.h +++ b/MasterPassword/iOS/MPAppDelegate.h @@ -8,11 +8,13 @@ #import #import + #import "MPAppDelegate_Shared.h" +#import "GPPShare.h" @interface MPAppDelegate : MPAppDelegate_Shared -+ (MPAppDelegate *)get; +@property (nonatomic, readonly) GPPShare *googlePlus; - (void)showGuide; - (void)showFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController; diff --git a/MasterPassword/iOS/MPAppDelegate.m b/MasterPassword/iOS/MPAppDelegate.m index 4d8ab151..0cb7fcc1 100644 --- a/MasterPassword/iOS/MPAppDelegate.m +++ b/MasterPassword/iOS/MPAppDelegate.m @@ -14,14 +14,7 @@ @interface MPAppDelegate () -- (NSDictionary *)testFlightInfo; -- (NSString *)testFlightToken; - -- (NSDictionary *)crashlyticsInfo; -- (NSString *)crashlyticsAPIKey; - -- (NSDictionary *)localyticsInfo; -- (NSString *)localyticsKey; +@property (nonatomic, readwrite) GPPShare *googlePlus; @end @@ -38,11 +31,6 @@ #endif } -+ (MPAppDelegate *)get { - - return (MPAppDelegate *)[super get]; -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[[NSBundle mainBundle] mutableInfoDictionary] setObject:@"Master Password" forKey:@"CFBundleDisplayName"]; @@ -83,6 +71,16 @@ err(@"TestFlight: %@", exception); } #endif + @try { + NSString *googlePlusClientID = [self googlePlusClientID]; + if ([googlePlusClientID length]) { + inf(@"Initializing Google+"); + self.googlePlus = [[GPPShare alloc] initWithClientID:googlePlusClientID]; + } + } + @catch (id exception) { + err(@"Google+: %@", exception); + } @try { NSString *crashlyticsAPIKey = [self crashlyticsAPIKey]; if ([crashlyticsAPIKey length]) { @@ -280,6 +278,10 @@ if (!url) return NO; + // Google+ + if ([self.googlePlus handleURL:url sourceApplication:sourceApplication annotation:annotation]) + return YES; + // Arbitrary URL to mpsites data. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSError *error; @@ -658,8 +660,26 @@ } } -#pragma mark - TestFlight +#pragma mark - Google+ + +- (NSDictionary *)googlePlusInfo { + + static NSDictionary *googlePlusInfo = nil; + if (googlePlusInfo == nil) + googlePlusInfo = [[NSDictionary alloc] initWithContentsOfURL: + [[NSBundle mainBundle] URLForResource:@"Google+" withExtension:@"plist"]]; + + return googlePlusInfo; +} + +- (NSString *)googlePlusClientID { + + return NSNullToNil([[self googlePlusInfo] valueForKeyPath:@"ClientID"]); +} + + +#pragma mark - TestFlight - (NSDictionary *)testFlightInfo { @@ -679,7 +699,6 @@ #pragma mark - Crashlytics - - (NSDictionary *)crashlyticsInfo { static NSDictionary *crashlyticsInfo = nil; @@ -698,7 +717,6 @@ #pragma mark - Localytics - - (NSDictionary *)localyticsInfo { static NSDictionary *localyticsInfo = nil; diff --git a/MasterPassword/iOS/MPUnlockViewController.m b/MasterPassword/iOS/MPUnlockViewController.m index fc072ae5..5911080b 100644 --- a/MasterPassword/iOS/MPUnlockViewController.m +++ b/MasterPassword/iOS/MPUnlockViewController.m @@ -8,7 +8,6 @@ #import #import -#import "GooglePlusShare.h" #import "MPUnlockViewController.h" #import "MPAppDelegate.h" @@ -837,11 +836,9 @@ - (IBAction)google:(UIButton *)sender { - GooglePlusShare *share = [[GooglePlusShare alloc] initWithClientID:[[PearlInfoPlist get] objectForKeyPath:@"GooglePlusClientID"]]; - [[[[share shareDialog] - setURLToShare:[NSURL URLWithString:@"http://masterpasswordapp.com"]] - setPrefillText:@"I've secured my accounts with Master Password: Actually secure passwords that cannot get lost."] - open]; + id shareDialog = [[MPAppDelegate get].googlePlus shareDialog]; + [[[shareDialog setURLToShare:[NSURL URLWithString:@"http://masterpasswordapp.com"]] + setPrefillText:@"I've started doing passwords properly thanks to Master Password for iOS."] open]; } - (IBAction)mail:(UIButton *)sender { diff --git a/MasterPassword/iOS/MPiOSConfig.h b/MasterPassword/iOS/MPiOSConfig.h index 60d9048e..b66083ee 100644 --- a/MasterPassword/iOS/MPiOSConfig.h +++ b/MasterPassword/iOS/MPiOSConfig.h @@ -17,6 +17,4 @@ @property (nonatomic, retain) NSNumber *typeTipShown; @property (nonatomic, retain) NSNumber *loginNameTipShown; -+ (MPiOSConfig *)get; - @end diff --git a/MasterPassword/iOS/MasterPassword-Info.plist b/MasterPassword/iOS/MasterPassword-Info.plist index 964a5c76..ed36747f 100644 --- a/MasterPassword/iOS/MasterPassword-Info.plist +++ b/MasterPassword/iOS/MasterPassword-Info.plist @@ -63,16 +63,6 @@ ???? CFBundleURLTypes - - CFBundleTypeRole - Editor - CFBundleURLName - facebook - CFBundleURLSchemes - - fb257095917745237 - - CFBundleTypeRole Editor @@ -88,8 +78,6 @@ [auto] FacebookAppID 257095917745237 - GooglePlusClientID - 1098891429568.apps.googleusercontent.com LSRequiresIPhoneOS NSHumanReadableCopyright @@ -119,10 +107,6 @@ MainStoryboard_iPhone UIPrerenderedIcon - UIRequiredDeviceCapabilities - - armv7 - UIStatusBarHidden UIStatusBarStyle