Update Google+ integration.
[UPDATED] Google+ SDK to 1.1.0.
This commit is contained in:
@@ -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];
|
||||
|
||||
|
@@ -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 <GTLQueryProtocol> {
|
||||
|
@@ -16,6 +16,9 @@
|
||||
//
|
||||
// GTLDateTime.h
|
||||
//
|
||||
// This is an immutable class representing a date and optionally a
|
||||
// time with time zone.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#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
|
||||
|
@@ -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;
|
||||
|
@@ -17,6 +17,8 @@
|
||||
// GTLObject.h
|
||||
//
|
||||
|
||||
// GTLObject documentation:
|
||||
// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Objects_and_Queries
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -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 <GTLCollectionProtocol, NSFastEnumeration>
|
||||
@interface GTLCollectionObject : GTLObject <GTLCollectionProtocol, NSFastEnumeration> {
|
||||
@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)
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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 <Foundation/Foundation.h>
|
||||
|
||||
@@ -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"
|
||||
|
@@ -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";
|
||||
|
@@ -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.
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -17,6 +17,9 @@
|
||||
// GTLService.h
|
||||
//
|
||||
|
||||
// Service object documentation:
|
||||
// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Services_and_Tickets
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#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<GTLQueryProtocol>)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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -17,6 +17,9 @@
|
||||
// GTLUploadParameters.h
|
||||
//
|
||||
|
||||
// Uploading documentation:
|
||||
// https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Uploading_Files
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "GTLDefines.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
|
||||
|
@@ -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
|
||||
|
@@ -21,9 +21,13 @@
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include <Foundation/NSObjCRuntime.h>
|
||||
#endif // __OBJC__
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include <Availability.h>
|
||||
#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__
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
|
@@ -77,6 +77,33 @@
|
||||
// Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
|
||||
//
|
||||
//
|
||||
// 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 <NSObject>
|
||||
// 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 <GTMHTTPFetchHistoryProtocol> fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies
|
||||
NSInteger cookieStorageMethod_; // constant from above
|
||||
id <GTMCookieStorageProtocol> 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;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,16 @@
|
||||
#import <pthread.h>
|
||||
|
||||
|
||||
#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__
|
||||
|
||||
|
@@ -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))) {
|
||||
|
@@ -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);
|
||||
|
@@ -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 -
|
||||
|
@@ -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 <GTMHTTPFetcherServiceProtocol> 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:)];
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -1,32 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">768</int>
|
||||
<string key="IBDocument.SystemVersion">10J869</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">851</string>
|
||||
<string key="IBDocument.AppKitVersion">1038.35</string>
|
||||
<string key="IBDocument.HIToolboxVersion">461.00</string>
|
||||
<int key="IBDocument.SystemTarget">1024</int>
|
||||
<string key="IBDocument.SystemVersion">12C60</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2843</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.34</string>
|
||||
<string key="IBDocument.HIToolboxVersion">625.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">141</string>
|
||||
<string key="NS.object.0">1929</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
|
||||
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="4"/>
|
||||
<integer value="15"/>
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUIActivityIndicatorView</string>
|
||||
<string>IBUIBarButtonItem</string>
|
||||
<string>IBUIButton</string>
|
||||
<string>IBUINavigationItem</string>
|
||||
<string>IBUIView</string>
|
||||
<string>IBUIWebView</string>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys" id="0">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
@@ -56,16 +56,13 @@
|
||||
<int key="NSvFlags">292</int>
|
||||
<string key="NSFrameSize">{30, 30}</string>
|
||||
<reference key="NSSuperview" ref="808907889"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="981703116"/>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<object class="NSFont" key="IBUIFont" id="530402572">
|
||||
<string key="NSName">Helvetica-Bold</string>
|
||||
<double key="NSSize">24</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
<string key="IBUITitleShadowOffset">{0, -2}</string>
|
||||
<string key="IBUINormalTitle">◀</string>
|
||||
<object class="NSColor" key="IBUIHighlightedTitleColor" id="193465259">
|
||||
@@ -81,18 +78,30 @@
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MC41AA</bytes>
|
||||
</object>
|
||||
<object class="IBUIFontDescription" key="IBUIFontDescription" id="621440819">
|
||||
<string key="name">Helvetica-Bold</string>
|
||||
<string key="family">Helvetica</string>
|
||||
<int key="traits">2</int>
|
||||
<double key="pointSize">24</double>
|
||||
</object>
|
||||
<object class="NSFont" key="IBUIFont" id="530402572">
|
||||
<string key="NSName">Helvetica-Bold</string>
|
||||
<double key="NSSize">24</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBUIButton" id="981703116">
|
||||
<reference key="NSNextResponder" ref="808907889"/>
|
||||
<int key="NSvFlags">292</int>
|
||||
<string key="NSFrame">{{30, 0}, {30, 30}}</string>
|
||||
<reference key="NSSuperview" ref="808907889"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<int key="IBUIContentHorizontalAlignment">0</int>
|
||||
<int key="IBUIContentVerticalAlignment">0</int>
|
||||
<reference key="IBUIFont" ref="530402572"/>
|
||||
<string key="IBUITitleShadowOffset">{0, -2}</string>
|
||||
<string key="IBUINormalTitle">▶</string>
|
||||
<reference key="IBUIHighlightedTitleColor" ref="193465259"/>
|
||||
@@ -102,10 +111,14 @@
|
||||
</object>
|
||||
<reference key="IBUINormalTitleColor" ref="193465259"/>
|
||||
<reference key="IBUINormalTitleShadowColor" ref="999379443"/>
|
||||
<reference key="IBUIFontDescription" ref="621440819"/>
|
||||
<reference key="IBUIFont" ref="530402572"/>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrameSize">{60, 30}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="453250804"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MSAwAA</bytes>
|
||||
@@ -113,6 +126,7 @@
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
|
||||
<int key="IBUIInterfaceOrientation">3</int>
|
||||
<int key="interfaceOrientation">3</int>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
@@ -127,6 +141,8 @@
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrameSize">{320, 460}</string>
|
||||
<reference key="NSSuperview" ref="426018584"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="268967673"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MSAxIDEAA</bytes>
|
||||
@@ -137,9 +153,25 @@
|
||||
<int key="IBUIDataDetectorTypes">1</int>
|
||||
<bool key="IBUIDetectsPhoneNumbers">YES</bool>
|
||||
</object>
|
||||
<object class="IBUIActivityIndicatorView" id="268967673">
|
||||
<reference key="NSNextResponder" ref="426018584"/>
|
||||
<int key="NSvFlags">292</int>
|
||||
<string key="NSFrame">{{150, 115}, {20, 20}}</string>
|
||||
<reference key="NSSuperview" ref="426018584"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBUIHidesWhenStopped">NO</bool>
|
||||
<bool key="IBUIAnimating">YES</bool>
|
||||
<int key="IBUIStyle">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrameSize">{320, 460}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="663477729"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
@@ -153,40 +185,6 @@
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<object class="NSMutableArray" key="connectionRecords">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="663477729"/>
|
||||
<reference key="destination" ref="372490531"/>
|
||||
</object>
|
||||
<int key="connectionID">9</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">rightBarButtonItem</string>
|
||||
<reference key="source" ref="1047805472"/>
|
||||
<reference key="destination" ref="961671599"/>
|
||||
</object>
|
||||
<int key="connectionID">14</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goBack</string>
|
||||
<reference key="source" ref="453250804"/>
|
||||
<reference key="destination" ref="663477729"/>
|
||||
<int key="IBEventType">7</int>
|
||||
</object>
|
||||
<int key="connectionID">18</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goForward</string>
|
||||
<reference key="source" ref="981703116"/>
|
||||
<reference key="destination" ref="663477729"/>
|
||||
<int key="IBEventType">7</int>
|
||||
</object>
|
||||
<int key="connectionID">19</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">rightBarButtonItem</string>
|
||||
@@ -235,13 +233,57 @@
|
||||
</object>
|
||||
<int key="connectionID">29</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">initialActivityIndicator</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="268967673"/>
|
||||
</object>
|
||||
<int key="connectionID">33</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="663477729"/>
|
||||
<reference key="destination" ref="372490531"/>
|
||||
</object>
|
||||
<int key="connectionID">9</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">rightBarButtonItem</string>
|
||||
<reference key="source" ref="1047805472"/>
|
||||
<reference key="destination" ref="961671599"/>
|
||||
</object>
|
||||
<int key="connectionID">14</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goBack</string>
|
||||
<reference key="source" ref="453250804"/>
|
||||
<reference key="destination" ref="663477729"/>
|
||||
<int key="IBEventType">7</int>
|
||||
</object>
|
||||
<int key="connectionID">18</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goForward</string>
|
||||
<reference key="source" ref="981703116"/>
|
||||
<reference key="destination" ref="663477729"/>
|
||||
<int key="IBEventType">7</int>
|
||||
</object>
|
||||
<int key="connectionID">19</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<object class="NSArray" key="orderedObjects">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<reference key="object" ref="0"/>
|
||||
<object class="NSArray" key="object" id="0">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
@@ -295,6 +337,7 @@
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="663477729"/>
|
||||
<reference ref="268967673"/>
|
||||
</object>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
@@ -303,6 +346,11 @@
|
||||
<reference key="object" ref="663477729"/>
|
||||
<reference key="parent" ref="426018584"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">31</int>
|
||||
<reference key="object" ref="268967673"/>
|
||||
<reference key="parent" ref="426018584"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
||||
@@ -310,27 +358,29 @@
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>-1.CustomClassName</string>
|
||||
<string>-1.IBPluginDependency</string>
|
||||
<string>-2.CustomClassName</string>
|
||||
<string>-2.IBPluginDependency</string>
|
||||
<string>10.IBPluginDependency</string>
|
||||
<string>15.IBEditorWindowLastContentRect</string>
|
||||
<string>15.IBPluginDependency</string>
|
||||
<string>16.IBPluginDependency</string>
|
||||
<string>17.IBPluginDependency</string>
|
||||
<string>27.IBEditorWindowLastContentRect</string>
|
||||
<string>27.IBPluginDependency</string>
|
||||
<string>31.IBPluginDependency</string>
|
||||
<string>4.IBPluginDependency</string>
|
||||
<string>6.IBPluginDependency</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<object class="NSArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>GTMOAuth2ViewControllerTouch</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>UIResponder</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>{{34, 1031}, {60, 30}}</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>{{214, 696}, {320, 460}}</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
@@ -339,20 +389,16 @@
|
||||
<object class="NSMutableDictionary" key="unlocalizedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference key="dict.sortedKeys" ref="0"/>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="dict.values" ref="0"/>
|
||||
</object>
|
||||
<nil key="activeLocalization"/>
|
||||
<object class="NSMutableDictionary" key="localizations">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference key="dict.sortedKeys" ref="0"/>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="dict.values" ref="0"/>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">29</int>
|
||||
<int key="maxID">33</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
@@ -365,21 +411,19 @@
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>backButton</string>
|
||||
<string>delegate_</string>
|
||||
<string>forwardButton</string>
|
||||
<string>initialActivityIndicator</string>
|
||||
<string>navButtonsView</string>
|
||||
<string>rightBarButtonItem</string>
|
||||
<string>userData_</string>
|
||||
<string>webView</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<object class="NSArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>UIButton</string>
|
||||
<string>id</string>
|
||||
<string>UIButton</string>
|
||||
<string>UIActivityIndicatorView</string>
|
||||
<string>UIView</string>
|
||||
<string>UIBarButtonItem</string>
|
||||
<string>id</string>
|
||||
<string>UIWebView</string>
|
||||
</object>
|
||||
</object>
|
||||
@@ -388,27 +432,26 @@
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>backButton</string>
|
||||
<string>delegate_</string>
|
||||
<string>forwardButton</string>
|
||||
<string>initialActivityIndicator</string>
|
||||
<string>navButtonsView</string>
|
||||
<string>rightBarButtonItem</string>
|
||||
<string>userData_</string>
|
||||
<string>webView</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<object class="NSArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">backButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">delegate_</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">forwardButton</string>
|
||||
<string key="candidateClassName">UIButton</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">initialActivityIndicator</string>
|
||||
<string key="candidateClassName">UIActivityIndicatorView</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">navButtonsView</string>
|
||||
<string key="candidateClassName">UIView</string>
|
||||
@@ -417,10 +460,6 @@
|
||||
<string key="name">rightBarButtonItem</string>
|
||||
<string key="candidateClassName">UIBarButtonItem</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">userData_</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo">
|
||||
<string key="name">webView</string>
|
||||
<string key="candidateClassName">UIWebView</string>
|
||||
@@ -429,7 +468,7 @@
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">Touch/GTMOAuth2ViewControllerTouch.h</string>
|
||||
<string key="minorKey">./Classes/GTMOAuth2ViewControllerTouch.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
@@ -438,19 +477,18 @@
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
|
||||
<integer value="768" key="NS.object.0"/>
|
||||
<real value="1024" key="NS.object.0"/>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
|
||||
<integer value="800" key="NS.object.0"/>
|
||||
<real value="1536" key="NS.object.0"/>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
|
||||
<integer value="3000" key="NS.object.0"/>
|
||||
</object>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<string key="IBDocument.LastKnownRelativeProjectPath">../GTMOAuth2.xcodeproj</string>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">141</string>
|
||||
<string key="IBCocoaTouchPluginVersion">1929</string>
|
||||
</data>
|
||||
</archive>
|
||||
|
Reference in New Issue
Block a user