Sharing on Facebook, Twitter and Google+
[FIXED] Font of navbar. [FIXED] A few compile fixes. [IMPROVED] Made properties nonatomic. [ADDED] Support for facebook, twitter and google+ sharing.
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -10,3 +10,6 @@
 | 
			
		||||
[submodule "External/FontReplacer"]
 | 
			
		||||
	path = External/FontReplacer
 | 
			
		||||
	url = git://github.com/0xced/FontReplacer.git
 | 
			
		||||
[submodule "External/facebook-ios-sdk"]
 | 
			
		||||
	path = External/facebook-ios-sdk
 | 
			
		||||
	url = https://github.com/facebook/facebook-ios-sdk
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								External/Pearl
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
							
								
								
									
										1
									
								
								External/facebook-ios-sdk
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
							
								
								
									
										3
									
								
								External/google-plus-ios-sdk/Changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
			
		||||
2012-06-25  -- v1.0.0
 | 
			
		||||
- Google+ sign-in button, share plugin, and Google+ history integration library
 | 
			
		||||
  with sample app.
 | 
			
		||||
							
								
								
									
										25
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,25 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
NSData *GTLDecodeBase64(NSString *base64Str);
 | 
			
		||||
NSString *GTLEncodeBase64(NSData *data);
 | 
			
		||||
 | 
			
		||||
// "Web-safe" encoding substitutes - and _ for + and / in the encoding table,
 | 
			
		||||
// per http://www.ietf.org/rfc/rfc4648.txt section 5.
 | 
			
		||||
 | 
			
		||||
NSData *GTLDecodeWebSafeBase64(NSString *base64Str);
 | 
			
		||||
NSString *GTLEncodeWebSafeBase64(NSData *data);
 | 
			
		||||
							
								
								
									
										139
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBase64.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,139 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "GTLBase64.h"
 | 
			
		||||
 | 
			
		||||
// Based on Cyrus Najmabadi's elegent little encoder and decoder from
 | 
			
		||||
// http://www.cocoadev.com/index.pl?BaseSixtyFour
 | 
			
		||||
 | 
			
		||||
static char gStandardEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
			
		||||
static char gWebSafeEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
 | 
			
		||||
 | 
			
		||||
#pragma mark Encode
 | 
			
		||||
 | 
			
		||||
static NSString *EncodeBase64StringCommon(NSData *data, const char *table) {
 | 
			
		||||
  if (data == nil) return nil;
 | 
			
		||||
 | 
			
		||||
  const uint8_t* input = [data bytes];
 | 
			
		||||
  NSUInteger length = [data length];
 | 
			
		||||
 | 
			
		||||
  NSUInteger bufferSize = ((length + 2) / 3) * 4;
 | 
			
		||||
  NSMutableData* buffer = [NSMutableData dataWithLength:bufferSize];
 | 
			
		||||
 | 
			
		||||
  uint8_t *output = [buffer mutableBytes];
 | 
			
		||||
 | 
			
		||||
  for (NSUInteger i = 0; i < length; i += 3) {
 | 
			
		||||
    NSUInteger value = 0;
 | 
			
		||||
    for (NSUInteger j = i; j < (i + 3); j++) {
 | 
			
		||||
      value <<= 8;
 | 
			
		||||
 | 
			
		||||
      if (j < length) {
 | 
			
		||||
        value |= (0xFF & input[j]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSInteger idx = (i / 3) * 4;
 | 
			
		||||
    output[idx + 0] =                    table[(value >> 18) & 0x3F];
 | 
			
		||||
    output[idx + 1] =                    table[(value >> 12) & 0x3F];
 | 
			
		||||
    output[idx + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
 | 
			
		||||
    output[idx + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *result = [[[NSString alloc] initWithData:buffer
 | 
			
		||||
                                            encoding:NSASCIIStringEncoding] autorelease];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSString *GTLEncodeBase64(NSData *data) {
 | 
			
		||||
  return EncodeBase64StringCommon(data, gStandardEncodingTable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSString *GTLEncodeWebSafeBase64(NSData *data) {
 | 
			
		||||
  return EncodeBase64StringCommon(data, gWebSafeEncodingTable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Decode
 | 
			
		||||
 | 
			
		||||
static void CreateDecodingTable(const char *encodingTable,
 | 
			
		||||
                                size_t encodingTableSize, char *decodingTable) {
 | 
			
		||||
  memset(decodingTable, 0, 128);
 | 
			
		||||
  for (unsigned int i = 0; i < encodingTableSize; i++) {
 | 
			
		||||
    decodingTable[(unsigned int) encodingTable[i]] = i;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static NSData *DecodeBase64StringCommon(NSString *base64Str,
 | 
			
		||||
                                        char *decodingTable) {
 | 
			
		||||
  // The input string should be plain ASCII
 | 
			
		||||
  const char *cString = [base64Str cStringUsingEncoding:NSASCIIStringEncoding];
 | 
			
		||||
  if (cString == nil) return nil;
 | 
			
		||||
 | 
			
		||||
  NSUInteger inputLength = strlen(cString);
 | 
			
		||||
  if (inputLength % 4 != 0) return nil;
 | 
			
		||||
  if (inputLength == 0) return [NSData data];
 | 
			
		||||
 | 
			
		||||
  while (inputLength > 0 && cString[inputLength - 1] == '=') {
 | 
			
		||||
    inputLength--;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSInteger outputLength = inputLength * 3 / 4;
 | 
			
		||||
  NSMutableData* data = [NSMutableData dataWithLength:outputLength];
 | 
			
		||||
  uint8_t *output = [data mutableBytes];
 | 
			
		||||
 | 
			
		||||
  NSInteger inputPoint = 0;
 | 
			
		||||
  NSInteger outputPoint = 0;
 | 
			
		||||
  char *table = decodingTable;
 | 
			
		||||
 | 
			
		||||
  while (inputPoint < inputLength) {
 | 
			
		||||
    int i0 = cString[inputPoint++];
 | 
			
		||||
    int i1 = cString[inputPoint++];
 | 
			
		||||
    int i2 = inputPoint < inputLength ? cString[inputPoint++] : 'A'; // 'A' will decode to \0
 | 
			
		||||
    int i3 = inputPoint < inputLength ? cString[inputPoint++] : 'A';
 | 
			
		||||
 | 
			
		||||
    output[outputPoint++] = (table[i0] << 2) | (table[i1] >> 4);
 | 
			
		||||
    if (outputPoint < outputLength) {
 | 
			
		||||
      output[outputPoint++] = ((table[i1] & 0xF) << 4) | (table[i2] >> 2);
 | 
			
		||||
    }
 | 
			
		||||
    if (outputPoint < outputLength) {
 | 
			
		||||
      output[outputPoint++] = ((table[i2] & 0x3) << 6) | table[i3];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSData *GTLDecodeBase64(NSString *base64Str) {
 | 
			
		||||
  static char decodingTable[128];
 | 
			
		||||
  static BOOL hasInited = NO;
 | 
			
		||||
 | 
			
		||||
  if (!hasInited) {
 | 
			
		||||
    CreateDecodingTable(gStandardEncodingTable, sizeof(gStandardEncodingTable),
 | 
			
		||||
                        decodingTable);
 | 
			
		||||
    hasInited = YES;
 | 
			
		||||
  }
 | 
			
		||||
  return DecodeBase64StringCommon(base64Str, decodingTable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSData *GTLDecodeWebSafeBase64(NSString *base64Str) {
 | 
			
		||||
  static char decodingTable[128];
 | 
			
		||||
  static BOOL hasInited = NO;
 | 
			
		||||
 | 
			
		||||
  if (!hasInited) {
 | 
			
		||||
    CreateDecodingTable(gWebSafeEncodingTable, sizeof(gWebSafeEncodingTable),
 | 
			
		||||
                        decodingTable);
 | 
			
		||||
    hasInited = YES;
 | 
			
		||||
  }
 | 
			
		||||
  return DecodeBase64StringCommon(base64Str, decodingTable);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,49 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLBatchQuery.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLQuery.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLBatchQuery : NSObject <GTLQueryProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSMutableArray *queries_;
 | 
			
		||||
  NSMutableDictionary *requestIDMap_;
 | 
			
		||||
  BOOL skipAuthorization_;
 | 
			
		||||
  NSDictionary *additionalHTTPHeaders_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Queries included in this batch.  Each query should have a unique requestID.
 | 
			
		||||
@property (retain) NSArray *queries;
 | 
			
		||||
 | 
			
		||||
// Clients may set this to YES to disallow authorization. Defaults to NO.
 | 
			
		||||
@property (assign) BOOL shouldSkipAuthorization;
 | 
			
		||||
 | 
			
		||||
// Any additional HTTP headers for this batch.
 | 
			
		||||
//
 | 
			
		||||
// These headers override the same keys from the service object's
 | 
			
		||||
// additionalHTTPHeaders.
 | 
			
		||||
@property (copy) NSDictionary *additionalHTTPHeaders;
 | 
			
		||||
 | 
			
		||||
+ (id)batchQuery;
 | 
			
		||||
+ (id)batchQueryWithQueries:(NSArray *)array;
 | 
			
		||||
 | 
			
		||||
- (void)addQuery:(GTLQuery *)query;
 | 
			
		||||
 | 
			
		||||
- (GTLQuery *)queryForRequestID:(NSString *)requestID;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										133
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchQuery.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,133 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLBatchQuery.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLBatchQuery.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLBatchQuery
 | 
			
		||||
 | 
			
		||||
@synthesize shouldSkipAuthorization = skipAuthorization_,
 | 
			
		||||
            additionalHTTPHeaders = additionalHTTPHeaders_;
 | 
			
		||||
 | 
			
		||||
+ (id)batchQuery {
 | 
			
		||||
  GTLBatchQuery *obj = [[[self alloc] init] autorelease];
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)batchQueryWithQueries:(NSArray *)queries {
 | 
			
		||||
  GTLBatchQuery *obj = [self batchQuery];
 | 
			
		||||
  obj.queries = queries;
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone {
 | 
			
		||||
  // Deep copy the list of queries
 | 
			
		||||
  NSArray *copiesOfQueries = [[[NSArray alloc] initWithArray:self.queries
 | 
			
		||||
                                                   copyItems:YES] autorelease];
 | 
			
		||||
  GTLBatchQuery *newBatch = [[[self class] allocWithZone:zone] init];
 | 
			
		||||
  newBatch.queries = copiesOfQueries;
 | 
			
		||||
  newBatch.shouldSkipAuthorization = self.shouldSkipAuthorization;
 | 
			
		||||
  newBatch.additionalHTTPHeaders = self.additionalHTTPHeaders;
 | 
			
		||||
  return newBatch;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [queries_ release];
 | 
			
		||||
  [additionalHTTPHeaders_ release];
 | 
			
		||||
  [requestIDMap_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  NSArray *queries = self.queries;
 | 
			
		||||
  NSArray *methodNames = [queries valueForKey:@"methodName"];
 | 
			
		||||
  NSArray *dedupedNames = [[NSSet setWithArray:methodNames] allObjects];
 | 
			
		||||
  NSString *namesStr = [dedupedNames componentsJoinedByString:@","];
 | 
			
		||||
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p (queries:%lu methods:%@)",
 | 
			
		||||
          [self class], self, (unsigned long) [queries count], namesStr];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (BOOL)isBatchQuery {
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTLUploadParameters *)uploadParameters {
 | 
			
		||||
  // File upload is not supported for batches
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)executionDidStop {
 | 
			
		||||
  NSArray *queries = self.queries;
 | 
			
		||||
  [queries makeObjectsPerformSelector:@selector(executionDidStop)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTLQuery *)queryForRequestID:(NSString *)requestID {
 | 
			
		||||
  GTLQuery *result = [requestIDMap_ objectForKey:requestID];
 | 
			
		||||
  if (result) return result;
 | 
			
		||||
 | 
			
		||||
  // We've not before tried to look up a query, or the map is stale
 | 
			
		||||
  [requestIDMap_ release];
 | 
			
		||||
  requestIDMap_ = [[NSMutableDictionary alloc] init];
 | 
			
		||||
 | 
			
		||||
  for (GTLQuery *query in queries_) {
 | 
			
		||||
    [requestIDMap_ setObject:query forKey:query.requestID];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  result = [requestIDMap_ objectForKey:requestID];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)setQueries:(NSArray *)array {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  for (id obj in array) {
 | 
			
		||||
    GTLQuery *query = obj;
 | 
			
		||||
    GTL_DEBUG_ASSERT([query isKindOfClass:[GTLQuery class]],
 | 
			
		||||
                     @"unexpected query class: %@", [obj class]);
 | 
			
		||||
    GTL_DEBUG_ASSERT(query.uploadParameters == nil,
 | 
			
		||||
                     @"batch may not contain upload: %@", query);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  [queries_ autorelease];
 | 
			
		||||
  queries_ = [array mutableCopy];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSArray *)queries {
 | 
			
		||||
  return queries_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)addQuery:(GTLQuery *)query {
 | 
			
		||||
  GTL_DEBUG_ASSERT([query isKindOfClass:[GTLQuery class]],
 | 
			
		||||
                   @"unexpected query class: %@", [query class]);
 | 
			
		||||
  GTL_DEBUG_ASSERT(query.uploadParameters == nil,
 | 
			
		||||
                   @"batch may not contain upload: %@", query);
 | 
			
		||||
 | 
			
		||||
  if (queries_ == nil) {
 | 
			
		||||
    queries_ = [[NSMutableArray alloc] init];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [queries_ addObject:query];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										58
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchResult.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,58 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLBatchResult.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLObject.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLBatchResult : GTLObject <GTLBatchItemCreationProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSMutableDictionary *successes_;
 | 
			
		||||
  NSMutableDictionary *failures_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dictionaries of results for all queries in the batch
 | 
			
		||||
//
 | 
			
		||||
// Dictionary keys are requestID strings; objects are results or
 | 
			
		||||
// GTLErrorObjects.
 | 
			
		||||
//
 | 
			
		||||
// For successes with no returned object (such as from delete operations),
 | 
			
		||||
// the object for the dictionary entry is NSNull.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// The original query for each result is available from the service ticket,
 | 
			
		||||
// for example
 | 
			
		||||
//
 | 
			
		||||
// NSDictionary *successes = batchResults.successes;
 | 
			
		||||
// for (NSString *requestID in successes) {
 | 
			
		||||
//   GTLObject *obj = [successes objectForKey:requestID];
 | 
			
		||||
//   GTLQuery *query = [ticket queryForRequestID:requestID];
 | 
			
		||||
//   NSLog(@"Query %@ returned object %@", query, obj);
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// NSDictionary *failures = batchResults.failures;
 | 
			
		||||
// for (NSString *requestID in failures) {
 | 
			
		||||
//   GTLErrorObject *errorObj = [failures objectForKey:requestID];
 | 
			
		||||
//   GTLQuery *query = [ticket queryForRequestID:requestID];
 | 
			
		||||
//   NSLog(@"Query %@ failed with error %@", query, errorObj);
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@property (retain) NSMutableDictionary *successes;
 | 
			
		||||
@property (retain) NSMutableDictionary *failures;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										92
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLBatchResult.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,92 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLBatchResult.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLBatchResult.h"
 | 
			
		||||
 | 
			
		||||
#import "GTLErrorObject.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLBatchResult
 | 
			
		||||
 | 
			
		||||
@synthesize successes = successes_,
 | 
			
		||||
            failures = failures_;
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone {
 | 
			
		||||
  GTLBatchResult* newObject = [super copyWithZone:zone];
 | 
			
		||||
  newObject.successes = [[self.successes mutableCopyWithZone:zone] autorelease];
 | 
			
		||||
  newObject.failures = [[self.failures mutableCopyWithZone:zone] autorelease];
 | 
			
		||||
  return newObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [successes_ release];
 | 
			
		||||
  [failures_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p (successes:%lu failures:%lu)",
 | 
			
		||||
          [self class], self,
 | 
			
		||||
          (unsigned long) [self.successes count],
 | 
			
		||||
          (unsigned long) [self.failures count]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)createItemsWithClassMap:(NSDictionary *)batchClassMap {
 | 
			
		||||
  // This is called by GTLObject objectForJSON:defaultClass:
 | 
			
		||||
  // JSON is defined to be a dictionary, but for batch results, it really
 | 
			
		||||
  // is any array.
 | 
			
		||||
  id json = self.JSON;
 | 
			
		||||
  GTL_DEBUG_ASSERT([json isKindOfClass:[NSArray class]],
 | 
			
		||||
                   @"didn't get an array for the batch results");
 | 
			
		||||
  NSArray *jsonArray = json;
 | 
			
		||||
 | 
			
		||||
  NSMutableDictionary *successes = [NSMutableDictionary dictionary];
 | 
			
		||||
  NSMutableDictionary *failures = [NSMutableDictionary dictionary];
 | 
			
		||||
 | 
			
		||||
  for (NSMutableDictionary *rpcResponse in jsonArray) {
 | 
			
		||||
    NSString *responseID = [rpcResponse objectForKey:@"id"];
 | 
			
		||||
 | 
			
		||||
    NSMutableDictionary *errorJSON = [rpcResponse objectForKey:@"error"];
 | 
			
		||||
    if (errorJSON) {
 | 
			
		||||
      GTLErrorObject *errorObject = [GTLErrorObject objectWithJSON:errorJSON];
 | 
			
		||||
      [failures setValue:errorObject forKey:responseID];
 | 
			
		||||
    } else {
 | 
			
		||||
      NSMutableDictionary *resultJSON = [rpcResponse objectForKey:@"result"];
 | 
			
		||||
 | 
			
		||||
      NSDictionary *surrogates = self.surrogates;
 | 
			
		||||
      Class defaultClass = [batchClassMap objectForKey:responseID];
 | 
			
		||||
 | 
			
		||||
      id resultObject = [[self class] objectForJSON:resultJSON
 | 
			
		||||
                                       defaultClass:defaultClass
 | 
			
		||||
                                         surrogates:surrogates
 | 
			
		||||
                                      batchClassMap:nil];
 | 
			
		||||
      if (resultObject == nil) {
 | 
			
		||||
        // methods like delete return no object
 | 
			
		||||
        resultObject = [NSNull null];
 | 
			
		||||
      }
 | 
			
		||||
      [successes setValue:resultObject forKey:responseID];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  self.successes = successes;
 | 
			
		||||
  self.failures = failures;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										56
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,56 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLDateTime.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLDateTime : NSObject <NSCopying> {
 | 
			
		||||
  NSDateComponents *dateComponents_;
 | 
			
		||||
  NSInteger milliseconds_; // This is only for the fraction of a second 0-999
 | 
			
		||||
  NSInteger offsetSeconds_; // may be NSUndefinedDateComponent
 | 
			
		||||
  BOOL isUniversalTime_; // preserves "Z"
 | 
			
		||||
  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;
 | 
			
		||||
+ (GTLDateTime *)dateTimeWithDate:(NSDate *)date timeZone:(NSTimeZone *)tz;
 | 
			
		||||
 | 
			
		||||
- (void)setFromDate:(NSDate *)date timeZone:(NSTimeZone *)tz;
 | 
			
		||||
- (void)setFromRFC3339String:(NSString *)str;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, readonly) NSDate *date;
 | 
			
		||||
@property (nonatomic, readonly) NSCalendar *calendar;
 | 
			
		||||
 | 
			
		||||
@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, assign) BOOL hasTime;
 | 
			
		||||
@property (nonatomic, assign) NSInteger offsetSeconds;
 | 
			
		||||
@property (nonatomic, assign, getter=isUniversalTime) BOOL universalTime;
 | 
			
		||||
 | 
			
		||||
- (void)setTimeZone:(NSTimeZone *)timeZone withOffsetSeconds:(NSInteger)val;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										422
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLDateTime.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,422 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLDateTime.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLDateTime.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTLDateTime
 | 
			
		||||
 | 
			
		||||
// A note about milliseconds_:
 | 
			
		||||
// RFC 3339 has support for fractions of a second.  NSDateComponents is all
 | 
			
		||||
// NSInteger based, so it can't handle a fraction of a second.  NSDate is
 | 
			
		||||
// built on NSTimeInterval so it has sub-millisecond precision.  GTL takes
 | 
			
		||||
// the compromise of supporting the RFC's optional fractional second support
 | 
			
		||||
// by maintaining a number of milliseconds past what fits in the
 | 
			
		||||
// NSDateComponents.  The parsing and string conversions will include
 | 
			
		||||
// 3 decimal digits (hence milliseconds).  When going to a string, the decimal
 | 
			
		||||
// digits are only included if the milliseconds are non zero.
 | 
			
		||||
 | 
			
		||||
@dynamic date;
 | 
			
		||||
@dynamic calendar;
 | 
			
		||||
@dynamic RFC3339String;
 | 
			
		||||
@dynamic stringValue;
 | 
			
		||||
@dynamic timeZone;
 | 
			
		||||
@dynamic hasTime;
 | 
			
		||||
 | 
			
		||||
@synthesize dateComponents = dateComponents_,
 | 
			
		||||
            milliseconds = milliseconds_,
 | 
			
		||||
            offsetSeconds = offsetSeconds_,
 | 
			
		||||
            universalTime = isUniversalTime_;
 | 
			
		||||
 | 
			
		||||
+ (GTLDateTime *)dateTimeWithRFC3339String:(NSString *)str {
 | 
			
		||||
  if (str == nil) return nil;
 | 
			
		||||
 | 
			
		||||
  GTLDateTime *result = [[[self alloc] init] autorelease];
 | 
			
		||||
  [result setFromRFC3339String:str];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (GTLDateTime *)dateTimeWithDate:(NSDate *)date timeZone:(NSTimeZone *)tz {
 | 
			
		||||
  if (date == nil) return nil;
 | 
			
		||||
 | 
			
		||||
  GTLDateTime *result = [[[self alloc] init] autorelease];
 | 
			
		||||
  [result setFromDate:date timeZone:tz];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [dateComponents_ release];
 | 
			
		||||
  [timeZone_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// until NSDateComponent implements isEqual, we'll use this
 | 
			
		||||
- (BOOL)doesDateComponents:(NSDateComponents *)dc1
 | 
			
		||||
       equalDateComponents:(NSDateComponents *)dc2 {
 | 
			
		||||
 | 
			
		||||
  return [dc1 era] == [dc2 era]
 | 
			
		||||
          && [dc1 year] == [dc2 year]
 | 
			
		||||
          && [dc1 month] == [dc2 month]
 | 
			
		||||
          && [dc1 day] == [dc2 day]
 | 
			
		||||
          && [dc1 hour] == [dc2 hour]
 | 
			
		||||
          && [dc1 minute] == [dc2 minute]
 | 
			
		||||
          && [dc1 second] == [dc2 second]
 | 
			
		||||
          && [dc1 week] == [dc2 week]
 | 
			
		||||
          && [dc1 weekday] == [dc2 weekday]
 | 
			
		||||
          && [dc1 weekdayOrdinal] == [dc2 weekdayOrdinal];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isEqual:(GTLDateTime *)other {
 | 
			
		||||
 | 
			
		||||
  if (self == other) return YES;
 | 
			
		||||
  if (![other isKindOfClass:[GTLDateTime class]]) return NO;
 | 
			
		||||
 | 
			
		||||
  BOOL areDateComponentsEqual = [self doesDateComponents:self.dateComponents
 | 
			
		||||
                                     equalDateComponents:other.dateComponents];
 | 
			
		||||
  NSTimeZone *tz1 = self.timeZone;
 | 
			
		||||
  NSTimeZone *tz2 = other.timeZone;
 | 
			
		||||
  BOOL areTimeZonesEqual = (tz1 == tz2 || (tz2 && [tz1 isEqual:tz2]));
 | 
			
		||||
 | 
			
		||||
  return self.offsetSeconds == other.offsetSeconds
 | 
			
		||||
    && self.isUniversalTime == other.isUniversalTime
 | 
			
		||||
    && self.milliseconds == other.milliseconds
 | 
			
		||||
    && areDateComponentsEqual
 | 
			
		||||
    && areTimeZonesEqual;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p: {%@}",
 | 
			
		||||
    [self class], self, self.RFC3339String];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSTimeZone *)timeZone {
 | 
			
		||||
  if (timeZone_) {
 | 
			
		||||
    return timeZone_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (self.isUniversalTime) {
 | 
			
		||||
    NSTimeZone *ztz = [NSTimeZone timeZoneWithName:@"Universal"];
 | 
			
		||||
    return ztz;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSInteger offsetSeconds = self.offsetSeconds;
 | 
			
		||||
 | 
			
		||||
  if (offsetSeconds != NSUndefinedDateComponent) {
 | 
			
		||||
    NSTimeZone *tz = [NSTimeZone timeZoneForSecondsFromGMT:offsetSeconds];
 | 
			
		||||
    return tz;
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setTimeZone:(NSTimeZone *)timeZone {
 | 
			
		||||
  [timeZone_ release];
 | 
			
		||||
  timeZone_ = [timeZone retain];
 | 
			
		||||
 | 
			
		||||
  if (timeZone) {
 | 
			
		||||
    NSInteger offsetSeconds = [timeZone secondsFromGMTForDate:self.date];
 | 
			
		||||
    self.offsetSeconds = offsetSeconds;
 | 
			
		||||
  } else {
 | 
			
		||||
    self.offsetSeconds = NSUndefinedDateComponent;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (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;
 | 
			
		||||
  if (tz) {
 | 
			
		||||
    [cal setTimeZone:tz];
 | 
			
		||||
  }
 | 
			
		||||
  return cal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDate *)date {
 | 
			
		||||
  NSCalendar *cal = self.calendar;
 | 
			
		||||
  NSDateComponents *dateComponents = self.dateComponents;
 | 
			
		||||
  NSTimeInterval extraMillisecondsAsSeconds = 0.0;
 | 
			
		||||
 | 
			
		||||
  if (!self.hasTime) {
 | 
			
		||||
    // we're not keeping track of a time, but NSDate always is based on
 | 
			
		||||
    // an absolute time. We want to avoid returning an NSDate where the
 | 
			
		||||
    // calendar date appears different from what was used to create our
 | 
			
		||||
    // date-time object.
 | 
			
		||||
    //
 | 
			
		||||
    // We'll make a copy of the date components, setting the time on our
 | 
			
		||||
    // copy to noon GMT, since that ensures the date renders correctly for
 | 
			
		||||
    // any time zone
 | 
			
		||||
    NSDateComponents *noonDateComponents = [[dateComponents copy] autorelease];
 | 
			
		||||
    [noonDateComponents setHour:12];
 | 
			
		||||
    [noonDateComponents setMinute:0];
 | 
			
		||||
    [noonDateComponents setSecond:0];
 | 
			
		||||
    dateComponents = noonDateComponents;
 | 
			
		||||
    
 | 
			
		||||
    NSTimeZone *gmt = [NSTimeZone timeZoneWithName:@"Universal"];
 | 
			
		||||
    [cal setTimeZone:gmt];
 | 
			
		||||
  } else {
 | 
			
		||||
    // Add in the fractional seconds that don't fit into NSDateComponents.
 | 
			
		||||
    extraMillisecondsAsSeconds = ((NSTimeInterval)self.milliseconds) / 1000.0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSDate *date = [cal dateFromComponents:dateComponents];
 | 
			
		||||
 | 
			
		||||
  // Add in any milliseconds that didn't fit into the dateComponents.
 | 
			
		||||
  if (extraMillisecondsAsSeconds > 0.0) {
 | 
			
		||||
#if GTL_IPHONE || (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5)
 | 
			
		||||
    date = [date dateByAddingTimeInterval:extraMillisecondsAsSeconds];
 | 
			
		||||
#else
 | 
			
		||||
    date = [date addTimeInterval:extraMillisecondsAsSeconds];
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringValue {
 | 
			
		||||
  return self.RFC3339String;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)RFC3339String {
 | 
			
		||||
  NSDateComponents *dateComponents = self.dateComponents;
 | 
			
		||||
  NSInteger offset = self.offsetSeconds;
 | 
			
		||||
 | 
			
		||||
  NSString *timeString = @""; // timeString like "T15:10:46-08:00"
 | 
			
		||||
 | 
			
		||||
  if (self.hasTime) {
 | 
			
		||||
 | 
			
		||||
    NSString *timeOffsetString; // timeOffsetString like "-08:00"
 | 
			
		||||
 | 
			
		||||
    if (self.isUniversalTime) {
 | 
			
		||||
     timeOffsetString = @"Z";
 | 
			
		||||
    } else if (offset == NSUndefinedDateComponent) {
 | 
			
		||||
      // unknown offset is rendered as -00:00 per
 | 
			
		||||
      // http://www.ietf.org/rfc/rfc3339.txt section 4.3
 | 
			
		||||
      timeOffsetString = @"-00:00";
 | 
			
		||||
    } else {
 | 
			
		||||
      NSString *sign = @"+";
 | 
			
		||||
      if (offset < 0) {
 | 
			
		||||
        sign = @"-";
 | 
			
		||||
        offset = -offset;
 | 
			
		||||
      }
 | 
			
		||||
      timeOffsetString = [NSString stringWithFormat:@"%@%02ld:%02ld",
 | 
			
		||||
        sign, (long)(offset/(60*60)) % 24, (long)(offset / 60) % 60];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSString *fractionalSecondsString = @"";
 | 
			
		||||
    if (self.milliseconds > 0.0) {
 | 
			
		||||
      fractionalSecondsString = [NSString stringWithFormat:@".%03ld", (long)self.milliseconds];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    timeString = [NSString stringWithFormat:@"T%02ld:%02ld:%02ld%@%@",
 | 
			
		||||
      (long)[dateComponents hour], (long)[dateComponents minute],
 | 
			
		||||
      (long)[dateComponents second], fractionalSecondsString, timeOffsetString];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // full dateString like "2006-11-17T15:10:46-08:00"
 | 
			
		||||
  NSString *dateString = [NSString stringWithFormat:@"%04ld-%02ld-%02ld%@",
 | 
			
		||||
    (long)[dateComponents year], (long)[dateComponents month],
 | 
			
		||||
    (long)[dateComponents day], timeString];
 | 
			
		||||
 | 
			
		||||
  return dateString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setFromDate:(NSDate *)date timeZone:(NSTimeZone *)tz {
 | 
			
		||||
  NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
 | 
			
		||||
  if (tz) {
 | 
			
		||||
    [cal setTimeZone:tz];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSUInteger const kComponentBits = (NSYearCalendarUnit | NSMonthCalendarUnit
 | 
			
		||||
    | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit
 | 
			
		||||
    | NSSecondCalendarUnit);
 | 
			
		||||
 | 
			
		||||
  NSDateComponents *components = [cal components:kComponentBits fromDate:date];
 | 
			
		||||
  self.dateComponents = components;
 | 
			
		||||
 | 
			
		||||
  // Extract the fractional seconds.
 | 
			
		||||
  NSTimeInterval asTimeInterval = [date timeIntervalSince1970];
 | 
			
		||||
  NSTimeInterval worker = asTimeInterval - trunc(asTimeInterval);
 | 
			
		||||
  self.milliseconds = (NSInteger)round(worker * 1000.0);
 | 
			
		||||
  
 | 
			
		||||
  self.universalTime = NO;
 | 
			
		||||
 | 
			
		||||
  NSInteger offset = NSUndefinedDateComponent;
 | 
			
		||||
 | 
			
		||||
  if (tz) {
 | 
			
		||||
    offset = [tz secondsFromGMTForDate:date];
 | 
			
		||||
 | 
			
		||||
    if (offset == 0 && [tz isEqualToTimeZone:[NSTimeZone timeZoneWithName:@"Universal"]]) {
 | 
			
		||||
      self.universalTime = YES;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  self.offsetSeconds = offset;
 | 
			
		||||
 | 
			
		||||
  // though offset seconds are authoritative, we'll retain the time zone
 | 
			
		||||
  // since we can't regenerate it reliably from just the offset
 | 
			
		||||
  timeZone_ = [tz retain];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setFromRFC3339String:(NSString *)str {
 | 
			
		||||
 | 
			
		||||
  NSInteger year = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger month = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger day = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger hour = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger minute = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger sec = NSUndefinedDateComponent;
 | 
			
		||||
  NSInteger milliseconds = 0;
 | 
			
		||||
  double secDouble = -1.0;
 | 
			
		||||
  NSString* sign = nil;
 | 
			
		||||
  NSInteger offsetHour = 0;
 | 
			
		||||
  NSInteger offsetMinute = 0;
 | 
			
		||||
 | 
			
		||||
  if ([str length] > 0) {
 | 
			
		||||
    NSScanner* scanner = [NSScanner scannerWithString:str];
 | 
			
		||||
    // There should be no whitespace, so no skip characters.
 | 
			
		||||
    [scanner setCharactersToBeSkipped:nil];
 | 
			
		||||
 | 
			
		||||
    NSCharacterSet* dashSet = [NSCharacterSet characterSetWithCharactersInString:@"-"];
 | 
			
		||||
    NSCharacterSet* tSet = [NSCharacterSet characterSetWithCharactersInString:@"Tt "];
 | 
			
		||||
    NSCharacterSet* colonSet = [NSCharacterSet characterSetWithCharactersInString:@":"];
 | 
			
		||||
    NSCharacterSet* plusMinusZSet = [NSCharacterSet characterSetWithCharactersInString:@"+-zZ"];
 | 
			
		||||
 | 
			
		||||
    // for example, scan 2006-11-17T15:10:46-08:00
 | 
			
		||||
    //                or 2006-11-17T15:10:46Z
 | 
			
		||||
    if (// yyyy-mm-dd
 | 
			
		||||
        [scanner scanInteger:&year] &&
 | 
			
		||||
        [scanner scanCharactersFromSet:dashSet intoString:NULL] &&
 | 
			
		||||
        [scanner scanInteger:&month] &&
 | 
			
		||||
        [scanner scanCharactersFromSet:dashSet intoString:NULL] &&
 | 
			
		||||
        [scanner scanInteger:&day] &&
 | 
			
		||||
        // Thh:mm:ss
 | 
			
		||||
        [scanner scanCharactersFromSet:tSet intoString:NULL] &&
 | 
			
		||||
        [scanner scanInteger:&hour] &&
 | 
			
		||||
        [scanner scanCharactersFromSet:colonSet intoString:NULL] &&
 | 
			
		||||
        [scanner scanInteger:&minute] &&
 | 
			
		||||
        [scanner scanCharactersFromSet:colonSet intoString:NULL] &&
 | 
			
		||||
        [scanner scanDouble:&secDouble]) {
 | 
			
		||||
 | 
			
		||||
      // At this point we got secDouble, pull it apart.
 | 
			
		||||
      sec = (NSInteger)secDouble;
 | 
			
		||||
      double worker = secDouble - ((double)sec);
 | 
			
		||||
      milliseconds = (NSInteger)round(worker * 1000.0);
 | 
			
		||||
 | 
			
		||||
      // Finish parsing, now the offset info.
 | 
			
		||||
      if (// Z or +hh:mm
 | 
			
		||||
          [scanner scanCharactersFromSet:plusMinusZSet intoString:&sign] &&
 | 
			
		||||
          [scanner scanInteger:&offsetHour] &&
 | 
			
		||||
          [scanner scanCharactersFromSet:colonSet intoString:NULL] &&
 | 
			
		||||
          [scanner scanInteger:&offsetMinute]) {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSDateComponents *dateComponents = [[[NSDateComponents alloc] init] autorelease];
 | 
			
		||||
  [dateComponents setYear:year];
 | 
			
		||||
  [dateComponents setMonth:month];
 | 
			
		||||
  [dateComponents setDay:day];
 | 
			
		||||
  [dateComponents setHour:hour];
 | 
			
		||||
  [dateComponents setMinute:minute];
 | 
			
		||||
  [dateComponents setSecond:sec];
 | 
			
		||||
 | 
			
		||||
  self.dateComponents = dateComponents;
 | 
			
		||||
  self.milliseconds = milliseconds;
 | 
			
		||||
  
 | 
			
		||||
  // determine the offset, like from Z, or -08:00:00.0
 | 
			
		||||
 | 
			
		||||
  self.timeZone = nil;
 | 
			
		||||
 | 
			
		||||
  NSInteger totalOffset = NSUndefinedDateComponent;
 | 
			
		||||
  self.universalTime = NO;
 | 
			
		||||
 | 
			
		||||
  if ([sign caseInsensitiveCompare:@"Z"] == NSOrderedSame) {
 | 
			
		||||
 | 
			
		||||
    self.universalTime = YES;
 | 
			
		||||
    totalOffset = 0;
 | 
			
		||||
 | 
			
		||||
  } else if (sign != nil) {
 | 
			
		||||
 | 
			
		||||
    totalOffset = (60 * offsetMinute) + (60 * 60 * offsetHour);
 | 
			
		||||
 | 
			
		||||
    if ([sign isEqual:@"-"]) {
 | 
			
		||||
 | 
			
		||||
      if (totalOffset == 0) {
 | 
			
		||||
        // special case: offset of -0.00 means undefined offset
 | 
			
		||||
        totalOffset = NSUndefinedDateComponent;
 | 
			
		||||
      } else {
 | 
			
		||||
        totalOffset *= -1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  self.offsetSeconds = totalOffset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)hasTime {
 | 
			
		||||
  NSDateComponents *dateComponents = self.dateComponents;
 | 
			
		||||
 | 
			
		||||
  BOOL hasTime = ([dateComponents hour] != NSUndefinedDateComponent
 | 
			
		||||
                  && [dateComponents minute] != NSUndefinedDateComponent);
 | 
			
		||||
 | 
			
		||||
  return hasTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setHasTime:(BOOL)shouldHaveTime {
 | 
			
		||||
 | 
			
		||||
  // we'll set time values to zero or NSUndefinedDateComponent as appropriate
 | 
			
		||||
  BOOL hadTime = self.hasTime;
 | 
			
		||||
 | 
			
		||||
  if (shouldHaveTime && !hadTime) {
 | 
			
		||||
    [dateComponents_ setHour:0];
 | 
			
		||||
    [dateComponents_ setMinute:0];
 | 
			
		||||
    [dateComponents_ setSecond:0];
 | 
			
		||||
    milliseconds_ = 0;
 | 
			
		||||
    offsetSeconds_ = NSUndefinedDateComponent;
 | 
			
		||||
    isUniversalTime_ = NO;
 | 
			
		||||
 | 
			
		||||
  } else if (hadTime && !shouldHaveTime) {
 | 
			
		||||
    [dateComponents_ setHour:NSUndefinedDateComponent];
 | 
			
		||||
    [dateComponents_ setMinute:NSUndefinedDateComponent];
 | 
			
		||||
    [dateComponents_ setSecond:NSUndefinedDateComponent];
 | 
			
		||||
    milliseconds_ = 0;
 | 
			
		||||
    offsetSeconds_ = NSUndefinedDateComponent;
 | 
			
		||||
    isUniversalTime_ = NO;
 | 
			
		||||
    self.timeZone = nil;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										128
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLDefines.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,128 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTLDefines.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Ensure Apple's conditionals we depend on are defined.
 | 
			
		||||
#import <TargetConditionals.h>
 | 
			
		||||
#import <AvailabilityMacros.h>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// The developer may choose to define these in the project:
 | 
			
		||||
//
 | 
			
		||||
//   #define GTL_TARGET_NAMESPACE Xxx  // preface all GTL class names with Xxx (recommended for building plug-ins)
 | 
			
		||||
//   #define GTL_FOUNDATION_ONLY 1     // builds without AppKit or Carbon (default for iPhone builds)
 | 
			
		||||
//   #define STRIP_GTM_FETCH_LOGGING 1 // omit http logging code (default for iPhone release builds)
 | 
			
		||||
//
 | 
			
		||||
// Mac developers may find GTL_SIMPLE_DESCRIPTIONS and STRIP_GTM_FETCH_LOGGING useful for
 | 
			
		||||
// reducing code size.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Define later OS versions when building on earlier versions
 | 
			
		||||
#ifdef MAC_OS_X_VERSION_10_0
 | 
			
		||||
  #ifndef MAC_OS_X_VERSION_10_6
 | 
			
		||||
    #define MAC_OS_X_VERSION_10_6 1060
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef GTL_TARGET_NAMESPACE
 | 
			
		||||
// prefix all GTL class names with GTL_TARGET_NAMESPACE for this target
 | 
			
		||||
  #import "GTLTargetNamespace.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Provide a common definition for externing constants/functions
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
  #define GTL_EXTERN extern "C"
 | 
			
		||||
#else
 | 
			
		||||
  #define GTL_EXTERN extern
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE // iPhone SDK
 | 
			
		||||
 | 
			
		||||
  #define GTL_IPHONE 1
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if GTL_IPHONE
 | 
			
		||||
 | 
			
		||||
  #define GTL_FOUNDATION_ONLY 1
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTL_ASSERT is like NSAssert, but takes a variable number of arguments:
 | 
			
		||||
//
 | 
			
		||||
//     GTL_ASSERT(condition, @"Problem in argument %@", argStr);
 | 
			
		||||
//
 | 
			
		||||
// GTL_DEBUG_ASSERT is similar, but compiles in only for debug builds
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef GTL_ASSERT
 | 
			
		||||
  // we directly invoke the NSAssert handler so we can pass on the varargs
 | 
			
		||||
  #if !defined(NS_BLOCK_ASSERTIONS)
 | 
			
		||||
    #define GTL_ASSERT(condition, ...)                                       \
 | 
			
		||||
      do {                                                                     \
 | 
			
		||||
        if (!(condition)) {                                                    \
 | 
			
		||||
          [[NSAssertionHandler currentHandler]                                 \
 | 
			
		||||
              handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
 | 
			
		||||
                                 file:[NSString stringWithUTF8String:__FILE__] \
 | 
			
		||||
                           lineNumber:__LINE__                                 \
 | 
			
		||||
                          description:__VA_ARGS__];                            \
 | 
			
		||||
        }                                                                      \
 | 
			
		||||
      } while(0)
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTL_ASSERT(condition, ...) do { } while (0)
 | 
			
		||||
  #endif // !defined(NS_BLOCK_ASSERTIONS)
 | 
			
		||||
#endif // GTL_ASSERT
 | 
			
		||||
 | 
			
		||||
#ifndef GTL_DEBUG_ASSERT
 | 
			
		||||
  #if DEBUG
 | 
			
		||||
    #define GTL_DEBUG_ASSERT(condition, ...) GTL_ASSERT(condition, __VA_ARGS__)
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTL_DEBUG_ASSERT(condition, ...) do { } while (0)
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef GTL_DEBUG_LOG
 | 
			
		||||
  #if DEBUG
 | 
			
		||||
    #define GTL_DEBUG_LOG(...) NSLog(__VA_ARGS__)
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTL_DEBUG_LOG(...) do { } while (0)
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef STRIP_GTM_FETCH_LOGGING
 | 
			
		||||
  #if GTL_IPHONE && !DEBUG
 | 
			
		||||
    #define STRIP_GTM_FETCH_LOGGING 1
 | 
			
		||||
  #else
 | 
			
		||||
    #define STRIP_GTM_FETCH_LOGGING 0
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Some support for advanced clang static analysis functionality
 | 
			
		||||
// See http://clang-analyzer.llvm.org/annotations.html
 | 
			
		||||
#ifndef __has_feature      // Optional.
 | 
			
		||||
  #define __has_feature(x) 0 // Compatibility with non-clang compilers.
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef NS_RETURNS_NOT_RETAINED
 | 
			
		||||
  #if __has_feature(attribute_ns_returns_not_retained)
 | 
			
		||||
    #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
 | 
			
		||||
  #else
 | 
			
		||||
    #define NS_RETURNS_NOT_RETAINED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										45
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLErrorObject.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,45 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLErrorObject.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLObject.h"
 | 
			
		||||
 | 
			
		||||
@class GTLErrorObjectData;
 | 
			
		||||
 | 
			
		||||
@interface GTLErrorObject : GTLObject
 | 
			
		||||
@property (retain) NSNumber *code;
 | 
			
		||||
@property (retain) NSString *message;
 | 
			
		||||
@property (retain) NSArray *data; // of GTLErrorObjectData
 | 
			
		||||
 | 
			
		||||
// Convenience accessor for creating an NSError from a GTLErrorObject.
 | 
			
		||||
@property (readonly) NSError *foundationError;
 | 
			
		||||
 | 
			
		||||
// Convenience accessor for extracting the GTLErrorObject that was used to
 | 
			
		||||
// create an NSError.
 | 
			
		||||
//
 | 
			
		||||
// Returns nil if the error was not originally from a GTLErrorObject.
 | 
			
		||||
+ (GTLErrorObject *)underlyingObjectForError:(NSError *)foundationError;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTLErrorObjectData : GTLObject
 | 
			
		||||
@property (retain) NSString *domain;
 | 
			
		||||
@property (retain) NSString *reason;
 | 
			
		||||
@property (retain) NSString *message;
 | 
			
		||||
@property (retain) NSString *location;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										78
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLErrorObject.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLErrorObject.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLErrorObject.h"
 | 
			
		||||
#import "GTLService.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLErrorObject
 | 
			
		||||
 | 
			
		||||
@dynamic code;
 | 
			
		||||
@dynamic message;
 | 
			
		||||
@dynamic data;
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap {
 | 
			
		||||
  NSDictionary *map = [NSDictionary dictionaryWithObject:[GTLErrorObjectData class]
 | 
			
		||||
                                                  forKey:@"data"];
 | 
			
		||||
  return map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSError *)foundationError {
 | 
			
		||||
  NSMutableDictionary *userInfo;
 | 
			
		||||
 | 
			
		||||
  // This structured GTLErrorObject will be available in the error's userInfo
 | 
			
		||||
  // dictionary
 | 
			
		||||
  userInfo = [NSMutableDictionary dictionaryWithObject:self
 | 
			
		||||
                                                forKey:kGTLStructuredErrorKey];
 | 
			
		||||
 | 
			
		||||
  NSString *reasonStr = self.message;
 | 
			
		||||
  if (reasonStr) {
 | 
			
		||||
    // We always store an error in the userInfo key "error"
 | 
			
		||||
    [userInfo setObject:reasonStr
 | 
			
		||||
                 forKey:kGTLServerErrorStringKey];
 | 
			
		||||
 | 
			
		||||
    // Store a user-readable "reason" to show up when an error is logged,
 | 
			
		||||
    // in parentheses like NSError does it
 | 
			
		||||
    NSString *parenthesized = [NSString stringWithFormat:@"(%@)", reasonStr];
 | 
			
		||||
    [userInfo setObject:parenthesized
 | 
			
		||||
                 forKey:NSLocalizedFailureReasonErrorKey];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSInteger code = [self.code integerValue];
 | 
			
		||||
  NSError *error = [NSError errorWithDomain:kGTLJSONRPCErrorDomain
 | 
			
		||||
                                       code:code
 | 
			
		||||
                                   userInfo:userInfo];
 | 
			
		||||
  return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (GTLErrorObject *)underlyingObjectForError:(NSError *)foundationError {
 | 
			
		||||
  NSDictionary *userInfo = [foundationError userInfo];
 | 
			
		||||
  GTLErrorObject *errorObj = [userInfo objectForKey:kGTLStructuredErrorKey];
 | 
			
		||||
  return errorObj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTLErrorObjectData
 | 
			
		||||
@dynamic domain;
 | 
			
		||||
@dynamic reason;
 | 
			
		||||
@dynamic message;
 | 
			
		||||
@dynamic location;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLFramework.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,35 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef _GTLFRAMEWORK_H_
 | 
			
		||||
#define _GTLFRAMEWORK_H_
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Returns the version of the framework.  Major and minor should
 | 
			
		||||
// match the bundle version in the Info.plist file.
 | 
			
		||||
//
 | 
			
		||||
// Pass NULL to ignore any of the parameters.
 | 
			
		||||
 | 
			
		||||
void GTLFrameworkVersion(NSUInteger* major, NSUInteger* minor, NSUInteger* release);
 | 
			
		||||
 | 
			
		||||
// Returns the version in @"a.b" or @"a.b.c" format
 | 
			
		||||
NSString *GTLFrameworkVersionString(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										40
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLFramework.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,40 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "GTLFramework.h"
 | 
			
		||||
 | 
			
		||||
void GTLFrameworkVersion(NSUInteger* major, NSUInteger* minor, NSUInteger* release) {
 | 
			
		||||
  // version 2.0.0
 | 
			
		||||
  if (major)   *major = 2;
 | 
			
		||||
  if (minor)   *minor = 0;
 | 
			
		||||
  if (release) *release = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSString *GTLFrameworkVersionString(void) {
 | 
			
		||||
  NSUInteger major, minor, release;
 | 
			
		||||
  NSString *libVersionString;
 | 
			
		||||
 | 
			
		||||
  GTLFrameworkVersion(&major, &minor, &release);
 | 
			
		||||
 | 
			
		||||
  // most library releases will have a release value of zero
 | 
			
		||||
  if (release != 0) {
 | 
			
		||||
    libVersionString = [NSString stringWithFormat:@"%d.%d.%d",
 | 
			
		||||
                        (int)major, (int)minor, (int)release];
 | 
			
		||||
  } else {
 | 
			
		||||
    libVersionString = [NSString stringWithFormat:@"%d.%d",
 | 
			
		||||
                        (int)major, (int)minor];
 | 
			
		||||
  }
 | 
			
		||||
  return libVersionString;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLJSONParser.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,41 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLJSONParser.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// This class is a thin wrapper around the JSON parser.  It uses
 | 
			
		||||
// NSJSONSerialization when available, and SBJSON otherwise.
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLJSONParser : NSObject
 | 
			
		||||
+ (NSString*)stringWithObject:(id)value
 | 
			
		||||
                humanReadable:(BOOL)humanReadable
 | 
			
		||||
                        error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
+ (NSData *)dataWithObject:(id)obj
 | 
			
		||||
             humanReadable:(BOOL)humanReadable
 | 
			
		||||
                     error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
+ (id)objectWithString:(NSString *)jsonStr
 | 
			
		||||
                 error:(NSError **)error;
 | 
			
		||||
 | 
			
		||||
+ (id)objectWithData:(NSData *)jsonData
 | 
			
		||||
               error:(NSError **)error;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										150
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLJSONParser.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,150 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLJSONParser.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLJSONParser.h"
 | 
			
		||||
 | 
			
		||||
// We can assume NSJSONSerialization is present on Mac OS X 10.7 and iOS 5
 | 
			
		||||
#if !defined(GTL_REQUIRES_NSJSONSERIALIZATION)
 | 
			
		||||
#if (!TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) || \
 | 
			
		||||
    (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
 | 
			
		||||
#define GTL_REQUIRES_NSJSONSERIALIZATION 1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// If GTMNSJSONSerialization is available, it is used for parsing and
 | 
			
		||||
// formatting JSON
 | 
			
		||||
#if !GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
@interface GTMNSJSONSerialization : NSObject
 | 
			
		||||
+ (NSData *)dataWithJSONObject:(id)obj options:(NSUInteger)opt error:(NSError **)error;
 | 
			
		||||
+ (id)JSONObjectWithData:(NSData *)data options:(NSUInteger)opt error:(NSError **)error;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// As a fallback, SBJSON is used for parsing and formatting JSON
 | 
			
		||||
@interface GTLSBJSON
 | 
			
		||||
- (void)setHumanReadable:(BOOL)flag;
 | 
			
		||||
- (NSString*)stringWithObject:(id)value error:(NSError**)error;
 | 
			
		||||
- (id)objectWithString:(NSString*)jsonrep error:(NSError**)error;
 | 
			
		||||
@end
 | 
			
		||||
#endif // !GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
 | 
			
		||||
@implementation GTLJSONParser
 | 
			
		||||
 | 
			
		||||
#if DEBUG && !GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
// When compiling for iOS 4 compatibility, SBJSON must be available
 | 
			
		||||
+ (void)load {
 | 
			
		||||
  Class writer = NSClassFromString(@"SBJsonWriter");
 | 
			
		||||
  Class parser = NSClassFromString(@"SBJsonParser");
 | 
			
		||||
  Class oldParser = NSClassFromString(@"SBJSON");
 | 
			
		||||
  GTL_ASSERT((oldParser != Nil)
 | 
			
		||||
             || (writer != Nil && parser != Nil),
 | 
			
		||||
             @"No parsing class found");
 | 
			
		||||
}
 | 
			
		||||
#endif // DEBUG && !GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
 | 
			
		||||
+ (NSString*)stringWithObject:(id)obj
 | 
			
		||||
                humanReadable:(BOOL)humanReadable
 | 
			
		||||
                        error:(NSError**)error {
 | 
			
		||||
  NSData *data = [self dataWithObject:obj
 | 
			
		||||
                        humanReadable:humanReadable
 | 
			
		||||
                                error:error];
 | 
			
		||||
  if (data) {
 | 
			
		||||
    NSString *jsonStr = [[[NSString alloc] initWithData:data
 | 
			
		||||
                                               encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
    return jsonStr;
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSData *)dataWithObject:(id)obj
 | 
			
		||||
             humanReadable:(BOOL)humanReadable
 | 
			
		||||
                     error:(NSError**)error {
 | 
			
		||||
  const NSUInteger kOpts = humanReadable ? (1UL << 0) : 0; // NSJSONWritingPrettyPrinted
 | 
			
		||||
 | 
			
		||||
#if GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
  NSData *data = [NSJSONSerialization dataWithJSONObject:obj
 | 
			
		||||
                                                 options:kOpts
 | 
			
		||||
                                                   error:error];
 | 
			
		||||
  return data;
 | 
			
		||||
#else
 | 
			
		||||
  Class serializer = NSClassFromString(@"NSJSONSerialization");
 | 
			
		||||
  if (serializer) {
 | 
			
		||||
    NSData *data = [serializer dataWithJSONObject:obj
 | 
			
		||||
                                          options:kOpts
 | 
			
		||||
                                            error:error];
 | 
			
		||||
    return data;
 | 
			
		||||
  } else {
 | 
			
		||||
    Class jsonWriteClass = NSClassFromString(@"SBJsonWriter");
 | 
			
		||||
    if (!jsonWriteClass) {
 | 
			
		||||
      jsonWriteClass = NSClassFromString(@"SBJSON");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (error) *error = nil;
 | 
			
		||||
 | 
			
		||||
    GTLSBJSON *writer = [[[jsonWriteClass alloc] init] autorelease];
 | 
			
		||||
    [writer setHumanReadable:humanReadable];
 | 
			
		||||
    NSString *jsonStr = [writer stringWithObject:obj
 | 
			
		||||
                                           error:error];
 | 
			
		||||
    NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
    return data;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)objectWithString:(NSString *)jsonStr
 | 
			
		||||
                 error:(NSError **)error {
 | 
			
		||||
  NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
  return [self objectWithData:data
 | 
			
		||||
                        error:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)objectWithData:(NSData *)jsonData
 | 
			
		||||
               error:(NSError **)error {
 | 
			
		||||
#if GTL_REQUIRES_NSJSONSERIALIZATION
 | 
			
		||||
  NSMutableDictionary *obj = [NSJSONSerialization JSONObjectWithData:jsonData
 | 
			
		||||
                                                             options:NSJSONReadingMutableContainers
 | 
			
		||||
                                                               error:error];
 | 
			
		||||
  return obj;
 | 
			
		||||
#else
 | 
			
		||||
  Class serializer = NSClassFromString(@"NSJSONSerialization");
 | 
			
		||||
  if (serializer) {
 | 
			
		||||
    const NSUInteger kOpts = (1UL << 0); // NSJSONReadingMutableContainers
 | 
			
		||||
    NSMutableDictionary *obj = [serializer JSONObjectWithData:jsonData
 | 
			
		||||
                                                      options:kOpts
 | 
			
		||||
                                                        error:error];
 | 
			
		||||
    return obj;
 | 
			
		||||
  } else {
 | 
			
		||||
    Class jsonParseClass = NSClassFromString(@"SBJsonParser");
 | 
			
		||||
    if (!jsonParseClass) {
 | 
			
		||||
      jsonParseClass = NSClassFromString(@"SBJSON");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (error) *error = nil;
 | 
			
		||||
 | 
			
		||||
    GTLSBJSON *parser = [[[jsonParseClass alloc] init] autorelease];
 | 
			
		||||
 | 
			
		||||
    NSString *jsonrep = [[[NSString alloc] initWithData:jsonData
 | 
			
		||||
                                               encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
    id obj = [parser objectWithString:jsonrep
 | 
			
		||||
                                error:error];
 | 
			
		||||
    return obj;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										180
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,180 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLObject.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
#import "GTLUtilities.h"
 | 
			
		||||
#import "GTLDateTime.h"
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTLOBJECT_DEFINE_GLOBALS
 | 
			
		||||
#define _EXTERN
 | 
			
		||||
#define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
#define _EXTERN extern
 | 
			
		||||
#define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@protocol GTLCollectionProtocol
 | 
			
		||||
@optional
 | 
			
		||||
@property (retain) NSArray *items;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol GTLBatchItemCreationProtocol
 | 
			
		||||
- (void)createItemsWithClassMap:(NSDictionary *)batchClassMap;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTLObject : NSObject <NSCopying> {
 | 
			
		||||
 | 
			
		||||
 @private
 | 
			
		||||
 | 
			
		||||
  NSMutableDictionary *json_;
 | 
			
		||||
 | 
			
		||||
  // 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.
 | 
			
		||||
  NSMutableDictionary *childCache_;
 | 
			
		||||
 | 
			
		||||
  // Anything defined by the client; retained but not used internally; not
 | 
			
		||||
  // copied by copyWithZone:
 | 
			
		||||
  NSMutableDictionary *userProperties_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) NSMutableDictionary *JSON;
 | 
			
		||||
@property (nonatomic, retain) NSDictionary *surrogates;
 | 
			
		||||
@property (nonatomic, retain) NSMutableDictionary *userProperties;
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Public methods
 | 
			
		||||
//
 | 
			
		||||
// These methods are intended for users of the library
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
+ (id)object;
 | 
			
		||||
+ (id)objectWithJSON:(NSMutableDictionary *)dict;
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone;
 | 
			
		||||
 | 
			
		||||
- (NSString *)JSONString;
 | 
			
		||||
 | 
			
		||||
// generic access to json; also creates it if necessary
 | 
			
		||||
- (void)setJSONValue:(id)obj forKey:(NSString *)key;
 | 
			
		||||
- (id)JSONValueForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
// Returns the list of keys in this object's JSON that aren't listed as
 | 
			
		||||
// properties on the object.
 | 
			
		||||
- (NSArray *)additionalJSONKeys;
 | 
			
		||||
 | 
			
		||||
// Any keys in the JSON that aren't listed as @properties on the object
 | 
			
		||||
// are counted as "additional properties".  These allow you to get/set them.
 | 
			
		||||
- (id)additionalPropertyForName:(NSString *)name;
 | 
			
		||||
- (void)setAdditionalProperty:(id)obj forName:(NSString *)name;
 | 
			
		||||
- (NSDictionary *)additionalProperties;
 | 
			
		||||
 | 
			
		||||
// User properties are supported for client convenience, but are not copied by
 | 
			
		||||
// copyWithZone.  User Properties keys beginning with _ are reserved by the library.
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
 | 
			
		||||
- (id)propertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
// userData is stored as a property with key "_userData"
 | 
			
		||||
- (void)setUserData:(id)obj;
 | 
			
		||||
- (id)userData;
 | 
			
		||||
 | 
			
		||||
// Makes a partial query-compatible string describing the fields present
 | 
			
		||||
// in this object. (Note: only the first element of any array is examined.)
 | 
			
		||||
//
 | 
			
		||||
// http://code.google.com/apis/tasks/v1/performance.html#partial
 | 
			
		||||
//
 | 
			
		||||
- (NSString *)fieldsDescription;
 | 
			
		||||
 | 
			
		||||
// Makes an object containing only the changes needed to do a partial update
 | 
			
		||||
// (patch), where the patch would be to change an object from the original
 | 
			
		||||
// to the receiver, such as
 | 
			
		||||
//
 | 
			
		||||
// GTLSomeObject *patchObject = [newVersion patchObjectFromOriginal:oldVersion];
 | 
			
		||||
//
 | 
			
		||||
// http://code.google.com/apis/tasks/v1/performance.html#patch
 | 
			
		||||
//
 | 
			
		||||
// NOTE: this method returns nil if there are no changes between the original
 | 
			
		||||
// and the receiver.
 | 
			
		||||
- (id)patchObjectFromOriginal:(GTLObject *)original;
 | 
			
		||||
 | 
			
		||||
// Method creating a null value to set object properties for patch queries that
 | 
			
		||||
// delete fields.  Do not use this except when setting an object property for
 | 
			
		||||
// a patch query.
 | 
			
		||||
+ (id)nullValue;
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Protected methods
 | 
			
		||||
//
 | 
			
		||||
// These methods are intended for subclasses of GTLObject
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// class registration ("kind" strings) for subclasses
 | 
			
		||||
+ (Class)registeredObjectClassForKind:(NSString *)kind;
 | 
			
		||||
+ (void)registerObjectClassForKind:(NSString *)kind;
 | 
			
		||||
 | 
			
		||||
// creation of objects from a JSON dictionary
 | 
			
		||||
+ (GTLObject *)objectForJSON:(NSMutableDictionary *)json
 | 
			
		||||
                defaultClass:(Class)defaultClass
 | 
			
		||||
                  surrogates:(NSDictionary *)surrogates
 | 
			
		||||
               batchClassMap:(NSDictionary *)batchClassMap;
 | 
			
		||||
 | 
			
		||||
// property-to-key mapping (for JSON keys which are not used as method names)
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMap;
 | 
			
		||||
 | 
			
		||||
// property-to-Class mapping for array properties (to say what is in the array)
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap;
 | 
			
		||||
 | 
			
		||||
// The default class for additional JSON keys
 | 
			
		||||
+ (Class)classForAdditionalProperties;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// Collection objects with an "items" property should derive from GTLCollection
 | 
			
		||||
// object.  This provides support for fast object enumeration and the
 | 
			
		||||
// itemAtIndex: convenience method.
 | 
			
		||||
//
 | 
			
		||||
// Subclasses must implement the items method dynamically.
 | 
			
		||||
@interface GTLCollectionObject : GTLObject <GTLCollectionProtocol, NSFastEnumeration>
 | 
			
		||||
 | 
			
		||||
// itemAtIndex: returns nil when the index exceeds the bounds of the items array
 | 
			
		||||
- (id)itemAtIndex:(NSUInteger)idx;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTLCollectionObject (DynamicMethods)
 | 
			
		||||
- (NSArray *)items;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// Base object use for when an service method directly returns an array instead
 | 
			
		||||
// of an object. Normally methods should return an object with an 'items'
 | 
			
		||||
// property, this exists for the methods not up to spec.
 | 
			
		||||
@interface GTLResultArray : GTLCollectionObject
 | 
			
		||||
// This method should only be called by subclasses.
 | 
			
		||||
- (NSArray *)itemsWithItemClass:(Class)itemClass;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										691
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLObject.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,691 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLObject.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#define GTLOBJECT_DEFINE_GLOBALS 1
 | 
			
		||||
 | 
			
		||||
#include <objc/runtime.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLObject.h"
 | 
			
		||||
#import "GTLRuntimeCommon.h"
 | 
			
		||||
#import "GTLJSONParser.h"
 | 
			
		||||
 | 
			
		||||
static NSString *const kUserDataPropertyKey = @"_userData";
 | 
			
		||||
 | 
			
		||||
@interface GTLObject () <GTLRuntimeCommon>
 | 
			
		||||
+ (NSMutableArray *)allDeclaredProperties;
 | 
			
		||||
+ (NSArray *)allKnownKeys;
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)fieldsElementsForJSON:(NSDictionary *)targetJSON;
 | 
			
		||||
+ (NSString *)fieldsDescriptionForJSON:(NSDictionary *)targetJSON;
 | 
			
		||||
 | 
			
		||||
+ (NSMutableDictionary *)patchDictionaryForJSON:(NSDictionary *)newJSON
 | 
			
		||||
                               fromOriginalJSON:(NSDictionary *)originalJSON;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTLObject
 | 
			
		||||
 | 
			
		||||
@synthesize JSON = json_,
 | 
			
		||||
            surrogates = surrogates_,
 | 
			
		||||
            userProperties = userProperties_;
 | 
			
		||||
 | 
			
		||||
+ (id)object {
 | 
			
		||||
  return [[[self alloc] init] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)objectWithJSON:(NSMutableDictionary *)dict {
 | 
			
		||||
  GTLObject *obj = [self object];
 | 
			
		||||
  obj.JSON = dict;
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMap {
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap {
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (Class)classForAdditionalProperties {
 | 
			
		||||
  return Nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isEqual:(GTLObject *)other {
 | 
			
		||||
  if (self == other) return YES;
 | 
			
		||||
  if (other == nil) return NO;
 | 
			
		||||
 | 
			
		||||
  // The objects should be the same class, or one should be a subclass of the
 | 
			
		||||
  // other's class
 | 
			
		||||
  if (![other isKindOfClass:[self class]]
 | 
			
		||||
      && ![self isKindOfClass:[other class]]) return NO;
 | 
			
		||||
 | 
			
		||||
  // What we're not comparing here:
 | 
			
		||||
  //   properties
 | 
			
		||||
  return GTL_AreEqualOrBothNil(json_, [other JSON]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// By definition, for two objects to potentially be considered equal,
 | 
			
		||||
// they must have the same hash value.  The hash is mostly ignored,
 | 
			
		||||
// but removeObjectsInArray: in Leopard does seem to check the hash,
 | 
			
		||||
// and NSObject's default hash method just returns the instance pointer.
 | 
			
		||||
// We'll define hash here for all of our GTLObjects.
 | 
			
		||||
- (NSUInteger)hash {
 | 
			
		||||
  return (NSUInteger) (void *) [GTLObject class];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone {
 | 
			
		||||
  GTLObject* newObject = [[[self class] allocWithZone:zone] init];
 | 
			
		||||
  CFPropertyListRef ref = CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
 | 
			
		||||
                    json_, kCFPropertyListMutableContainers);
 | 
			
		||||
  GTL_DEBUG_ASSERT(ref != NULL, @"GTLObject: copy failed (probably a non-plist type in the JSON)");
 | 
			
		||||
  newObject.JSON = [NSMakeCollectable(ref) autorelease];
 | 
			
		||||
  newObject.surrogates = self.surrogates;
 | 
			
		||||
 | 
			
		||||
  // What we're not copying:
 | 
			
		||||
  //   userProperties
 | 
			
		||||
  return newObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)descriptionWithLocale:(id)locale {
 | 
			
		||||
  return [self description];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [json_ release];
 | 
			
		||||
  [surrogates_ release];
 | 
			
		||||
  [childCache_ release];
 | 
			
		||||
  [userProperties_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark JSON values
 | 
			
		||||
 | 
			
		||||
- (void)setJSONValue:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  NSMutableDictionary *dict = self.JSON;
 | 
			
		||||
  if (dict == nil && obj != nil) {
 | 
			
		||||
    dict = [NSMutableDictionary dictionaryWithCapacity:1];
 | 
			
		||||
    self.JSON = dict;
 | 
			
		||||
  }
 | 
			
		||||
  [dict setValue:obj forKey:key];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)JSONValueForKey:(NSString *)key {
 | 
			
		||||
  id obj = [self.JSON objectForKey:key];
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)JSONString {
 | 
			
		||||
  NSError *error = nil;
 | 
			
		||||
  NSString *str = [GTLJSONParser stringWithObject:[self JSON]
 | 
			
		||||
                                    humanReadable:YES
 | 
			
		||||
                                            error:&error];
 | 
			
		||||
  if (error) {
 | 
			
		||||
    return [error description];
 | 
			
		||||
  }
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSArray *)additionalJSONKeys {
 | 
			
		||||
  NSArray *knownKeys = [[self class] allKnownKeys];
 | 
			
		||||
  NSMutableArray *result = [NSMutableArray arrayWithArray:[json_ allKeys]];
 | 
			
		||||
  [result removeObjectsInArray:knownKeys];
 | 
			
		||||
  // Return nil instead of an empty array.
 | 
			
		||||
  if ([result count] == 0) {
 | 
			
		||||
    result = nil;
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Partial - Fields
 | 
			
		||||
 | 
			
		||||
- (NSString *)fieldsDescription {
 | 
			
		||||
  NSString *str = [GTLObject fieldsDescriptionForJSON:self.JSON];
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)fieldsDescriptionForJSON:(NSDictionary *)targetJSON {
 | 
			
		||||
  // Internal routine: recursively generate a string field description
 | 
			
		||||
  // by joining elements
 | 
			
		||||
  NSArray *array = [self fieldsElementsForJSON:targetJSON];
 | 
			
		||||
  NSString *str = [array componentsJoinedByString:@","];
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)fieldsElementsForJSON:(NSDictionary *)targetJSON {
 | 
			
		||||
  // Internal routine: recursively generate an array of field description
 | 
			
		||||
  // element strings
 | 
			
		||||
  NSMutableArray *resultFields = [NSMutableArray array];
 | 
			
		||||
 | 
			
		||||
  // Sorting the dictionary keys gives us deterministic results when iterating
 | 
			
		||||
  NSArray *sortedKeys = [[targetJSON allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
 | 
			
		||||
  for (NSString *key in sortedKeys) {
 | 
			
		||||
    // We'll build a comma-separated list of fields
 | 
			
		||||
    id value = [targetJSON objectForKey:key];
 | 
			
		||||
    if ([value isKindOfClass:[NSString class]]
 | 
			
		||||
        || [value isKindOfClass:[NSNumber class]]) {
 | 
			
		||||
      // Basic type (string, number), so the key is what we want
 | 
			
		||||
      [resultFields addObject:key];
 | 
			
		||||
    } else if ([value isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
      // Object (dictionary): "parent/child1,parent/child2,parent/child3"
 | 
			
		||||
      NSArray *subElements = [self fieldsElementsForJSON:value];
 | 
			
		||||
      for (NSString *subElem in subElements) {
 | 
			
		||||
        NSString *prepended = [NSString stringWithFormat:@"%@/%@",
 | 
			
		||||
                               key, subElem];
 | 
			
		||||
        [resultFields addObject:prepended];
 | 
			
		||||
      }
 | 
			
		||||
    } else if ([value isKindOfClass:[NSArray class]]) {
 | 
			
		||||
      // Array; we'll generate from the first array entry:
 | 
			
		||||
      // "parent(child1,child2,child3)"
 | 
			
		||||
      //
 | 
			
		||||
      // Open question: should this instead create the union of elements for
 | 
			
		||||
      // all items in the array, rather than just get fields from the first
 | 
			
		||||
      // array object?
 | 
			
		||||
      if ([value count] > 0) {
 | 
			
		||||
        id firstObj = [value objectAtIndex:0];
 | 
			
		||||
        if ([firstObj isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
          // An array of objects
 | 
			
		||||
          NSString *contentsStr = [self fieldsDescriptionForJSON:firstObj];
 | 
			
		||||
          NSString *encapsulated = [NSString stringWithFormat:@"%@(%@)",
 | 
			
		||||
                                    key, contentsStr];
 | 
			
		||||
          [resultFields addObject:encapsulated];
 | 
			
		||||
        } else {
 | 
			
		||||
          // An array of some basic type, or of arrays
 | 
			
		||||
          [resultFields addObject:key];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      GTL_ASSERT(0, @"GTLObject unknown field element for %@ (%@)",
 | 
			
		||||
                 key, NSStringFromClass([value class]));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return resultFields;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Partial - Patch
 | 
			
		||||
 | 
			
		||||
- (id)patchObjectFromOriginal:(GTLObject *)original {
 | 
			
		||||
  id resultObj;
 | 
			
		||||
  NSMutableDictionary *resultJSON = [GTLObject patchDictionaryForJSON:self.JSON
 | 
			
		||||
                                                     fromOriginalJSON:original.JSON];
 | 
			
		||||
  if ([resultJSON count] > 0) {
 | 
			
		||||
    resultObj = [[self class] objectWithJSON:resultJSON];
 | 
			
		||||
  } else {
 | 
			
		||||
    // Client apps should not attempt to patch with an object containing
 | 
			
		||||
    // empty JSON
 | 
			
		||||
    resultObj = nil;
 | 
			
		||||
  }
 | 
			
		||||
  return resultObj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSMutableDictionary *)patchDictionaryForJSON:(NSDictionary *)newJSON
 | 
			
		||||
                               fromOriginalJSON:(NSDictionary *)originalJSON {
 | 
			
		||||
  // Internal recursive routine to create an object suitable for
 | 
			
		||||
  // our patch semantics
 | 
			
		||||
  NSMutableDictionary *resultJSON = [NSMutableDictionary dictionary];
 | 
			
		||||
 | 
			
		||||
  // Iterate through keys present in the old object
 | 
			
		||||
  NSArray *originalKeys = [originalJSON allKeys];
 | 
			
		||||
  for (NSString *key in originalKeys) {
 | 
			
		||||
    id originalValue = [originalJSON objectForKey:key];
 | 
			
		||||
    id newValue = [newJSON valueForKey:key];
 | 
			
		||||
    if (newValue == nil) {
 | 
			
		||||
      // There is no new value for this key, so set the value to NSNull
 | 
			
		||||
      [resultJSON setValue:[NSNull null] forKey:key];
 | 
			
		||||
    } else if (!GTL_AreEqualOrBothNil(originalValue, newValue)) {
 | 
			
		||||
      // The values for this key differ
 | 
			
		||||
      if ([originalValue isKindOfClass:[NSDictionary class]]
 | 
			
		||||
          && [newValue isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
        // Both are objects; recurse
 | 
			
		||||
        NSMutableDictionary *subDict = [self patchDictionaryForJSON:newValue
 | 
			
		||||
                                                   fromOriginalJSON:originalValue];
 | 
			
		||||
        [resultJSON setValue:subDict forKey:key];
 | 
			
		||||
      } else {
 | 
			
		||||
        // They are non-object values; the new replaces the old. Per the
 | 
			
		||||
        // documentation for patch, this replaces entire arrays.
 | 
			
		||||
        [resultJSON setValue:newValue forKey:key];
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // The values are the same; omit this key-value pair
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Iterate through keys present only in the new object, and add them to the
 | 
			
		||||
  // result
 | 
			
		||||
  NSMutableArray *newKeys = [NSMutableArray arrayWithArray:[newJSON allKeys]];
 | 
			
		||||
  [newKeys removeObjectsInArray:originalKeys];
 | 
			
		||||
 | 
			
		||||
  for (NSString *key in newKeys) {
 | 
			
		||||
    id value = [newJSON objectForKey:key];
 | 
			
		||||
    [resultJSON setValue:value forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
  return resultJSON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)nullValue {
 | 
			
		||||
  return [NSNull null];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Additional Properties
 | 
			
		||||
 | 
			
		||||
- (id)additionalPropertyForName:(NSString *)name {
 | 
			
		||||
  // Return the cached object, if any, before creating one.
 | 
			
		||||
  id result = [self cacheChildForKey:name];
 | 
			
		||||
  if (result != nil) {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Class defaultClass = [[self class] classForAdditionalProperties];
 | 
			
		||||
  id jsonObj = [self JSONValueForKey:name];
 | 
			
		||||
  BOOL shouldCache = NO;
 | 
			
		||||
  if (jsonObj != nil) {
 | 
			
		||||
    NSDictionary *surrogates = self.surrogates;
 | 
			
		||||
    result = [GTLRuntimeCommon objectFromJSON:jsonObj
 | 
			
		||||
                                 defaultClass:defaultClass
 | 
			
		||||
                                   surrogates:surrogates
 | 
			
		||||
                                  isCacheable:&shouldCache];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [self setCacheChild:(shouldCache ? result : nil)
 | 
			
		||||
               forKey:name];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAdditionalProperty:(id)obj forName:(NSString *)name {
 | 
			
		||||
  BOOL shouldCache = NO;
 | 
			
		||||
  Class defaultClass = [[self class] classForAdditionalProperties];
 | 
			
		||||
  id json = [GTLRuntimeCommon jsonFromAPIObject:obj
 | 
			
		||||
                                  expectedClass:defaultClass
 | 
			
		||||
                                    isCacheable:&shouldCache];
 | 
			
		||||
  [self setJSONValue:json forKey:name];
 | 
			
		||||
  [self setCacheChild:(shouldCache ? obj : nil)
 | 
			
		||||
               forKey:name];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)additionalProperties {
 | 
			
		||||
  NSMutableDictionary *result = [NSMutableDictionary dictionary];
 | 
			
		||||
 | 
			
		||||
  NSArray *propertyNames = [self additionalJSONKeys];
 | 
			
		||||
  for (NSString *name in propertyNames) {
 | 
			
		||||
    id obj = [self additionalPropertyForName:name];
 | 
			
		||||
    [result setObject:obj forKey:name];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Child Cache methods
 | 
			
		||||
 | 
			
		||||
// There is no property for childCache_ as there shouldn't be KVC/KVO
 | 
			
		||||
// support for it, it's an implementation detail.
 | 
			
		||||
 | 
			
		||||
- (void)setCacheChild:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  if (childCache_ == nil && obj != nil) {
 | 
			
		||||
    childCache_ = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
 | 
			
		||||
                   obj, key, nil];
 | 
			
		||||
  } else {
 | 
			
		||||
    [childCache_ setValue:obj forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)cacheChildForKey:(NSString *)key {
 | 
			
		||||
  id obj = [childCache_ objectForKey:key];
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark userData and user properties
 | 
			
		||||
 | 
			
		||||
- (void)setUserData:(id)userData {
 | 
			
		||||
  [self setProperty:userData forKey:kUserDataPropertyKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)userData {
 | 
			
		||||
  // be sure the returned pointer has the life of the autorelease pool,
 | 
			
		||||
  // in case self is released immediately
 | 
			
		||||
  return [[[self propertyForKey:kUserDataPropertyKey] retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  if (obj == nil) {
 | 
			
		||||
    // user passed in nil, so delete the property
 | 
			
		||||
    [userProperties_ removeObjectForKey:key];
 | 
			
		||||
  } else {
 | 
			
		||||
    // be sure the property dictionary exists
 | 
			
		||||
    if (userProperties_ == nil) {
 | 
			
		||||
      self.userProperties = [NSMutableDictionary dictionary];
 | 
			
		||||
    }
 | 
			
		||||
    [userProperties_ setObject:obj forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)propertyForKey:(NSString *)key {
 | 
			
		||||
  id obj = [userProperties_ objectForKey:key];
 | 
			
		||||
 | 
			
		||||
  // be sure the returned pointer has the life of the autorelease pool,
 | 
			
		||||
  // in case self is released immediately
 | 
			
		||||
  return [[obj retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Support methods
 | 
			
		||||
 | 
			
		||||
+ (NSMutableArray *)allDeclaredProperties {
 | 
			
		||||
  NSMutableArray *array = [NSMutableArray array];
 | 
			
		||||
 | 
			
		||||
  // walk from this class up the hierarchy to GTLObject
 | 
			
		||||
  Class topClass = class_getSuperclass([GTLObject class]);
 | 
			
		||||
  for (Class currClass = self;
 | 
			
		||||
       currClass != topClass;
 | 
			
		||||
       currClass = class_getSuperclass(currClass)) {
 | 
			
		||||
    // step through this class's properties, and add the property names to the
 | 
			
		||||
    // array
 | 
			
		||||
    objc_property_t *properties = class_copyPropertyList(currClass, NULL);
 | 
			
		||||
    if (properties) {
 | 
			
		||||
      for (objc_property_t *prop = properties;
 | 
			
		||||
           *prop != NULL;
 | 
			
		||||
           ++prop) {
 | 
			
		||||
        const char *propName = property_getName(*prop);
 | 
			
		||||
        // We only want dynamic properties; their attributes contain ",D".
 | 
			
		||||
        const char *attr = property_getAttributes(*prop);
 | 
			
		||||
        const char *dynamicMarker = strstr(attr, ",D");
 | 
			
		||||
        if (dynamicMarker &&
 | 
			
		||||
            (dynamicMarker[2] == 0 || dynamicMarker[2] == ',' )) {
 | 
			
		||||
          [array addObject:[NSString stringWithUTF8String:propName]];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      free(properties);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return array;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)allKnownKeys {
 | 
			
		||||
  NSArray *allProps = [self allDeclaredProperties];
 | 
			
		||||
  NSMutableArray *knownKeys = [NSMutableArray arrayWithArray:allProps];
 | 
			
		||||
 | 
			
		||||
  NSDictionary *propMap = [GTLObject propertyToJSONKeyMapForClass:[self class]];
 | 
			
		||||
 | 
			
		||||
  NSUInteger idx = 0;
 | 
			
		||||
  for (NSString *propName in allProps) {
 | 
			
		||||
    NSString *jsonKey = [propMap objectForKey:propName];
 | 
			
		||||
    if (jsonKey) {
 | 
			
		||||
      [knownKeys replaceObjectAtIndex:idx
 | 
			
		||||
                           withObject:jsonKey];
 | 
			
		||||
    }
 | 
			
		||||
    ++idx;
 | 
			
		||||
  }
 | 
			
		||||
  return knownKeys;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  // find the list of declared and otherwise known JSON keys for this class
 | 
			
		||||
  NSArray *knownKeys = [[self class] allKnownKeys];
 | 
			
		||||
 | 
			
		||||
  NSMutableString *descStr = [NSMutableString string];
 | 
			
		||||
 | 
			
		||||
  NSString *spacer = @"";
 | 
			
		||||
  for (NSString *key in json_) {
 | 
			
		||||
    NSString *value = nil;
 | 
			
		||||
    // show question mark for JSON keys not supported by a declared property:
 | 
			
		||||
    //   foo?:"Hi mom."
 | 
			
		||||
    NSString *qmark = [knownKeys containsObject:key] ? @"" : @"?";
 | 
			
		||||
 | 
			
		||||
    // determine property value to dislay
 | 
			
		||||
    id rawValue = [json_ valueForKey:key];
 | 
			
		||||
    if ([rawValue isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
      // for dictionaries, show the list of keys:
 | 
			
		||||
      //   {key1,key2,key3}
 | 
			
		||||
      NSString *subkeyList = [[rawValue allKeys] componentsJoinedByString:@","];
 | 
			
		||||
      value = [NSString stringWithFormat:@"{%@}", subkeyList];
 | 
			
		||||
    } else if ([rawValue isKindOfClass:[NSArray class]]) {
 | 
			
		||||
      // for arrays, show the number of items in the array:
 | 
			
		||||
      //   [3]
 | 
			
		||||
      value = [NSString stringWithFormat:@"[%lu]", (unsigned long)[rawValue count]];
 | 
			
		||||
    } else if ([rawValue isKindOfClass:[NSString class]]) {
 | 
			
		||||
      // for strings, show the string in quotes:
 | 
			
		||||
      //   "Hi mom."
 | 
			
		||||
      value = [NSString stringWithFormat:@"\"%@\"", rawValue];
 | 
			
		||||
    } else {
 | 
			
		||||
      // for numbers, show just the number
 | 
			
		||||
      value = [rawValue description];
 | 
			
		||||
    }
 | 
			
		||||
    [descStr appendFormat:@"%@%@%@:%@", spacer, key, qmark, value];
 | 
			
		||||
    spacer = @" ";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *str = [NSString stringWithFormat:@"%@ %p: {%@}",
 | 
			
		||||
                   [self class], self, descStr];
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Class Registration
 | 
			
		||||
 | 
			
		||||
static NSMutableDictionary *gKindMap = nil;
 | 
			
		||||
 | 
			
		||||
+ (Class)registeredObjectClassForKind:(NSString *)kind {
 | 
			
		||||
  Class resultClass = [gKindMap objectForKey:kind];
 | 
			
		||||
  return resultClass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (void)registerObjectClassForKind:(NSString *)kind {
 | 
			
		||||
  // there's no autorelease pool in place at +load time, so we'll create our own
 | 
			
		||||
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | 
			
		||||
 | 
			
		||||
  if (gKindMap == nil) {
 | 
			
		||||
    gKindMap = [GTLUtilities newStaticDictionary];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Class selfClass = [self class];
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  // ensure this is a unique registration
 | 
			
		||||
  if ([gKindMap objectForKey:kind] != nil ) {
 | 
			
		||||
    GTL_DEBUG_LOG(@"%@ (%@) registration conflicts with %@",
 | 
			
		||||
                  selfClass, kind, [gKindMap objectForKey:kind]);
 | 
			
		||||
  }
 | 
			
		||||
  if ([[gKindMap allKeysForObject:selfClass] count] != 0) {
 | 
			
		||||
    GTL_DEBUG_LOG(@"%@ (%@) registration conflicts with %@",
 | 
			
		||||
                  selfClass, kind, [gKindMap allKeysForObject:selfClass]);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  [gKindMap setValue:selfClass forKey:kind];
 | 
			
		||||
 | 
			
		||||
  // we drain here to keep the clang static analyzer quiet
 | 
			
		||||
  [pool drain];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Object Instantiation
 | 
			
		||||
 | 
			
		||||
+ (GTLObject *)objectForJSON:(NSMutableDictionary *)json
 | 
			
		||||
                defaultClass:(Class)defaultClass
 | 
			
		||||
                  surrogates:(NSDictionary *)surrogates
 | 
			
		||||
               batchClassMap:(NSDictionary *)batchClassMap {
 | 
			
		||||
  if ([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
 | 
			
		||||
  //
 | 
			
		||||
  // We're letting the dynamic kind override the default class so
 | 
			
		||||
  // feeds of heterogenous entries can use the defaultClass as a
 | 
			
		||||
  // fallback
 | 
			
		||||
  Class classToCreate = defaultClass;
 | 
			
		||||
  NSString *kind = nil;
 | 
			
		||||
  if ([json isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
    kind = [json valueForKey:@"kind"];
 | 
			
		||||
    if ([kind isKindOfClass:[NSString class]] && [kind length] > 0) {
 | 
			
		||||
      Class dynamicClass = [GTLObject registeredObjectClassForKind:kind];
 | 
			
		||||
      if (dynamicClass) {
 | 
			
		||||
        classToCreate = dynamicClass;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Warn the developer that no specific class of GTLObject
 | 
			
		||||
  // was requested with the fetch call, and no class is found
 | 
			
		||||
  // compiled in to match the "kind" attribute of the JSON
 | 
			
		||||
  // returned by the server
 | 
			
		||||
  GTL_ASSERT(classToCreate != nil,
 | 
			
		||||
             @"Could not find registered GTLObject subclass to "
 | 
			
		||||
             "match JSON with kind \"%@\"", kind);
 | 
			
		||||
 | 
			
		||||
  if (classToCreate == nil) {
 | 
			
		||||
    classToCreate = [self class];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // See if the top-level class for the JSON is listed in the surrogates;
 | 
			
		||||
  // if so, instantiate the surrogate class instead
 | 
			
		||||
  Class baseSurrogate = [surrogates objectForKey:classToCreate];
 | 
			
		||||
  if (baseSurrogate) {
 | 
			
		||||
    classToCreate = baseSurrogate;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // now instantiate the GTLObject
 | 
			
		||||
  GTLObject *parsedObject = [classToCreate object];
 | 
			
		||||
 | 
			
		||||
  parsedObject.surrogates = surrogates;
 | 
			
		||||
  parsedObject.JSON = json;
 | 
			
		||||
 | 
			
		||||
  // it's time to instantiate inner items
 | 
			
		||||
  if ([parsedObject conformsToProtocol:@protocol(GTLBatchItemCreationProtocol)]) {
 | 
			
		||||
    id <GTLBatchItemCreationProtocol> batch =
 | 
			
		||||
      (id <GTLBatchItemCreationProtocol>) parsedObject;
 | 
			
		||||
    [batch createItemsWithClassMap:batchClassMap];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return parsedObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Runtime Utilities
 | 
			
		||||
 | 
			
		||||
static NSMutableDictionary *gJSONKeyMapCache = nil;
 | 
			
		||||
static NSMutableDictionary *gArrayPropertyToClassMapCache = nil;
 | 
			
		||||
 | 
			
		||||
+ (void)initialize {
 | 
			
		||||
  // Note that initialize is guaranteed by the runtime to be called in a
 | 
			
		||||
  // thread-safe manner
 | 
			
		||||
  if (gJSONKeyMapCache == nil) {
 | 
			
		||||
    gJSONKeyMapCache = [GTLUtilities newStaticDictionary];
 | 
			
		||||
  }
 | 
			
		||||
  if (gArrayPropertyToClassMapCache == nil) {
 | 
			
		||||
    gArrayPropertyToClassMapCache = [GTLUtilities newStaticDictionary];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRuntimeCommon>)aClass {
 | 
			
		||||
  NSDictionary *resultMap =
 | 
			
		||||
    [GTLUtilities mergedClassDictionaryForSelector:@selector(propertyToJSONKeyMap)
 | 
			
		||||
                                        startClass:aClass
 | 
			
		||||
                                     ancestorClass:[GTLObject class]
 | 
			
		||||
                                             cache:gJSONKeyMapCache];
 | 
			
		||||
  return resultMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRuntimeCommon>)aClass {
 | 
			
		||||
  NSDictionary *resultMap =
 | 
			
		||||
    [GTLUtilities mergedClassDictionaryForSelector:@selector(arrayPropertyToClassMap)
 | 
			
		||||
                                        startClass:aClass
 | 
			
		||||
                                     ancestorClass:[GTLObject class]
 | 
			
		||||
                                             cache:gArrayPropertyToClassMapCache];
 | 
			
		||||
  return resultMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Runtime Support
 | 
			
		||||
 | 
			
		||||
+ (Class<GTLRuntimeCommon>)ancestorClass {
 | 
			
		||||
  return [GTLObject class];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (BOOL)resolveInstanceMethod:(SEL)sel {
 | 
			
		||||
  BOOL resolved = [GTLRuntimeCommon resolveInstanceMethod:sel onClass:self];
 | 
			
		||||
  if (resolved)
 | 
			
		||||
    return YES;
 | 
			
		||||
 | 
			
		||||
  return [super resolveInstanceMethod:sel];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTLCollectionObject
 | 
			
		||||
 | 
			
		||||
// Subclasses must implement the items method dynamically.
 | 
			
		||||
 | 
			
		||||
- (id)itemAtIndex:(NSUInteger)idx {
 | 
			
		||||
  NSArray *items = [self performSelector:@selector(items)];
 | 
			
		||||
  if (idx < [items count]) {
 | 
			
		||||
    return [items objectAtIndex:idx];
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NSFastEnumeration protocol
 | 
			
		||||
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
 | 
			
		||||
                                  objects:(id *)stackbuf
 | 
			
		||||
                                    count:(NSUInteger)len {
 | 
			
		||||
  NSArray *items = [self performSelector:@selector(items)];
 | 
			
		||||
  NSUInteger result = [items countByEnumeratingWithState:state
 | 
			
		||||
                                                 objects:stackbuf
 | 
			
		||||
                                                   count:len];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTLResultArray
 | 
			
		||||
 | 
			
		||||
- (NSArray *)itemsWithItemClass:(Class)itemClass {
 | 
			
		||||
  // Return the cached array before creating on demand.
 | 
			
		||||
  NSString *cacheKey = @"result_array_items";
 | 
			
		||||
  NSMutableArray *cachedArray = [self cacheChildForKey:cacheKey];
 | 
			
		||||
  if (cachedArray != nil) {
 | 
			
		||||
    return cachedArray;
 | 
			
		||||
  }
 | 
			
		||||
  NSArray *result = nil;
 | 
			
		||||
  NSArray *array = (NSArray *)[self JSON];
 | 
			
		||||
  if (array != nil) {
 | 
			
		||||
    if ([array isKindOfClass:[NSArray class]]) {
 | 
			
		||||
      NSDictionary *surrogates = self.surrogates;
 | 
			
		||||
      result = [GTLRuntimeCommon objectFromJSON:array
 | 
			
		||||
                                   defaultClass:itemClass
 | 
			
		||||
                                     surrogates:surrogates
 | 
			
		||||
                                    isCacheable:NULL];
 | 
			
		||||
    } else {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
      if (![array isKindOfClass:[NSNull class]]) {
 | 
			
		||||
        GTL_DEBUG_LOG(@"GTLObject: unexpected JSON: %@ should be an array, actually is a %@:\n%@",
 | 
			
		||||
                      NSStringFromClass([self class]),
 | 
			
		||||
                      NSStringFromClass([array class]),
 | 
			
		||||
                      array);
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
      result = array;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [self setCacheChild:result forKey:cacheKey];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										36
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlus.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,36 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlus.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/
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusConstants.h"
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusItemScope.h"
 | 
			
		||||
#import "GTLPlusMoment.h"
 | 
			
		||||
#import "GTLPlusPerson.h"
 | 
			
		||||
 | 
			
		||||
#import "GTLQueryPlus.h"
 | 
			
		||||
#import "GTLServicePlus.h"
 | 
			
		||||
							
								
								
									
										46
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,46 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusConstants.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/
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#if GTL_BUILT_AS_FRAMEWORK
 | 
			
		||||
  #import "GTL/GTLDefines.h"
 | 
			
		||||
#else
 | 
			
		||||
  #import "GTLDefines.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// 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"
 | 
			
		||||
 | 
			
		||||
// Collection
 | 
			
		||||
GTL_EXTERN NSString * const kGTLPlusCollectionVault;  // "vault"
 | 
			
		||||
							
								
								
									
										37
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusConstants.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,37 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusConstants.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/
 | 
			
		||||
 | 
			
		||||
#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";
 | 
			
		||||
 | 
			
		||||
// Collection
 | 
			
		||||
NSString * const kGTLPlusCollectionVault = @"vault";
 | 
			
		||||
							
								
								
									
										225
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,225 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusItemScope.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:
 | 
			
		||||
//   GTLPlusItemScope (0 custom class methods, 55 custom properties)
 | 
			
		||||
 | 
			
		||||
#if GTL_BUILT_AS_FRAMEWORK
 | 
			
		||||
  #import "GTL/GTLObject.h"
 | 
			
		||||
#else
 | 
			
		||||
  #import "GTLObject.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@class GTLPlusItemScope;
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//   GTLPlusItemScope
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@interface GTLPlusItemScope : GTLObject
 | 
			
		||||
 | 
			
		||||
// The subject matter of the content.
 | 
			
		||||
@property (retain) GTLPlusItemScope *about;
 | 
			
		||||
 | 
			
		||||
// An additional name for a Person, can be used for a middle name.
 | 
			
		||||
@property (retain) NSArray *additionalName;  // of NSString
 | 
			
		||||
 | 
			
		||||
// Postal address.
 | 
			
		||||
@property (retain) GTLPlusItemScope *address;
 | 
			
		||||
 | 
			
		||||
// Address country.
 | 
			
		||||
@property (copy) NSString *addressCountry;
 | 
			
		||||
 | 
			
		||||
// Address locality.
 | 
			
		||||
@property (copy) NSString *addressLocality;
 | 
			
		||||
 | 
			
		||||
// Address region.
 | 
			
		||||
@property (copy) NSString *addressRegion;
 | 
			
		||||
 | 
			
		||||
// The encoding.
 | 
			
		||||
@property (retain) NSArray *associatedMedia;  // of GTLPlusItemScope
 | 
			
		||||
 | 
			
		||||
// Number of attendees.
 | 
			
		||||
@property (retain) NSNumber *attendeeCount;  // intValue
 | 
			
		||||
 | 
			
		||||
// A person attending the event.
 | 
			
		||||
@property (retain) NSArray *attendees;  // of GTLPlusItemScope
 | 
			
		||||
 | 
			
		||||
// From http://schema.org/MusicRecording, the audio file.
 | 
			
		||||
@property (retain) GTLPlusItemScope *audio;
 | 
			
		||||
 | 
			
		||||
// The person who created this scope.
 | 
			
		||||
@property (retain) NSArray *author;  // of GTLPlusItemScope
 | 
			
		||||
 | 
			
		||||
// Best possible rating value.
 | 
			
		||||
@property (copy) NSString *bestRating;
 | 
			
		||||
 | 
			
		||||
// Date of birth.
 | 
			
		||||
@property (copy) NSString *birthDate;
 | 
			
		||||
 | 
			
		||||
// From http://schema.org/MusicRecording, the artist that performed this
 | 
			
		||||
// recording.
 | 
			
		||||
@property (retain) GTLPlusItemScope *byArtist;
 | 
			
		||||
 | 
			
		||||
// The caption for this object.
 | 
			
		||||
@property (copy) NSString *caption;
 | 
			
		||||
 | 
			
		||||
// File size in (mega/kilo) bytes.
 | 
			
		||||
@property (copy) NSString *contentSize;
 | 
			
		||||
 | 
			
		||||
// Actual bytes of the media object, for example the image file or video file.
 | 
			
		||||
@property (copy) NSString *contentUrl;
 | 
			
		||||
 | 
			
		||||
// The list of contributors for this scope.
 | 
			
		||||
@property (retain) NSArray *contributor;  // of GTLPlusItemScope
 | 
			
		||||
 | 
			
		||||
// The date this scope was created.
 | 
			
		||||
@property (copy) NSString *dateCreated;
 | 
			
		||||
 | 
			
		||||
// The date this scope was last modified.
 | 
			
		||||
@property (copy) NSString *dateModified;
 | 
			
		||||
 | 
			
		||||
// The initial date this scope was published.
 | 
			
		||||
@property (copy) NSString *datePublished;
 | 
			
		||||
 | 
			
		||||
// The string describing the content of this scope.
 | 
			
		||||
// Remapped to 'descriptionProperty' to avoid NSObject's 'description'.
 | 
			
		||||
@property (copy) NSString *descriptionProperty;
 | 
			
		||||
 | 
			
		||||
// The duration of the item (movie, audio recording, event, etc.) in ISO 8601
 | 
			
		||||
// date format.
 | 
			
		||||
@property (copy) NSString *duration;
 | 
			
		||||
 | 
			
		||||
// A URL pointing to a player for a specific video. In general, this is the
 | 
			
		||||
// information in the src element of an embed tag and should not be the same as
 | 
			
		||||
// the content of the loc tag.
 | 
			
		||||
@property (copy) NSString *embedUrl;
 | 
			
		||||
 | 
			
		||||
// The end date and time of the event (in ISO 8601 date format).
 | 
			
		||||
@property (copy) NSString *endDate;
 | 
			
		||||
 | 
			
		||||
// Family name. In the U.S., the last name of an Person. This can be used along
 | 
			
		||||
// with givenName instead of the Name property.
 | 
			
		||||
@property (copy) NSString *familyName;
 | 
			
		||||
 | 
			
		||||
// Gender of the person.
 | 
			
		||||
@property (copy) NSString *gender;
 | 
			
		||||
 | 
			
		||||
// Geo coordinates.
 | 
			
		||||
@property (retain) GTLPlusItemScope *geo;
 | 
			
		||||
 | 
			
		||||
// Given name. In the U.S., the first name of a Person. This can be used along
 | 
			
		||||
// with familyName instead of the Name property.
 | 
			
		||||
@property (copy) NSString *givenName;
 | 
			
		||||
 | 
			
		||||
// The height of the media object.
 | 
			
		||||
@property (copy) NSString *height;
 | 
			
		||||
 | 
			
		||||
// The id for this item scope.
 | 
			
		||||
// identifier property maps to 'id' in JSON (to avoid Objective C's 'id').
 | 
			
		||||
@property (copy) NSString *identifier;
 | 
			
		||||
 | 
			
		||||
// A url to the image for this scope.
 | 
			
		||||
@property (copy) NSString *image;
 | 
			
		||||
 | 
			
		||||
// From http://schema.org/MusicRecording, which album a song is in.
 | 
			
		||||
@property (retain) GTLPlusItemScope *inAlbum;
 | 
			
		||||
 | 
			
		||||
// Identifies this resource as an itemScope.
 | 
			
		||||
@property (copy) NSString *kind;
 | 
			
		||||
 | 
			
		||||
// Latitude.
 | 
			
		||||
@property (retain) NSNumber *latitude;  // doubleValue
 | 
			
		||||
 | 
			
		||||
// The location of the event or organization.
 | 
			
		||||
@property (retain) GTLPlusItemScope *location;
 | 
			
		||||
 | 
			
		||||
// Longitude.
 | 
			
		||||
@property (retain) NSNumber *longitude;  // doubleValue
 | 
			
		||||
 | 
			
		||||
// The name of this scope.
 | 
			
		||||
@property (copy) NSString *name;
 | 
			
		||||
 | 
			
		||||
// Property of http://schema.org/TVEpisode indicating which series the episode
 | 
			
		||||
// belongs to.
 | 
			
		||||
@property (retain) GTLPlusItemScope *partOfTVSeries;
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
@property (copy) NSString *playerType;
 | 
			
		||||
 | 
			
		||||
// Postal code.
 | 
			
		||||
@property (copy) NSString *postalCode;
 | 
			
		||||
 | 
			
		||||
// Post office box number.
 | 
			
		||||
@property (copy) NSString *postOfficeBoxNumber;
 | 
			
		||||
 | 
			
		||||
// Rating value.
 | 
			
		||||
@property (copy) NSString *ratingValue;
 | 
			
		||||
 | 
			
		||||
// Review rating.
 | 
			
		||||
@property (retain) NSArray *reviewRating;  // of GTLPlusItemScope
 | 
			
		||||
 | 
			
		||||
// The start date and time of the event (in ISO 8601 date format).
 | 
			
		||||
@property (copy) NSString *startDate;
 | 
			
		||||
 | 
			
		||||
// Street address.
 | 
			
		||||
@property (copy) NSString *streetAddress;
 | 
			
		||||
 | 
			
		||||
// Comment text, review text, etc.
 | 
			
		||||
@property (copy) NSString *text;
 | 
			
		||||
 | 
			
		||||
// Thumbnail image for an image or video.
 | 
			
		||||
@property (retain) GTLPlusItemScope *thumbnail;
 | 
			
		||||
 | 
			
		||||
// A url to a thumbnail image for this scope.
 | 
			
		||||
@property (copy) NSString *thumbnailUrl;
 | 
			
		||||
 | 
			
		||||
// The exchange traded instrument associated with a Corporation object. The
 | 
			
		||||
// tickerSymbol is expressed as an exchange and an instrument name separated by
 | 
			
		||||
// a space character. For the exchange component of the tickerSymbol attribute,
 | 
			
		||||
// we reccommend using the controlled vocaulary of Market Identifier Codes (MIC)
 | 
			
		||||
// specified in ISO15022.
 | 
			
		||||
@property (copy) NSString *tickerSymbol;
 | 
			
		||||
 | 
			
		||||
// The item type.
 | 
			
		||||
@property (copy) NSString *type;
 | 
			
		||||
 | 
			
		||||
// A url for this scope.
 | 
			
		||||
@property (copy) NSString *url;
 | 
			
		||||
 | 
			
		||||
// The width of the media object.
 | 
			
		||||
@property (copy) NSString *width;
 | 
			
		||||
 | 
			
		||||
// Worst possible rating value.
 | 
			
		||||
@property (copy) NSString *worstRating;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										78
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusItemScope.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusItemScope.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:
 | 
			
		||||
//   GTLPlusItemScope (0 custom class methods, 55 custom properties)
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusItemScope.h"
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//   GTLPlusItemScope
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@implementation GTLPlusItemScope
 | 
			
		||||
@dynamic about, additionalName, address, addressCountry, addressLocality,
 | 
			
		||||
         addressRegion, associatedMedia, attendeeCount, attendees, audio,
 | 
			
		||||
         author, bestRating, birthDate, byArtist, caption, contentSize,
 | 
			
		||||
         contentUrl, contributor, dateCreated, dateModified, datePublished,
 | 
			
		||||
         descriptionProperty, duration, embedUrl, endDate, familyName, gender,
 | 
			
		||||
         geo, givenName, height, identifier, image, inAlbum, kind, latitude,
 | 
			
		||||
         location, longitude, name, partOfTVSeries, performers, playerType,
 | 
			
		||||
         postalCode, postOfficeBoxNumber, ratingValue, reviewRating, startDate,
 | 
			
		||||
         streetAddress, text, thumbnail, thumbnailUrl, tickerSymbol, type, url,
 | 
			
		||||
         width, worstRating;
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMap {
 | 
			
		||||
  NSDictionary *map =
 | 
			
		||||
    [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
      @"associated_media", @"associatedMedia",
 | 
			
		||||
      @"description", @"descriptionProperty",
 | 
			
		||||
      @"id", @"identifier",
 | 
			
		||||
      nil];
 | 
			
		||||
  return map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap {
 | 
			
		||||
  NSDictionary *map =
 | 
			
		||||
    [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
      [NSString class], @"additionalName",
 | 
			
		||||
      [GTLPlusItemScope class], @"associated_media",
 | 
			
		||||
      [GTLPlusItemScope class], @"attendees",
 | 
			
		||||
      [GTLPlusItemScope class], @"author",
 | 
			
		||||
      [GTLPlusItemScope class], @"contributor",
 | 
			
		||||
      [GTLPlusItemScope class], @"performers",
 | 
			
		||||
      [GTLPlusItemScope class], @"reviewRating",
 | 
			
		||||
      nil];
 | 
			
		||||
  return map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (void)load {
 | 
			
		||||
  [self registerObjectClassForKind:@"plus#itemScope"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										79
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,79 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusMoment.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:
 | 
			
		||||
//   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"
 | 
			
		||||
#else
 | 
			
		||||
  #import "GTLObject.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@class GTLPlusItemScope;
 | 
			
		||||
@class GTLPlusMomentVerb;
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//   GTLPlusMoment
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@interface GTLPlusMoment : GTLObject
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
@property (retain) GTLDateTime *startDate;
 | 
			
		||||
 | 
			
		||||
// The object on which the action was performed
 | 
			
		||||
@property (retain) GTLPlusItemScope *target;
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
							
								
								
									
										58
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusMoment.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,58 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLPlusMoment.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:
 | 
			
		||||
//   GTLPlusMoment (0 custom class methods, 6 custom properties)
 | 
			
		||||
//   GTLPlusMomentVerb (0 custom class methods, 1 custom properties)
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusMoment.h"
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusItemScope.h"
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//   GTLPlusMoment
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@implementation GTLPlusMoment
 | 
			
		||||
@dynamic kind, result, startDate, target, type, verb;
 | 
			
		||||
 | 
			
		||||
+ (void)load {
 | 
			
		||||
  [self registerObjectClassForKind:@"plus#moment"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//   GTLPlusMomentVerb
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@implementation GTLPlusMomentVerb
 | 
			
		||||
@dynamic url;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										285
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,285 @@
 | 
			
		||||
/* 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
 | 
			
		||||
							
								
								
									
										145
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLPlusPerson.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,145 @@
 | 
			
		||||
/* 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
 | 
			
		||||
							
								
								
									
										90
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,90 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLQueryPlus.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:
 | 
			
		||||
//   GTLQueryPlus (2 custom class methods, 4 custom properties)
 | 
			
		||||
 | 
			
		||||
#if GTL_BUILT_AS_FRAMEWORK
 | 
			
		||||
  #import "GTL/GTLQuery.h"
 | 
			
		||||
#else
 | 
			
		||||
  #import "GTLQuery.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@class GTLPlusMoment;
 | 
			
		||||
 | 
			
		||||
@interface GTLQueryPlus : GTLQuery
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Parameters valid on all methods.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Selector specifying which fields to include in a partial response.
 | 
			
		||||
@property (copy) NSString *fields;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Method-specific parameters; see the comments below for more information.
 | 
			
		||||
//
 | 
			
		||||
@property (copy) NSString *collection;
 | 
			
		||||
@property (assign) BOOL debug;
 | 
			
		||||
@property (copy) NSString *userId;
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
#pragma mark "moments" methods
 | 
			
		||||
// These create a GTLQueryPlus object.
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
//   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):
 | 
			
		||||
//   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
 | 
			
		||||
							
								
								
									
										72
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLQueryPlus.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,72 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLQueryPlus.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:
 | 
			
		||||
//   GTLQueryPlus (2 custom class methods, 4 custom properties)
 | 
			
		||||
 | 
			
		||||
#import "GTLQueryPlus.h"
 | 
			
		||||
 | 
			
		||||
#import "GTLPlusMoment.h"
 | 
			
		||||
#import "GTLPlusPerson.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLQueryPlus
 | 
			
		||||
 | 
			
		||||
@dynamic collection, debug, fields, userId;
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
#pragma mark "moments" methods
 | 
			
		||||
// These create a GTLQueryPlus object.
 | 
			
		||||
 | 
			
		||||
+ (id)queryForMomentsInsertWithObject:(GTLPlusMoment *)object
 | 
			
		||||
                               userId:(NSString *)userId
 | 
			
		||||
                           collection:(NSString *)collection {
 | 
			
		||||
  if (object == nil) {
 | 
			
		||||
    GTL_DEBUG_ASSERT(object != nil, @"%@ got a nil object", NSStringFromSelector(_cmd));
 | 
			
		||||
    return nil;
 | 
			
		||||
  }
 | 
			
		||||
  NSString *methodName = @"plus.moments.insert";
 | 
			
		||||
  GTLQueryPlus *query = [self queryWithMethodName:methodName];
 | 
			
		||||
  query.bodyObject = object;
 | 
			
		||||
  query.userId = userId;
 | 
			
		||||
  query.collection = collection;
 | 
			
		||||
  query.expectedObjectClass = [GTLPlusMoment class];
 | 
			
		||||
  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
 | 
			
		||||
							
								
								
									
										61
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,61 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLServicePlus.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:
 | 
			
		||||
//   GTLServicePlus (0 custom class methods, 0 custom properties)
 | 
			
		||||
 | 
			
		||||
#if GTL_BUILT_AS_FRAMEWORK
 | 
			
		||||
  #import "GTL/GTLService.h"
 | 
			
		||||
#else
 | 
			
		||||
  #import "GTLService.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@interface GTLServicePlus : GTLService
 | 
			
		||||
 | 
			
		||||
// No new methods
 | 
			
		||||
 | 
			
		||||
// Clients should create a standard query with any of the class methods in
 | 
			
		||||
// GTLQueryPlus.h. The query can the be sent with GTLService's execute methods,
 | 
			
		||||
//
 | 
			
		||||
//   - (GTLServiceTicket *)executeQuery:(GTLQuery *)query
 | 
			
		||||
//                    completionHandler:(void (^)(GTLServiceTicket *ticket,
 | 
			
		||||
//                                                id object, NSError *error))handler;
 | 
			
		||||
// or
 | 
			
		||||
//   - (GTLServiceTicket *)executeQuery:(GTLQuery *)query
 | 
			
		||||
//                             delegate:(id)delegate
 | 
			
		||||
//                    didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
//
 | 
			
		||||
// where finishedSelector has a signature of:
 | 
			
		||||
//
 | 
			
		||||
//   - (void)serviceTicket:(GTLServiceTicket *)ticket
 | 
			
		||||
//      finishedWithObject:(id)object
 | 
			
		||||
//                   error:(NSError *)error;
 | 
			
		||||
//
 | 
			
		||||
// The object passed to the completion handler or delegate method
 | 
			
		||||
// is a subclass of GTLObject, determined by the query method executed.
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										63
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLPlus/GTLServicePlus.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,63 @@
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLServicePlus.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:
 | 
			
		||||
//   GTLServicePlus (0 custom class methods, 0 custom properties)
 | 
			
		||||
 | 
			
		||||
#import "GTLPlus.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLServicePlus
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
// Method compiled in debug builds just to check that all the needed support
 | 
			
		||||
// classes are present at link time.
 | 
			
		||||
+ (NSArray *)checkClasses {
 | 
			
		||||
  NSArray *classes = [NSArray arrayWithObjects:
 | 
			
		||||
                      [GTLQueryPlus class],
 | 
			
		||||
                      [GTLPlusItemScope class],
 | 
			
		||||
                      [GTLPlusMoment class],
 | 
			
		||||
                      [GTLPlusPerson class],
 | 
			
		||||
                      nil];
 | 
			
		||||
  return classes;
 | 
			
		||||
}
 | 
			
		||||
#endif  // DEBUG
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    // Version from discovery.
 | 
			
		||||
    self.apiVersion = @"v1moments";
 | 
			
		||||
 | 
			
		||||
    // From discovery.  Where to send JSON-RPC.
 | 
			
		||||
    // Turn off prettyPrint for this service to save bandwidth (especially on
 | 
			
		||||
    // mobile). The fetcher logging will pretty print.
 | 
			
		||||
    self.rpcURL = [NSURL URLWithString:@"https://www.googleapis.com/rpc?prettyPrint=false"];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										132
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,132 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLQuery.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTLObject.h"
 | 
			
		||||
#import "GTLUploadParameters.h"
 | 
			
		||||
 | 
			
		||||
@protocol GTLQueryProtocol <NSObject, NSCopying>
 | 
			
		||||
- (BOOL)isBatchQuery;
 | 
			
		||||
- (BOOL)shouldSkipAuthorization;
 | 
			
		||||
- (void)executionDidStop;
 | 
			
		||||
- (NSDictionary *)additionalHTTPHeaders;
 | 
			
		||||
- (GTLUploadParameters *)uploadParameters;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol GTLQueryCollectionProtocol
 | 
			
		||||
@optional
 | 
			
		||||
@property (retain) NSString *pageToken;
 | 
			
		||||
@property (retain) NSNumber *startIndex;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@class GTLServiceTicket;
 | 
			
		||||
 | 
			
		||||
@interface GTLQuery : NSObject <GTLQueryProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSString *methodName_;
 | 
			
		||||
  NSMutableDictionary *json_;
 | 
			
		||||
  GTLObject *bodyObject_;
 | 
			
		||||
  NSMutableDictionary *childCache_;
 | 
			
		||||
  NSString *requestID_;
 | 
			
		||||
  GTLUploadParameters *uploadParameters_;
 | 
			
		||||
  NSDictionary *urlQueryParameters_;
 | 
			
		||||
  NSDictionary *additionalHTTPHeaders_;
 | 
			
		||||
  Class expectedObjectClass_;
 | 
			
		||||
  BOOL skipAuthorization_;
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  void (^completionBlock_)(GTLServiceTicket *ticket, id object, NSError *error);
 | 
			
		||||
#elif !__LP64__
 | 
			
		||||
  // Placeholders: for 32-bit builds, keep the size of the object's ivar section
 | 
			
		||||
  // the same with and without blocks
 | 
			
		||||
  id completionPlaceholder_;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The rpc method name.
 | 
			
		||||
@property (readonly) NSString *methodName;
 | 
			
		||||
 | 
			
		||||
// The JSON dictionary of all the parameters set on this query.
 | 
			
		||||
@property (retain) NSMutableDictionary *JSON;
 | 
			
		||||
 | 
			
		||||
// The object set to be uploaded with the query.
 | 
			
		||||
@property (retain) GTLObject *bodyObject;
 | 
			
		||||
 | 
			
		||||
// Each query must have a request ID string. The user may replace the
 | 
			
		||||
// default assigned request ID with a custom string, provided that if
 | 
			
		||||
// used in a batch query, all request IDs in the batch must be unique.
 | 
			
		||||
@property (copy) NSString *requestID;
 | 
			
		||||
 | 
			
		||||
// For queries which support file upload, the MIME type and file handle
 | 
			
		||||
// or data must be provided.
 | 
			
		||||
@property (copy) GTLUploadParameters *uploadParameters;
 | 
			
		||||
 | 
			
		||||
// Any url query parameters to add to the query (useful for debugging with some
 | 
			
		||||
// services).
 | 
			
		||||
@property (copy) NSDictionary *urlQueryParameters;
 | 
			
		||||
 | 
			
		||||
// Any additional HTTP headers for this query.  Not valid when this query
 | 
			
		||||
// is added to a batch.
 | 
			
		||||
//
 | 
			
		||||
// These headers override the same keys from the service object's
 | 
			
		||||
// additionalHTTPHeaders.
 | 
			
		||||
@property (copy) NSDictionary *additionalHTTPHeaders;
 | 
			
		||||
 | 
			
		||||
// The GTLObject subclass expected for results (used if the result doesn't
 | 
			
		||||
// include a kind attribute).
 | 
			
		||||
@property (assign) Class expectedObjectClass;
 | 
			
		||||
 | 
			
		||||
// Clients may set this to YES to disallow authorization. Defaults to NO.
 | 
			
		||||
@property (assign) BOOL shouldSkipAuthorization;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
// Clients may provide an optional callback block to be called immediately
 | 
			
		||||
// before the executeQuery: callback.
 | 
			
		||||
//
 | 
			
		||||
// The completionBlock property is particularly useful for queries executed
 | 
			
		||||
// in a batch.
 | 
			
		||||
//
 | 
			
		||||
// Errors passed to the completionBlock will have an "underlying" GTLErrorObject
 | 
			
		||||
// when the server returned an error for this specific query:
 | 
			
		||||
//
 | 
			
		||||
//   GTLErrorObject *errorObj = [GTLErrorObject underlyingObjectForError:error];
 | 
			
		||||
//   if (errorObj) {
 | 
			
		||||
//     // the server returned this error for this specific query
 | 
			
		||||
//   } else {
 | 
			
		||||
//     // the batch execution failed
 | 
			
		||||
//   }
 | 
			
		||||
@property (copy) void (^completionBlock)(GTLServiceTicket *ticket, id object, NSError *error);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// methodName is the RPC method name to use.
 | 
			
		||||
+ (id)queryWithMethodName:(NSString *)methodName;
 | 
			
		||||
 | 
			
		||||
// methodName is the RPC method name to use.
 | 
			
		||||
- (id)initWithMethodName:(NSString *)method;
 | 
			
		||||
 | 
			
		||||
// If you need to set a parameter that is not listed as a property for a
 | 
			
		||||
// query class, you can do so via this api.  If you need to clear it after
 | 
			
		||||
// setting, pass nil for obj.
 | 
			
		||||
- (void)setCustomParameter:(id)obj forKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
// Auto-generated request IDs
 | 
			
		||||
+ (NSString *)nextRequestID;
 | 
			
		||||
 | 
			
		||||
// Methods for subclasses to override.
 | 
			
		||||
+ (NSDictionary *)parameterNameMap;
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										267
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLQuery.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,267 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLQuery.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <objc/runtime.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLQuery.h"
 | 
			
		||||
#import "GTLRuntimeCommon.h"
 | 
			
		||||
#import "GTLUtilities.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLQuery () <GTLRuntimeCommon>
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTLQuery
 | 
			
		||||
 | 
			
		||||
// Implementation Note: bodyObject could be done as a dynamic property and map
 | 
			
		||||
// it to the key "resource".  But we expose the object on the ServiceTicket
 | 
			
		||||
// for developers, and so sending it through the plumbing already in the
 | 
			
		||||
// parameters and outside of that gets into a grey area.  For requests sent
 | 
			
		||||
// via this class, we don't need to touch the JSON, but for developers that
 | 
			
		||||
// have to use the lower level apis for something we'd need to know to add
 | 
			
		||||
// it to the JSON.
 | 
			
		||||
 | 
			
		||||
@synthesize methodName = methodName_,
 | 
			
		||||
            JSON = json_,
 | 
			
		||||
            bodyObject = bodyObject_,
 | 
			
		||||
            requestID = requestID_,
 | 
			
		||||
            uploadParameters = uploadParameters_,
 | 
			
		||||
            urlQueryParameters = urlQueryParameters_,
 | 
			
		||||
            additionalHTTPHeaders = additionalHTTPHeaders_,
 | 
			
		||||
            expectedObjectClass = expectedObjectClass_,
 | 
			
		||||
            shouldSkipAuthorization = skipAuthorization_;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@synthesize completionBlock = completionBlock_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
+ (id)queryWithMethodName:(NSString *)methodName {
 | 
			
		||||
  return [[[self alloc] initWithMethodName:methodName] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithMethodName:(NSString *)methodName {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    requestID_ = [[[self class] nextRequestID] retain];
 | 
			
		||||
 | 
			
		||||
    methodName_ = [methodName copy];
 | 
			
		||||
    if ([methodName_ length] == 0) {
 | 
			
		||||
      [self release];
 | 
			
		||||
      self = nil;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [methodName_ release];
 | 
			
		||||
  [json_ release];
 | 
			
		||||
  [bodyObject_ release];
 | 
			
		||||
  [childCache_ release];
 | 
			
		||||
  [requestID_ release];
 | 
			
		||||
  [uploadParameters_ release];
 | 
			
		||||
  [urlQueryParameters_ release];
 | 
			
		||||
  [additionalHTTPHeaders_ release];
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  [completionBlock_ release];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone {
 | 
			
		||||
  GTLQuery *query =
 | 
			
		||||
    [[[self class] allocWithZone:zone] initWithMethodName:self.methodName];
 | 
			
		||||
 | 
			
		||||
  if ([json_ count] > 0) {
 | 
			
		||||
    // Deep copy the parameters
 | 
			
		||||
    CFPropertyListRef ref = CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
 | 
			
		||||
                                                         json_, kCFPropertyListMutableContainers);
 | 
			
		||||
    query.JSON = [NSMakeCollectable(ref) autorelease];
 | 
			
		||||
  }
 | 
			
		||||
  query.bodyObject = self.bodyObject;
 | 
			
		||||
  query.requestID = self.requestID;
 | 
			
		||||
  query.uploadParameters = self.uploadParameters;
 | 
			
		||||
  query.urlQueryParameters = self.urlQueryParameters;
 | 
			
		||||
  query.additionalHTTPHeaders = self.additionalHTTPHeaders;
 | 
			
		||||
  query.expectedObjectClass = self.expectedObjectClass;
 | 
			
		||||
  query.shouldSkipAuthorization = self.shouldSkipAuthorization;
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  query.completionBlock = self.completionBlock;
 | 
			
		||||
#endif
 | 
			
		||||
  return query;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  NSArray *keys = [self.JSON allKeys];
 | 
			
		||||
  NSArray *params = [keys sortedArrayUsingSelector:@selector(compare:)];
 | 
			
		||||
  NSString *paramsSummary = @"";
 | 
			
		||||
  if ([params count] > 0) {
 | 
			
		||||
    paramsSummary = [NSString stringWithFormat:@" params:(%@)",
 | 
			
		||||
                     [params componentsJoinedByString:@","]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  keys = [self.urlQueryParameters allKeys];
 | 
			
		||||
  NSArray *urlQParams = [keys sortedArrayUsingSelector:@selector(compare:)];
 | 
			
		||||
  NSString *urlQParamsSummary = @"";
 | 
			
		||||
  if ([urlQParams count] > 0) {
 | 
			
		||||
    urlQParamsSummary = [NSString stringWithFormat:@" urlQParams:(%@)",
 | 
			
		||||
                        [urlQParams componentsJoinedByString:@","]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GTLObject *bodyObj = self.bodyObject;
 | 
			
		||||
  NSString *bodyObjSummary = @"";
 | 
			
		||||
  if (bodyObj != nil) {
 | 
			
		||||
    bodyObjSummary = [NSString stringWithFormat:@" bodyObject:%@", [bodyObj class]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *uploadStr = @"";
 | 
			
		||||
  GTLUploadParameters *uploadParams = self.uploadParameters;
 | 
			
		||||
  if (uploadParams) {
 | 
			
		||||
    uploadStr = [NSString stringWithFormat:@" %@", uploadParams];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p: {method:%@%@%@%@%@}",
 | 
			
		||||
          [self class], self, self.methodName,
 | 
			
		||||
          paramsSummary, urlQParamsSummary, bodyObjSummary, uploadStr];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCustomParameter:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  [self setJSONValue:obj forKey:key];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isBatchQuery {
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)executionDidStop {
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  self.completionBlock = nil;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)nextRequestID {
 | 
			
		||||
  static unsigned long lastRequestID = 0;
 | 
			
		||||
  NSString *result;
 | 
			
		||||
 | 
			
		||||
  @synchronized([GTLQuery class]) {
 | 
			
		||||
    ++lastRequestID;
 | 
			
		||||
    result = [NSString stringWithFormat:@"gtl_%lu",
 | 
			
		||||
              (unsigned long) lastRequestID];
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark GTLRuntimeCommon Support
 | 
			
		||||
 | 
			
		||||
- (void)setJSONValue:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  NSMutableDictionary *dict = self.JSON;
 | 
			
		||||
  if (dict == nil && obj != nil) {
 | 
			
		||||
    dict = [NSMutableDictionary dictionaryWithCapacity:1];
 | 
			
		||||
    self.JSON = dict;
 | 
			
		||||
  }
 | 
			
		||||
  [dict setValue:obj forKey:key];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)JSONValueForKey:(NSString *)key {
 | 
			
		||||
  id obj = [self.JSON objectForKey:key];
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// There is no property for childCache_ as there shouldn't be KVC/KVO
 | 
			
		||||
// support for it, it's an implementation detail.
 | 
			
		||||
 | 
			
		||||
- (void)setCacheChild:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  if (childCache_ == nil && obj != nil) {
 | 
			
		||||
    childCache_ =
 | 
			
		||||
      [[NSMutableDictionary alloc] initWithObjectsAndKeys:obj, key, nil];
 | 
			
		||||
  } else {
 | 
			
		||||
    [childCache_ setValue:obj forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)cacheChildForKey:(NSString *)key {
 | 
			
		||||
  id obj = [childCache_ objectForKey:key];
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Methods for Subclasses to Override
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)parameterNameMap {
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMap {
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Runtime Utilities
 | 
			
		||||
 | 
			
		||||
static NSMutableDictionary *gParameterNameMapCache = nil;
 | 
			
		||||
static NSMutableDictionary *gArrayPropertyToClassMapCache = nil;
 | 
			
		||||
 | 
			
		||||
+ (void)initialize {
 | 
			
		||||
  // note that initialize is guaranteed by the runtime to be called in a
 | 
			
		||||
  // thread-safe manner
 | 
			
		||||
  if (gParameterNameMapCache == nil) {
 | 
			
		||||
    gParameterNameMapCache = [GTLUtilities newStaticDictionary];
 | 
			
		||||
  }
 | 
			
		||||
  if (gArrayPropertyToClassMapCache == nil) {
 | 
			
		||||
    gArrayPropertyToClassMapCache = [GTLUtilities newStaticDictionary];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRuntimeCommon>)aClass {
 | 
			
		||||
  NSDictionary *resultMap =
 | 
			
		||||
  [GTLUtilities mergedClassDictionaryForSelector:@selector(parameterNameMap)
 | 
			
		||||
                                      startClass:aClass
 | 
			
		||||
                                   ancestorClass:[GTLQuery class]
 | 
			
		||||
                                           cache:gParameterNameMapCache];
 | 
			
		||||
  return resultMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRuntimeCommon>)aClass {
 | 
			
		||||
  NSDictionary *resultMap =
 | 
			
		||||
    [GTLUtilities mergedClassDictionaryForSelector:@selector(arrayPropertyToClassMap)
 | 
			
		||||
                                        startClass:aClass
 | 
			
		||||
                                     ancestorClass:[GTLQuery class]
 | 
			
		||||
                                             cache:gArrayPropertyToClassMapCache];
 | 
			
		||||
  return resultMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Runtime Support
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)surrogates {
 | 
			
		||||
  // Stub method just needed for RumtimeCommon, query doesn't use surrogates.
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (Class<GTLRuntimeCommon>)ancestorClass {
 | 
			
		||||
  return [GTLQuery class];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (BOOL)resolveInstanceMethod:(SEL)sel {
 | 
			
		||||
  BOOL resolved = [GTLRuntimeCommon resolveInstanceMethod:sel onClass:self];
 | 
			
		||||
  if (resolved)
 | 
			
		||||
    return YES;
 | 
			
		||||
 | 
			
		||||
  return [super resolveInstanceMethod:sel];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										57
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,57 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLRuntimeCommon.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
 | 
			
		||||
// This protocol and support class are an internal implementation detail so
 | 
			
		||||
// GTLObject and GTLQuery can share some code.
 | 
			
		||||
 | 
			
		||||
@protocol GTLRuntimeCommon <NSObject>
 | 
			
		||||
@required
 | 
			
		||||
// Get/Set properties
 | 
			
		||||
- (void)setJSONValue:(id)obj forKey:(NSString *)key;
 | 
			
		||||
- (id)JSONValueForKey:(NSString *)key;
 | 
			
		||||
// Child cache
 | 
			
		||||
- (void)setCacheChild:(id)obj forKey:(NSString *)key;
 | 
			
		||||
- (id)cacheChildForKey:(NSString *)key;
 | 
			
		||||
// Surrogate class mappings.
 | 
			
		||||
- (NSDictionary *)surrogates;
 | 
			
		||||
// Key map
 | 
			
		||||
+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRuntimeCommon>)aClass;
 | 
			
		||||
// Array item types
 | 
			
		||||
+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRuntimeCommon>)aClass;
 | 
			
		||||
// The parent class for dynamic support
 | 
			
		||||
+ (Class<GTLRuntimeCommon>)ancestorClass;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTLRuntimeCommon : NSObject
 | 
			
		||||
// Wire things up.
 | 
			
		||||
+ (BOOL)resolveInstanceMethod:(SEL)sel onClass:(Class)onClass;
 | 
			
		||||
// Helpers
 | 
			
		||||
+ (id)objectFromJSON:(id)json
 | 
			
		||||
        defaultClass:(Class)defaultClass
 | 
			
		||||
          surrogates:(NSDictionary *)surrogates
 | 
			
		||||
         isCacheable:(BOOL*)isCacheable;
 | 
			
		||||
+ (id)jsonFromAPIObject:(id)obj
 | 
			
		||||
          expectedClass:(Class)expectedClass
 | 
			
		||||
            isCacheable:(BOOL*)isCacheable;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										1135
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLRuntimeCommon.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										592
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLService.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,592 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLService.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
#import "GTMHTTPFetcherService.h"
 | 
			
		||||
#import "GTLBatchQuery.h"
 | 
			
		||||
#import "GTLBatchResult.h"
 | 
			
		||||
#import "GTLDateTime.h"
 | 
			
		||||
#import "GTLErrorObject.h"
 | 
			
		||||
#import "GTLFramework.h"
 | 
			
		||||
#import "GTLJSONParser.h"
 | 
			
		||||
#import "GTLObject.h"
 | 
			
		||||
#import "GTLQuery.h"
 | 
			
		||||
#import "GTLUtilities.h"
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTLSERVICE_DEFINE_GLOBALS
 | 
			
		||||
#define _EXTERN
 | 
			
		||||
#define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
#define _EXTERN extern
 | 
			
		||||
#define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Error domains
 | 
			
		||||
_EXTERN NSString* const kGTLServiceErrorDomain _INITIALIZE_AS(@"com.google.GTLServiceDomain");
 | 
			
		||||
enum {
 | 
			
		||||
  kGTLErrorQueryResultMissing = -3000,
 | 
			
		||||
  kGTLErrorWaitTimedOut       = -3001
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
_EXTERN NSString* const kGTLJSONRPCErrorDomain _INITIALIZE_AS(@"com.google.GTLJSONRPCErrorDomain");
 | 
			
		||||
 | 
			
		||||
// We'll consistently store the server error string in the userInfo under
 | 
			
		||||
// this key
 | 
			
		||||
_EXTERN NSString* const kGTLServerErrorStringKey _INITIALIZE_AS(@"error");
 | 
			
		||||
 | 
			
		||||
_EXTERN Class const kGTLUseRegisteredClass _INITIALIZE_AS(nil);
 | 
			
		||||
 | 
			
		||||
_EXTERN NSUInteger const kGTLStandardUploadChunkSize _INITIALIZE_AS(NSUIntegerMax);
 | 
			
		||||
 | 
			
		||||
// When servers return us structured JSON errors, the NSError will
 | 
			
		||||
// contain a GTLErrorObject in the userInfo dictionary under the key
 | 
			
		||||
// kGTLStructuredErrorsKey
 | 
			
		||||
_EXTERN NSString* const kGTLStructuredErrorKey _INITIALIZE_AS(@"GTLStructuredError");
 | 
			
		||||
 | 
			
		||||
// When specifying an ETag for updating or deleting a single entry, use
 | 
			
		||||
// kGTLETagWildcard to tell the server to replace the current value
 | 
			
		||||
// unconditionally.  Do not use this in entries in a batch feed.
 | 
			
		||||
_EXTERN NSString* const kGTLETagWildcard _INITIALIZE_AS(@"*");
 | 
			
		||||
 | 
			
		||||
// Notifications when parsing of a fetcher feed or entry begins or ends
 | 
			
		||||
_EXTERN NSString* const kGTLServiceTicketParsingStartedNotification _INITIALIZE_AS(@"kGTLServiceTicketParsingStartedNotification");
 | 
			
		||||
_EXTERN NSString* const kGTLServiceTicketParsingStoppedNotification _INITIALIZE_AS(@"kGTLServiceTicketParsingStoppedNotification");
 | 
			
		||||
 | 
			
		||||
@class GTLServiceTicket;
 | 
			
		||||
 | 
			
		||||
// Block types used for fetch callbacks
 | 
			
		||||
//
 | 
			
		||||
// These typedefs are not used in the header file method declarations
 | 
			
		||||
// since it's more useful when code sense expansions show the argument
 | 
			
		||||
// types rather than the typedefs
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
typedef void (^GTLServiceCompletionHandler)(GTLServiceTicket *ticket, id object, NSError *error);
 | 
			
		||||
 | 
			
		||||
typedef void (^GTLServiceUploadProgressBlock)(GTLServiceTicket *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength);
 | 
			
		||||
#else
 | 
			
		||||
typedef void *GTLServiceCompletionHandler;
 | 
			
		||||
 | 
			
		||||
typedef void *GTLServiceUploadProgressBlock;
 | 
			
		||||
#endif // NS_BLOCKS_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Service base class
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@interface GTLService : NSObject {
 | 
			
		||||
 @private
 | 
			
		||||
  NSOperationQueue *parseQueue_;
 | 
			
		||||
  NSString *userAgent_;
 | 
			
		||||
  GTMHTTPFetcherService *fetcherService_;
 | 
			
		||||
  NSString *userAgentAddition_;
 | 
			
		||||
 | 
			
		||||
  NSMutableDictionary *serviceProperties_; // initial values for properties in future tickets
 | 
			
		||||
 | 
			
		||||
  NSDictionary *surrogates_; // initial value for surrogates in future tickets
 | 
			
		||||
 | 
			
		||||
  SEL uploadProgressSelector_; // optional
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  BOOL (^retryBlock_)(GTLServiceTicket *, BOOL, NSError *);
 | 
			
		||||
  void (^uploadProgressBlock_)(GTLServiceTicket *ticket,
 | 
			
		||||
                               unsigned long long numberOfBytesRead,
 | 
			
		||||
                               unsigned long long dataLength);
 | 
			
		||||
#elif !__LP64__
 | 
			
		||||
  // Placeholders: for 32-bit builds, keep the size of the object's ivar section
 | 
			
		||||
  // the same with and without blocks
 | 
			
		||||
  id retryPlaceholder_;
 | 
			
		||||
  id uploadProgressPlaceholder_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  NSUInteger uploadChunkSize_;      // zero when uploading via multi-part MIME http body
 | 
			
		||||
 | 
			
		||||
  BOOL isRetryEnabled_;      // user allows auto-retries
 | 
			
		||||
  SEL retrySelector_;             // optional; set with setServiceRetrySelector
 | 
			
		||||
  NSTimeInterval maxRetryInterval_; // default to 600. seconds
 | 
			
		||||
 | 
			
		||||
  BOOL shouldFetchNextPages_;
 | 
			
		||||
 | 
			
		||||
  NSString *apiKey_;
 | 
			
		||||
  BOOL isRESTDataWrapperRequired_;
 | 
			
		||||
  NSString *apiVersion_;
 | 
			
		||||
  NSURL *rpcURL_;
 | 
			
		||||
  NSURL *rpcUploadURL_;
 | 
			
		||||
  NSDictionary *urlQueryParameters_;
 | 
			
		||||
  NSDictionary *additionalHTTPHeaders_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Query Execution
 | 
			
		||||
 | 
			
		||||
// The finishedSelector has a signature matching:
 | 
			
		||||
//
 | 
			
		||||
//   - (void)serviceTicket:(GTLServiceTicket *)ticket
 | 
			
		||||
//      finishedWithObject:(GTLObject *)object
 | 
			
		||||
//                   error:(NSError *)error
 | 
			
		||||
//
 | 
			
		||||
// If an error occurs, the error parameter will be non-nil.  Otherwise,
 | 
			
		||||
// the object parameter will point to a GTLObject, if any was returned by
 | 
			
		||||
// the fetch.  (Delete fetches return no object, so the second parameter will
 | 
			
		||||
// be nil.)
 | 
			
		||||
//
 | 
			
		||||
// If the query object is a GTLBatchQuery, the object passed to the callback
 | 
			
		||||
// will be a GTLBatchResult
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)executeQuery:(id<GTLQueryProtocol>)query
 | 
			
		||||
                          delegate:(id)delegate
 | 
			
		||||
                 didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
- (GTLServiceTicket *)executeQuery:(id<GTLQueryProtocol>)query
 | 
			
		||||
                 completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Automatic page fetches
 | 
			
		||||
//
 | 
			
		||||
// Tickets can optionally do a sequence of fetches for queries where
 | 
			
		||||
// repeated requests with nextPageToken or nextStartIndex values is required to
 | 
			
		||||
// retrieve items of all pages of the response collection.  The client's
 | 
			
		||||
// callback is invoked only when all items have been retrieved, or an error has
 | 
			
		||||
// occurred.  During the fetch, the items accumulated so far are available from
 | 
			
		||||
// the ticket.
 | 
			
		||||
//
 | 
			
		||||
// Note that the final object may be a combination of multiple page responses
 | 
			
		||||
// so it may not be the same as if all results had been returned in a single
 | 
			
		||||
// page. Some fields of the response such as total item counts may reflect only
 | 
			
		||||
// the final page's values.
 | 
			
		||||
//
 | 
			
		||||
// Automatic page fetches will return an error if more than 25 page fetches are
 | 
			
		||||
// required.  For debug builds, this will log a warning to the console when more
 | 
			
		||||
// than 2 page fetches occur, as a reminder that the query's maxResults
 | 
			
		||||
// parameter should probably be increased to specify more items returned per
 | 
			
		||||
// page.
 | 
			
		||||
//
 | 
			
		||||
// Default value is NO.
 | 
			
		||||
@property (nonatomic, assign) BOOL shouldFetchNextPages;
 | 
			
		||||
 | 
			
		||||
// Retrying; see comments on retry support at the top of GTMHTTPFetcher.
 | 
			
		||||
//
 | 
			
		||||
// Default value is NO.
 | 
			
		||||
@property (nonatomic, assign, getter=isRetryEnabled) BOOL retryEnabled;
 | 
			
		||||
 | 
			
		||||
// Some services require a developer key for quotas and limits.  Setting this
 | 
			
		||||
// will include it on all request sent to this service via a GTLQuery class.
 | 
			
		||||
@property (nonatomic, copy) NSString *APIKey;
 | 
			
		||||
 | 
			
		||||
// An authorizer adds user authentication headers to the request as needed.
 | 
			
		||||
@property (nonatomic, retain) id <GTMFetcherAuthorizationProtocol> authorizer;
 | 
			
		||||
 | 
			
		||||
// Retry selector is optional for retries.
 | 
			
		||||
//
 | 
			
		||||
// If present, it should have the signature:
 | 
			
		||||
//   -(BOOL)ticket:(GTLServiceTicket *)ticket willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
 | 
			
		||||
// and return YES to cause a retry.  Note that unlike the GTMHTTPFetcher retry
 | 
			
		||||
// selector, this selector's first argument is a ticket, not a fetcher.
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, assign) SEL retrySelector;
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@property (copy) BOOL (^retryBlock)(GTLServiceTicket *ticket, BOOL suggestedWillRetry, NSError *error);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, assign) NSTimeInterval maxRetryInterval;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Fetches may be done using RPC or REST APIs, without creating
 | 
			
		||||
// a GTLQuery object
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#pragma mark RPC Fetch Methods
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// These methods may be used for RPC fetches without creating a GTLQuery object
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                      parameters:(NSDictionary *)parameters
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                                        delegate:(id)delegate
 | 
			
		||||
                               didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                 insertingObject:(GTLObject *)bodyObject
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                                        delegate:(id)delegate
 | 
			
		||||
                               didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                      parameters:(NSDictionary *)parameters
 | 
			
		||||
                                 insertingObject:(GTLObject *)bodyObject
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                                        delegate:(id)delegate
 | 
			
		||||
                               didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                      parameters:(NSDictionary *)parameters
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                               completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                 insertingObject:(GTLObject *)bodyObject
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                               completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithMethodNamed:(NSString *)methodName
 | 
			
		||||
                                      parameters:(NSDictionary *)parameters
 | 
			
		||||
                                 insertingObject:(GTLObject *)bodyObject
 | 
			
		||||
                                     objectClass:(Class)objectClass
 | 
			
		||||
                               completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma mark REST Fetch Methods
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithURL:(NSURL *)objectURL
 | 
			
		||||
                                delegate:(id)delegate
 | 
			
		||||
                       didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithURL:(NSURL *)objectURL
 | 
			
		||||
                             objectClass:(Class)objectClass
 | 
			
		||||
                                delegate:(id)delegate
 | 
			
		||||
                       didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchPublicObjectWithURL:(NSURL *)objectURL
 | 
			
		||||
                                   objectClass:(Class)objectClass
 | 
			
		||||
                                      delegate:(id)delegate
 | 
			
		||||
                             didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectByInsertingObject:(GTLObject *)bodyToPut
 | 
			
		||||
                                            forURL:(NSURL *)destinationURL
 | 
			
		||||
                                          delegate:(id)delegate
 | 
			
		||||
                                 didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectByUpdatingObject:(GTLObject *)bodyToPut
 | 
			
		||||
                                           forURL:(NSURL *)destinationURL
 | 
			
		||||
                                         delegate:(id)delegate
 | 
			
		||||
                                didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)deleteResourceURL:(NSURL *)destinationURL
 | 
			
		||||
                                   ETag:(NSString *)etagOrNil
 | 
			
		||||
                               delegate:(id)delegate
 | 
			
		||||
                      didFinishSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectWithURL:(NSURL *)objectURL
 | 
			
		||||
                       completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectByInsertingObject:(GTLObject *)bodyToPut
 | 
			
		||||
                                            forURL:(NSURL *)destinationURL
 | 
			
		||||
                                 completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)fetchObjectByUpdatingObject:(GTLObject *)bodyToPut
 | 
			
		||||
                                           forURL:(NSURL *)destinationURL
 | 
			
		||||
                                completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (GTLServiceTicket *)deleteResourceURL:(NSURL *)destinationURL
 | 
			
		||||
                                   ETag:(NSString *)etagOrNil
 | 
			
		||||
                      completionHandler:(void (^)(GTLServiceTicket *ticket, id object, NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma mark User Properties
 | 
			
		||||
 | 
			
		||||
// Properties and userData are supported for client convenience.
 | 
			
		||||
//
 | 
			
		||||
// Property keys beginning with _ are reserved by the library.
 | 
			
		||||
//
 | 
			
		||||
// The service properties dictionary is copied to become the initial property
 | 
			
		||||
// dictionary for each ticket.
 | 
			
		||||
- (void)setServiceProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
 | 
			
		||||
- (id)servicePropertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, copy) NSDictionary *serviceProperties;
 | 
			
		||||
 | 
			
		||||
// The service userData becomes the initial value for each future ticket's
 | 
			
		||||
// userData.
 | 
			
		||||
@property (nonatomic, retain) id serviceUserData;
 | 
			
		||||
 | 
			
		||||
#pragma mark Request Settings
 | 
			
		||||
 | 
			
		||||
// Set the surrogates to be used for future tickets.  Surrogates are subclasses
 | 
			
		||||
// to be used instead of standard classes when creating objects from the JSON.
 | 
			
		||||
// For example, this code will make the framework generate objects
 | 
			
		||||
// using MyCalendarItemSubclass instead of GTLItemCalendar and
 | 
			
		||||
// MyCalendarEventSubclass instead of GTLItemCalendarEvent.
 | 
			
		||||
//
 | 
			
		||||
//  NSDictionary *surrogates = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
//    [MyCalendarEntrySubclass class], [GTLItemCalendar class],
 | 
			
		||||
//    [MyCalendarEventSubclass class], [GTLItemCalendarEvent class],
 | 
			
		||||
//    nil];
 | 
			
		||||
//  [calendarService setServiceSurrogates:surrogates];
 | 
			
		||||
//
 | 
			
		||||
@property (nonatomic, retain) NSDictionary *surrogates;
 | 
			
		||||
 | 
			
		||||
// On iOS 4 and later, the fetch may optionally continue in the background
 | 
			
		||||
// until finished or stopped by OS expiration.
 | 
			
		||||
//
 | 
			
		||||
// The default value is NO.
 | 
			
		||||
//
 | 
			
		||||
// For Mac OS X, background fetches are always supported, and this property
 | 
			
		||||
// is ignored.
 | 
			
		||||
@property (nonatomic, assign) BOOL shouldFetchInBackground;
 | 
			
		||||
 | 
			
		||||
// Run loop modes are used for scheduling NSURLConnections.
 | 
			
		||||
//
 | 
			
		||||
// The default value, nil, schedules connections using the current run
 | 
			
		||||
// loop mode.  To use the service during a modal dialog, be sure to specify
 | 
			
		||||
// NSModalPanelRunLoopMode as one of the modes.
 | 
			
		||||
@property (nonatomic, retain) NSArray *runLoopModes;
 | 
			
		||||
 | 
			
		||||
// Applications needing an additional identifier in the server logs may specify
 | 
			
		||||
// one.
 | 
			
		||||
@property (nonatomic, copy) NSString *userAgentAddition;
 | 
			
		||||
 | 
			
		||||
// Applications have a default user-agent based on the application signature
 | 
			
		||||
// in the Info.plist settings.  Most applications should not explicitly set
 | 
			
		||||
// this property.
 | 
			
		||||
@property (nonatomic, copy) NSString *userAgent;
 | 
			
		||||
 | 
			
		||||
// The request user agent includes the library and OS version appended to the
 | 
			
		||||
// base userAgent, along with the optional addition string.
 | 
			
		||||
@property (nonatomic, readonly) NSString *requestUserAgent;
 | 
			
		||||
 | 
			
		||||
// Applications may call requestForURL:httpMethod to get a request with the
 | 
			
		||||
// proper user-agent and ETag headers
 | 
			
		||||
//
 | 
			
		||||
// For http method, pass nil (for default GET method), POST, PUT, or DELETE
 | 
			
		||||
- (NSMutableURLRequest *)requestForURL:(NSURL *)url
 | 
			
		||||
                                  ETag:(NSString *)etagOrNil
 | 
			
		||||
                            httpMethod:(NSString *)httpMethodOrNil;
 | 
			
		||||
 | 
			
		||||
// objectRequestForURL returns an NSMutableURLRequest for a JSON GTL object
 | 
			
		||||
//
 | 
			
		||||
// The object is the object being sent to the server, or nil;
 | 
			
		||||
// the http method may be nil for GET, or POST, PUT, DELETE
 | 
			
		||||
- (NSMutableURLRequest *)objectRequestForURL:(NSURL *)url
 | 
			
		||||
                                      object:(GTLObject *)object
 | 
			
		||||
                                        ETag:(NSString *)etag
 | 
			
		||||
                                  httpMethod:(NSString *)httpMethod
 | 
			
		||||
                                      isREST:(BOOL)isREST
 | 
			
		||||
                           additionalHeaders:(NSDictionary *)additionalHeaders
 | 
			
		||||
                                      ticket:(GTLServiceTicket *)ticket;
 | 
			
		||||
 | 
			
		||||
// The queue used for parsing JSON responses (previously this property
 | 
			
		||||
// was called operationQueue)
 | 
			
		||||
@property (nonatomic, retain) NSOperationQueue *parseQueue;
 | 
			
		||||
 | 
			
		||||
// The fetcher service object issues the GTMHTTPFetcher instances
 | 
			
		||||
// for this API service
 | 
			
		||||
@property (nonatomic, retain) GTMHTTPFetcherService *fetcherService;
 | 
			
		||||
 | 
			
		||||
// Default storage for cookies is in the service object's fetchHistory.
 | 
			
		||||
//
 | 
			
		||||
// Apps that want to share cookies between all standalone fetchers and the
 | 
			
		||||
// service object may specify static application-wide cookie storage,
 | 
			
		||||
// kGTMHTTPFetcherCookieStorageMethodStatic.
 | 
			
		||||
@property (nonatomic, assign) NSInteger cookieStorageMethod;
 | 
			
		||||
 | 
			
		||||
// When sending REST style queries, should the payload be wrapped in a "data"
 | 
			
		||||
// element, and will the reply be wrapped in an "data" element.
 | 
			
		||||
@property (nonatomic, assign) BOOL isRESTDataWrapperRequired;
 | 
			
		||||
 | 
			
		||||
// Any url query parameters to add to urls (useful for debugging with some
 | 
			
		||||
// services).
 | 
			
		||||
@property (copy) NSDictionary *urlQueryParameters;
 | 
			
		||||
 | 
			
		||||
// Any extra http headers to set on requests for GTLObjects.
 | 
			
		||||
@property (copy) NSDictionary *additionalHTTPHeaders;
 | 
			
		||||
 | 
			
		||||
// The service API version.
 | 
			
		||||
@property (nonatomic, copy) NSString *apiVersion;
 | 
			
		||||
 | 
			
		||||
// The URL for sending RPC requests for this service.
 | 
			
		||||
@property (nonatomic, retain) NSURL *rpcURL;
 | 
			
		||||
 | 
			
		||||
// The URL for sending RPC requests which initiate file upload.
 | 
			
		||||
@property (nonatomic, retain) NSURL *rpcUploadURL;
 | 
			
		||||
 | 
			
		||||
// Set a non-zero value to enable uploading via chunked fetches
 | 
			
		||||
// (resumable uploads); typically this defaults to kGTLStandardUploadChunkSize
 | 
			
		||||
// for service subclasses that support chunked uploads
 | 
			
		||||
@property (nonatomic, assign) NSUInteger serviceUploadChunkSize;
 | 
			
		||||
 | 
			
		||||
// Service subclasses may specify their own default chunk size
 | 
			
		||||
+ (NSUInteger)defaultServiceUploadChunkSize;
 | 
			
		||||
 | 
			
		||||
// The service uploadProgressSelector becomes the initial value for each future
 | 
			
		||||
// ticket's uploadProgressSelector.
 | 
			
		||||
//
 | 
			
		||||
// The optional uploadProgressSelector will be called in the delegate as bytes
 | 
			
		||||
// are uploaded to the server.  It should have a signature matching
 | 
			
		||||
//
 | 
			
		||||
// - (void)ticket:(GTLServiceTicket *)ticket
 | 
			
		||||
//   hasDeliveredByteCount:(unsigned long long)numberOfBytesRead
 | 
			
		||||
//        ofTotalByteCount:(unsigned long long)dataLength;
 | 
			
		||||
@property (nonatomic, assign) SEL uploadProgressSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@property (copy) void (^uploadProgressBlock)(GTLServiceTicket *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Wait synchronously for fetch to complete (strongly discouraged)
 | 
			
		||||
//
 | 
			
		||||
// This just runs the current event loop until the fetch completes
 | 
			
		||||
// or the timout limit is reached.  This may discard unexpected events
 | 
			
		||||
// that occur while spinning, so it's really not appropriate for use
 | 
			
		||||
// in serious applications.
 | 
			
		||||
//
 | 
			
		||||
// Returns true if an object was successfully fetched.  If the wait
 | 
			
		||||
// timed out, returns false and the returned error is nil.
 | 
			
		||||
//
 | 
			
		||||
// The returned object or error, if any, will be already autoreleased
 | 
			
		||||
//
 | 
			
		||||
// This routine will likely be removed in some future releases of the library.
 | 
			
		||||
- (BOOL)waitForTicket:(GTLServiceTicket *)ticket
 | 
			
		||||
              timeout:(NSTimeInterval)timeoutInSeconds
 | 
			
		||||
        fetchedObject:(GTLObject **)outObjectOrNil
 | 
			
		||||
                error:(NSError **)outErrorOrNil;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Ticket base class
 | 
			
		||||
//
 | 
			
		||||
@interface GTLServiceTicket : NSObject {
 | 
			
		||||
  GTLService *service_;
 | 
			
		||||
 | 
			
		||||
  NSMutableDictionary *ticketProperties_;
 | 
			
		||||
  NSDictionary *surrogates_;
 | 
			
		||||
 | 
			
		||||
  GTMHTTPFetcher *objectFetcher_;
 | 
			
		||||
  SEL uploadProgressSelector_;
 | 
			
		||||
  BOOL shouldFetchNextPages_;
 | 
			
		||||
  BOOL isRetryEnabled_;
 | 
			
		||||
  SEL retrySelector_;
 | 
			
		||||
  NSTimeInterval maxRetryInterval_;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  BOOL (^retryBlock_)(GTLServiceTicket *, BOOL, NSError *);
 | 
			
		||||
  void (^uploadProgressBlock_)(GTLServiceTicket *ticket,
 | 
			
		||||
                               unsigned long long numberOfBytesRead,
 | 
			
		||||
                               unsigned long long dataLength);
 | 
			
		||||
#elif !__LP64__
 | 
			
		||||
  // Placeholders: for 32-bit builds, keep the size of the object's ivar section
 | 
			
		||||
  // the same with and without blocks
 | 
			
		||||
  id retryPlaceholder_;
 | 
			
		||||
  id uploadProgressPlaceholder_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  GTLObject *postedObject_;
 | 
			
		||||
  GTLObject *fetchedObject_;
 | 
			
		||||
  id<GTLQueryProtocol> executingQuery_;
 | 
			
		||||
  id<GTLQueryProtocol> originalQuery_;
 | 
			
		||||
  NSError *fetchError_;
 | 
			
		||||
  BOOL hasCalledCallback_;
 | 
			
		||||
  NSUInteger pagesFetchedCounter_;
 | 
			
		||||
 | 
			
		||||
  NSString *apiKey_;
 | 
			
		||||
  BOOL isREST_;
 | 
			
		||||
 | 
			
		||||
  NSOperation *parseOperation_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)ticketForService:(GTLService *)service;
 | 
			
		||||
 | 
			
		||||
- (id)initWithService:(GTLService *)service;
 | 
			
		||||
 | 
			
		||||
- (id)service;
 | 
			
		||||
 | 
			
		||||
#pragma mark Execution Control
 | 
			
		||||
// if cancelTicket is called, the fetch is stopped if it is in progress,
 | 
			
		||||
// the callbacks will not be called, and the ticket will no longer be useful
 | 
			
		||||
// (though the client must still release the ticket if it retained the ticket)
 | 
			
		||||
- (void)cancelTicket;
 | 
			
		||||
 | 
			
		||||
// chunked upload tickets may be paused
 | 
			
		||||
- (void)pauseUpload;
 | 
			
		||||
- (void)resumeUpload;
 | 
			
		||||
- (BOOL)isUploadPaused;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) GTMHTTPFetcher *objectFetcher;
 | 
			
		||||
@property (nonatomic, assign) SEL uploadProgressSelector;
 | 
			
		||||
 | 
			
		||||
// Services which do not require an user authorization may require a developer
 | 
			
		||||
// API key for quota management
 | 
			
		||||
@property (nonatomic, copy) NSString *APIKey;
 | 
			
		||||
 | 
			
		||||
#pragma mark User Properties
 | 
			
		||||
 | 
			
		||||
// Properties and userData are supported for client convenience.
 | 
			
		||||
//
 | 
			
		||||
// Property keys beginning with _ are reserved by the library.
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
 | 
			
		||||
- (id)propertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, copy) NSDictionary *properties;
 | 
			
		||||
@property (nonatomic, retain) id userData;
 | 
			
		||||
 | 
			
		||||
#pragma mark Payload
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) GTLObject *postedObject;
 | 
			
		||||
@property (nonatomic, retain) GTLObject *fetchedObject;
 | 
			
		||||
@property (nonatomic, retain) id<GTLQueryProtocol> executingQuery; // Query currently being fetched by this ticket
 | 
			
		||||
@property (nonatomic, retain) id<GTLQueryProtocol> originalQuery;  // Query used to create this ticket
 | 
			
		||||
- (GTLQuery *)queryForRequestID:(NSString *)requestID; // Returns the query from within the batch with the given id.
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) NSDictionary *surrogates;
 | 
			
		||||
 | 
			
		||||
#pragma mark Retry
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, assign, getter=isRetryEnabled) BOOL retryEnabled;
 | 
			
		||||
@property (nonatomic, assign) SEL retrySelector;
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@property (copy) BOOL (^retryBlock)(GTLServiceTicket *ticket, BOOL suggestedWillRetry, NSError *error);
 | 
			
		||||
#endif
 | 
			
		||||
@property (nonatomic, assign) NSTimeInterval maxRetryInterval;
 | 
			
		||||
 | 
			
		||||
#pragma mark Status
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, readonly) NSInteger statusCode; // server status from object fetch
 | 
			
		||||
@property (nonatomic, retain) NSError *fetchError;
 | 
			
		||||
@property (nonatomic, assign) BOOL hasCalledCallback;
 | 
			
		||||
 | 
			
		||||
#pragma mark Pagination
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, assign) BOOL shouldFetchNextPages;
 | 
			
		||||
@property (nonatomic, assign) NSUInteger pagesFetchedCounter;
 | 
			
		||||
 | 
			
		||||
#pragma mark Upload
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@property (copy) void (^uploadProgressBlock)(GTLServiceTicket *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Category to provide opaque access to tickets stored in fetcher properties
 | 
			
		||||
@interface GTMHTTPFetcher (GTLServiceTicketAdditions)
 | 
			
		||||
- (id)ticket;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2387
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLService.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										58
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLTargetNamespace.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,58 @@
 | 
			
		||||
//
 | 
			
		||||
// Makes the value of GTL_TARGET_NAMESPACE a prefix for all GTL
 | 
			
		||||
// library class names
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// To avoid global namespace issues, define GTL_TARGET_NAMESPACE to a short
 | 
			
		||||
// string in your target if you are using the GTL library in a shared-code
 | 
			
		||||
// environment like a plug-in.
 | 
			
		||||
//
 | 
			
		||||
// For example:   -DGTL_TARGET_NAMESPACE=MyPlugin
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// com.google.GTLFramework v. 2.0 (29 classes) 2011-10-25 19:25:36 -0700
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined(__OBJC__) && defined(GTL_TARGET_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
  #define _GTL_NS_SYMBOL_INNER(ns, symbol) ns ## _ ## symbol
 | 
			
		||||
  #define _GTL_NS_SYMBOL_MIDDLE(ns, symbol) _GTL_NS_SYMBOL_INNER(ns, symbol)
 | 
			
		||||
  #define _GTL_NS_SYMBOL(symbol) _GTL_NS_SYMBOL_MIDDLE(GTL_TARGET_NAMESPACE, symbol)
 | 
			
		||||
 | 
			
		||||
  #define _GTL_NS_STRING_INNER(ns) #ns
 | 
			
		||||
  #define _GTL_NS_STRING_MIDDLE(ns) _GTL_NS_STRING_INNER(ns)
 | 
			
		||||
  #define GTL_TARGET_NAMESPACE_STRING _GTL_NS_STRING_MIDDLE(GTL_TARGET_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
  #define GTLBatchQuery              _GTL_NS_SYMBOL(GTLBatchQuery)
 | 
			
		||||
  #define GTLBatchResult             _GTL_NS_SYMBOL(GTLBatchResult)
 | 
			
		||||
  #define GTLCollectionObject        _GTL_NS_SYMBOL(GTLCollectionObject)
 | 
			
		||||
  #define GTLDateTime                _GTL_NS_SYMBOL(GTLDateTime)
 | 
			
		||||
  #define GTLErrorObject             _GTL_NS_SYMBOL(GTLErrorObject)
 | 
			
		||||
  #define GTLErrorObjectData         _GTL_NS_SYMBOL(GTLErrorObjectData)
 | 
			
		||||
  #define GTLJSONParser              _GTL_NS_SYMBOL(GTLJSONParser)
 | 
			
		||||
  #define GTLObject                  _GTL_NS_SYMBOL(GTLObject)
 | 
			
		||||
  #define GTLQuery                   _GTL_NS_SYMBOL(GTLQuery)
 | 
			
		||||
  #define GTLRuntimeCommon           _GTL_NS_SYMBOL(GTLRuntimeCommon)
 | 
			
		||||
  #define GTLService                 _GTL_NS_SYMBOL(GTLService)
 | 
			
		||||
  #define GTLServiceTicket           _GTL_NS_SYMBOL(GTLServiceTicket)
 | 
			
		||||
  #define GTLUploadParameters        _GTL_NS_SYMBOL(GTLUploadParameters)
 | 
			
		||||
  #define GTLUtilities               _GTL_NS_SYMBOL(GTLUtilities)
 | 
			
		||||
  #define GTMCachedURLResponse       _GTL_NS_SYMBOL(GTMCachedURLResponse)
 | 
			
		||||
  #define GTMCookieStorage           _GTL_NS_SYMBOL(GTMCookieStorage)
 | 
			
		||||
  #define GTMGatherInputStream       _GTL_NS_SYMBOL(GTMGatherInputStream)
 | 
			
		||||
  #define GTMHTTPFetcher             _GTL_NS_SYMBOL(GTMHTTPFetcher)
 | 
			
		||||
  #define GTMHTTPFetcherService      _GTL_NS_SYMBOL(GTMHTTPFetcherService)
 | 
			
		||||
  #define GTMHTTPFetchHistory        _GTL_NS_SYMBOL(GTMHTTPFetchHistory)
 | 
			
		||||
  #define GTMHTTPUploadFetcher       _GTL_NS_SYMBOL(GTMHTTPUploadFetcher)
 | 
			
		||||
  #define GTMMIMEDocument            _GTL_NS_SYMBOL(GTMMIMEDocument)
 | 
			
		||||
  #define GTMMIMEPart                _GTL_NS_SYMBOL(GTMMIMEPart)
 | 
			
		||||
  #define GTMOAuth2Authentication    _GTL_NS_SYMBOL(GTMOAuth2Authentication)
 | 
			
		||||
  #define GTMOAuth2AuthorizationArgs _GTL_NS_SYMBOL(GTMOAuth2AuthorizationArgs)
 | 
			
		||||
  #define GTMOAuth2SignIn            _GTL_NS_SYMBOL(GTMOAuth2SignIn)
 | 
			
		||||
  #define GTMOAuth2WindowController  _GTL_NS_SYMBOL(GTMOAuth2WindowController)
 | 
			
		||||
  #define GTMReadMonitorInputStream  _GTL_NS_SYMBOL(GTMReadMonitorInputStream)
 | 
			
		||||
  #define GTMURLCache                _GTL_NS_SYMBOL(GTMURLCache)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										57
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,57 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLUploadParameters.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLDefines.h"
 | 
			
		||||
 | 
			
		||||
@interface GTLUploadParameters : NSObject <NSCopying> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSString *MIMEType_;
 | 
			
		||||
  NSData *data_;
 | 
			
		||||
  NSFileHandle *fileHandle_;
 | 
			
		||||
  NSURL *uploadLocationURL_;
 | 
			
		||||
  NSString *slug_;
 | 
			
		||||
  BOOL shouldSendUploadOnly_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uploading requires MIME type and one of
 | 
			
		||||
// - data to be uploaded
 | 
			
		||||
// - file handle for uploading
 | 
			
		||||
@property (copy) NSString *MIMEType;
 | 
			
		||||
@property (retain) NSData *data;
 | 
			
		||||
@property (retain) NSFileHandle *fileHandle;
 | 
			
		||||
 | 
			
		||||
// Resuming an in-progress upload is done with the upload location URL,
 | 
			
		||||
// and requires a file handle for uploading
 | 
			
		||||
@property (retain) NSURL *uploadLocationURL;
 | 
			
		||||
 | 
			
		||||
// Some services need a slug (filename) header
 | 
			
		||||
@property (copy) NSString *slug;
 | 
			
		||||
 | 
			
		||||
// Uploads may be done without a JSON body in the initial request
 | 
			
		||||
@property (assign) BOOL shouldSendUploadOnly;
 | 
			
		||||
 | 
			
		||||
+ (GTLUploadParameters *)uploadParametersWithData:(NSData *)data
 | 
			
		||||
                                         MIMEType:(NSString *)mimeType;
 | 
			
		||||
 | 
			
		||||
+ (GTLUploadParameters *)uploadParametersWithFileHandle:(NSFileHandle *)fileHandle
 | 
			
		||||
                                               MIMEType:(NSString *)mimeType;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										107
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLUploadParameters.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,107 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTLObject.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <objc/runtime.h>
 | 
			
		||||
 | 
			
		||||
#import "GTLUploadParameters.h"
 | 
			
		||||
 | 
			
		||||
@implementation GTLUploadParameters
 | 
			
		||||
 | 
			
		||||
@synthesize MIMEType = MIMEType_,
 | 
			
		||||
            data = data_,
 | 
			
		||||
            fileHandle = fileHandle_,
 | 
			
		||||
            uploadLocationURL = uploadLocationURL_,
 | 
			
		||||
            slug = slug_,
 | 
			
		||||
            shouldSendUploadOnly = shouldSendUploadOnly_;
 | 
			
		||||
 | 
			
		||||
+ (GTLUploadParameters *)uploadParametersWithData:(NSData *)data
 | 
			
		||||
                                         MIMEType:(NSString *)mimeType {
 | 
			
		||||
  GTLUploadParameters *params = [[[GTLUploadParameters alloc] init] autorelease];
 | 
			
		||||
  params.data = data;
 | 
			
		||||
  params.MIMEType = mimeType;
 | 
			
		||||
  return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (GTLUploadParameters *)uploadParametersWithFileHandle:(NSFileHandle *)fileHandle
 | 
			
		||||
                                               MIMEType:(NSString *)mimeType {
 | 
			
		||||
  GTLUploadParameters *params = [[[GTLUploadParameters alloc] init] autorelease];
 | 
			
		||||
  params.fileHandle = fileHandle;
 | 
			
		||||
  params.MIMEType = mimeType;
 | 
			
		||||
  return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)copyWithZone:(NSZone *)zone {
 | 
			
		||||
  GTLUploadParameters *newParams = [[[self class] allocWithZone:zone] init];
 | 
			
		||||
  newParams.MIMEType = self.MIMEType;
 | 
			
		||||
  newParams.data = self.data;
 | 
			
		||||
  newParams.fileHandle = self.fileHandle;
 | 
			
		||||
  newParams.uploadLocationURL = self.uploadLocationURL;
 | 
			
		||||
  newParams.slug = self.slug;
 | 
			
		||||
  newParams.shouldSendUploadOnly = self.shouldSendUploadOnly;
 | 
			
		||||
  return newParams;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [MIMEType_ release];
 | 
			
		||||
  [data_ release];
 | 
			
		||||
  [fileHandle_ release];
 | 
			
		||||
  [uploadLocationURL_ release];
 | 
			
		||||
  [slug_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  NSMutableArray *array = [NSMutableArray array];
 | 
			
		||||
  NSString *str = [NSString stringWithFormat:@"MIMEType:%@", MIMEType_];
 | 
			
		||||
  [array addObject:str];
 | 
			
		||||
 | 
			
		||||
  if (data_) {
 | 
			
		||||
    str = [NSString stringWithFormat:@"data:%llu bytes",
 | 
			
		||||
           (unsigned long long)[data_ length]];
 | 
			
		||||
    [array addObject:str];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (fileHandle_) {
 | 
			
		||||
    str = [NSString stringWithFormat:@"fileHandle:%@", fileHandle_];
 | 
			
		||||
    [array addObject:str];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (uploadLocationURL_) {
 | 
			
		||||
    str = [NSString stringWithFormat:@"uploadLocation:%@",
 | 
			
		||||
           [uploadLocationURL_ absoluteString]];
 | 
			
		||||
    [array addObject:str];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (slug_) {
 | 
			
		||||
    str = [NSString stringWithFormat:@"slug:%@", slug_];
 | 
			
		||||
    [array addObject:str];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (shouldSendUploadOnly_) {
 | 
			
		||||
    [array addObject:@"shouldSendUploadOnly"];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *descStr = [array componentsJoinedByString:@", "];
 | 
			
		||||
  str = [NSString stringWithFormat:@"%@ %p: {%@}",
 | 
			
		||||
         [self class], self, descStr];
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										105
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,105 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#ifndef SKIP_GTL_DEFINES
 | 
			
		||||
  #import "GTLDefines.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// helper functions for implementing isEqual:
 | 
			
		||||
BOOL GTL_AreEqualOrBothNil(id obj1, id obj2);
 | 
			
		||||
BOOL GTL_AreBoolsEqual(BOOL b1, BOOL b2);
 | 
			
		||||
 | 
			
		||||
// Helper to ensure a number is a number.
 | 
			
		||||
//
 | 
			
		||||
// The GoogleAPI servers will send numbers >53 bits as strings to avoid
 | 
			
		||||
// bugs in some JavaScript implementations.  Work around this by catching
 | 
			
		||||
// the string and turning it back into a number.
 | 
			
		||||
NSNumber *GTL_EnsureNSNumber(NSNumber *num);
 | 
			
		||||
 | 
			
		||||
@interface GTLUtilities : NSObject
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// String encoding
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// URL encoding, different for parts of URLs and parts of URL parameters
 | 
			
		||||
//
 | 
			
		||||
// +stringByURLEncodingString just makes a string legal for a URL
 | 
			
		||||
//
 | 
			
		||||
// +stringByURLEncodingForURI also encodes some characters that are legal in
 | 
			
		||||
// URLs but should not be used in URIs,
 | 
			
		||||
// per http://bitworking.org/projects/atom/rfc5023.html#rfc.section.9.7
 | 
			
		||||
//
 | 
			
		||||
// +stringByURLEncodingStringParameter is like +stringByURLEncodingForURI but
 | 
			
		||||
// replaces space characters with + characters rather than percent-escaping them
 | 
			
		||||
//
 | 
			
		||||
+ (NSString *)stringByURLEncodingString:(NSString *)str;
 | 
			
		||||
+ (NSString *)stringByURLEncodingForURI:(NSString *)str;
 | 
			
		||||
+ (NSString *)stringByURLEncodingStringParameter:(NSString *)str;
 | 
			
		||||
 | 
			
		||||
// Percent-encoded UTF-8
 | 
			
		||||
+ (NSString *)stringByPercentEncodingUTF8ForString:(NSString *)str;
 | 
			
		||||
 | 
			
		||||
// Key-value coding searches in an array
 | 
			
		||||
//
 | 
			
		||||
// Utilities to get from an array objects having a known value (or nil)
 | 
			
		||||
// at a keyPath
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)objectsFromArray:(NSArray *)sourceArray
 | 
			
		||||
                    withValue:(id)desiredValue
 | 
			
		||||
                   forKeyPath:(NSString *)keyPath;
 | 
			
		||||
 | 
			
		||||
+ (id)firstObjectFromArray:(NSArray *)sourceArray
 | 
			
		||||
                 withValue:(id)desiredValue
 | 
			
		||||
                forKeyPath:(NSString *)keyPath;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Version helpers
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
+ (NSComparisonResult)compareVersion:(NSString *)ver1 toVersion:(NSString *)ver2;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// URL builder
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// If there are already query parameters on urlString, the new ones are simple
 | 
			
		||||
// appended after them.
 | 
			
		||||
+ (NSURL *)URLWithString:(NSString *)urlString
 | 
			
		||||
         queryParameters:(NSDictionary *)queryParameters;
 | 
			
		||||
 | 
			
		||||
// Allocate a global dictionary
 | 
			
		||||
+ (NSMutableDictionary *)newStaticDictionary;
 | 
			
		||||
 | 
			
		||||
// Walk up the class tree merging dictionaries and return the result.
 | 
			
		||||
+ (NSDictionary *)mergedClassDictionaryForSelector:(SEL)selector
 | 
			
		||||
                                        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
 | 
			
		||||
							
								
								
									
										376
									
								
								External/google-plus-ios-sdk/OpenSource/GTL/GTLUtilities.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,376 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "GTLUtilities.h"
 | 
			
		||||
 | 
			
		||||
#include <objc/runtime.h>
 | 
			
		||||
 | 
			
		||||
@implementation GTLUtilities
 | 
			
		||||
 | 
			
		||||
#pragma mark String encoding
 | 
			
		||||
 | 
			
		||||
// URL Encoding
 | 
			
		||||
 | 
			
		||||
+ (NSString *)stringByURLEncodingString:(NSString *)str {
 | 
			
		||||
  NSString *result = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NSURL's stringByAddingPercentEscapesUsingEncoding: does not escape
 | 
			
		||||
// some characters that should be escaped in URL parameters, like / and ?;
 | 
			
		||||
// we'll use CFURL to force the encoding of those
 | 
			
		||||
//
 | 
			
		||||
// Reference: http://www.ietf.org/rfc/rfc3986.txt
 | 
			
		||||
 | 
			
		||||
const CFStringRef kCharsToForceEscape = CFSTR("!*'();:@&=+$,/?%#[]");
 | 
			
		||||
 | 
			
		||||
+ (NSString *)stringByURLEncodingForURI:(NSString *)str {
 | 
			
		||||
 | 
			
		||||
  NSString *resultStr = str;
 | 
			
		||||
 | 
			
		||||
  CFStringRef originalString = (CFStringRef) str;
 | 
			
		||||
  CFStringRef leaveUnescaped = NULL;
 | 
			
		||||
 | 
			
		||||
  CFStringRef escapedStr;
 | 
			
		||||
  escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
 | 
			
		||||
                                                       originalString,
 | 
			
		||||
                                                       leaveUnescaped,
 | 
			
		||||
                                                       kCharsToForceEscape,
 | 
			
		||||
                                                       kCFStringEncodingUTF8);
 | 
			
		||||
  if (escapedStr) {
 | 
			
		||||
    resultStr = [(id)CFMakeCollectable(escapedStr) autorelease];
 | 
			
		||||
  }
 | 
			
		||||
  return resultStr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)stringByURLEncodingStringParameter:(NSString *)str {
 | 
			
		||||
  // For parameters, we'll explicitly leave spaces unescaped now, and replace
 | 
			
		||||
  // them with +'s
 | 
			
		||||
  NSString *resultStr = str;
 | 
			
		||||
 | 
			
		||||
  CFStringRef originalString = (CFStringRef) str;
 | 
			
		||||
  CFStringRef leaveUnescaped = CFSTR(" ");
 | 
			
		||||
 | 
			
		||||
  CFStringRef escapedStr;
 | 
			
		||||
  escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
 | 
			
		||||
                                                       originalString,
 | 
			
		||||
                                                       leaveUnescaped,
 | 
			
		||||
                                                       kCharsToForceEscape,
 | 
			
		||||
                                                       kCFStringEncodingUTF8);
 | 
			
		||||
 | 
			
		||||
  if (escapedStr) {
 | 
			
		||||
    NSMutableString *mutableStr = [NSMutableString stringWithString:(NSString *)escapedStr];
 | 
			
		||||
    CFRelease(escapedStr);
 | 
			
		||||
 | 
			
		||||
    // replace spaces with plusses
 | 
			
		||||
    [mutableStr replaceOccurrencesOfString:@" "
 | 
			
		||||
                                withString:@"+"
 | 
			
		||||
                                   options:0
 | 
			
		||||
                                     range:NSMakeRange(0, [mutableStr length])];
 | 
			
		||||
    resultStr = mutableStr;
 | 
			
		||||
  }
 | 
			
		||||
  return resultStr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)stringByPercentEncodingUTF8ForString:(NSString *)inputStr {
 | 
			
		||||
 | 
			
		||||
  // Encode per http://bitworking.org/projects/atom/rfc5023.html#rfc.section.9.7
 | 
			
		||||
  //
 | 
			
		||||
  // This is used for encoding upload slug headers
 | 
			
		||||
  //
 | 
			
		||||
  // Step through the string as UTF-8, and replace characters outside 20..7E
 | 
			
		||||
  // (and the percent symbol itself, 25) with percent-encodings
 | 
			
		||||
  //
 | 
			
		||||
  // We avoid creating an encoding string unless we encounter some characters
 | 
			
		||||
  // that require it
 | 
			
		||||
  const char* utf8 = [inputStr UTF8String];
 | 
			
		||||
  if (utf8 == NULL) {
 | 
			
		||||
    return nil;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSMutableString *encoded = nil;
 | 
			
		||||
 | 
			
		||||
  for (unsigned int idx = 0; utf8[idx] != '\0'; idx++) {
 | 
			
		||||
 | 
			
		||||
    unsigned char currChar = utf8[idx];
 | 
			
		||||
    if (currChar < 0x20 || currChar == 0x25 || currChar > 0x7E) {
 | 
			
		||||
 | 
			
		||||
      if (encoded == nil) {
 | 
			
		||||
        // Start encoding and catch up on the character skipped so far
 | 
			
		||||
        encoded = [[[NSMutableString alloc] initWithBytes:utf8
 | 
			
		||||
                                                   length:idx
 | 
			
		||||
                                                 encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // append this byte as a % and then uppercase hex
 | 
			
		||||
      [encoded appendFormat:@"%%%02X", currChar];
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      // This character does not need encoding
 | 
			
		||||
      //
 | 
			
		||||
      // Encoded is nil here unless we've encountered a previous character
 | 
			
		||||
      // that needed encoding
 | 
			
		||||
      [encoded appendFormat:@"%c", currChar];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (encoded) {
 | 
			
		||||
    return encoded;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return inputStr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Key-Value Coding Searches in an Array
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)objectsFromArray:(NSArray *)sourceArray
 | 
			
		||||
                    withValue:(id)desiredValue
 | 
			
		||||
                   forKeyPath:(NSString *)keyPath {
 | 
			
		||||
  // Step through all entries, get the value from
 | 
			
		||||
  // the key path, and see if it's equal to the
 | 
			
		||||
  // desired value
 | 
			
		||||
  NSMutableArray *results = [NSMutableArray array];
 | 
			
		||||
 | 
			
		||||
  for(id obj in sourceArray) {
 | 
			
		||||
    id val = [obj valueForKeyPath:keyPath];
 | 
			
		||||
    if (GTL_AreEqualOrBothNil(val, desiredValue)) {
 | 
			
		||||
 | 
			
		||||
      // found a match; add it to the results array
 | 
			
		||||
      [results addObject:obj];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return results;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)firstObjectFromArray:(NSArray *)sourceArray
 | 
			
		||||
                 withValue:(id)desiredValue
 | 
			
		||||
                forKeyPath:(NSString *)keyPath {
 | 
			
		||||
  for (id obj in sourceArray) {
 | 
			
		||||
    id val = [obj valueForKeyPath:keyPath];
 | 
			
		||||
    if (GTL_AreEqualOrBothNil(val, desiredValue)) {
 | 
			
		||||
      // found a match; return it
 | 
			
		||||
      return obj;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Version helpers
 | 
			
		||||
 | 
			
		||||
// compareVersion compares two strings in 1.2.3.4 format
 | 
			
		||||
// missing fields are interpreted as zeros, so 1.2 = 1.2.0.0
 | 
			
		||||
+ (NSComparisonResult)compareVersion:(NSString *)ver1 toVersion:(NSString *)ver2 {
 | 
			
		||||
 | 
			
		||||
  static NSCharacterSet* dotSet = nil;
 | 
			
		||||
  if (dotSet == nil) {
 | 
			
		||||
    dotSet = [[NSCharacterSet characterSetWithCharactersInString:@"."] retain];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (ver1 == nil) ver1 = @"";
 | 
			
		||||
  if (ver2 == nil) ver2 = @"";
 | 
			
		||||
 | 
			
		||||
  NSScanner* scanner1 = [NSScanner scannerWithString:ver1];
 | 
			
		||||
  NSScanner* scanner2 = [NSScanner scannerWithString:ver2];
 | 
			
		||||
 | 
			
		||||
  [scanner1 setCharactersToBeSkipped:dotSet];
 | 
			
		||||
  [scanner2 setCharactersToBeSkipped:dotSet];
 | 
			
		||||
 | 
			
		||||
  int partA1 = 0, partA2 = 0, partB1 = 0, partB2 = 0;
 | 
			
		||||
  int partC1 = 0, partC2 = 0, partD1 = 0, partD2 = 0;
 | 
			
		||||
 | 
			
		||||
  if ([scanner1 scanInt:&partA1] && [scanner1 scanInt:&partB1]
 | 
			
		||||
      && [scanner1 scanInt:&partC1] && [scanner1 scanInt:&partD1]) {
 | 
			
		||||
  }
 | 
			
		||||
  if ([scanner2 scanInt:&partA2] && [scanner2 scanInt:&partB2]
 | 
			
		||||
      && [scanner2 scanInt:&partC2] && [scanner2 scanInt:&partD2]) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (partA1 != partA2) return ((partA1 < partA2) ? NSOrderedAscending : NSOrderedDescending);
 | 
			
		||||
  if (partB1 != partB2) return ((partB1 < partB2) ? NSOrderedAscending : NSOrderedDescending);
 | 
			
		||||
  if (partC1 != partC2) return ((partC1 < partC2) ? NSOrderedAscending : NSOrderedDescending);
 | 
			
		||||
  if (partD1 != partD2) return ((partD1 < partD2) ? NSOrderedAscending : NSOrderedDescending);
 | 
			
		||||
  return NSOrderedSame;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark URL builder
 | 
			
		||||
 | 
			
		||||
+ (NSURL *)URLWithString:(NSString *)urlString
 | 
			
		||||
         queryParameters:(NSDictionary *)queryParameters {
 | 
			
		||||
  if ([urlString length] == 0) return nil;
 | 
			
		||||
 | 
			
		||||
  NSString *fullURLString;
 | 
			
		||||
  if ([queryParameters count] > 0) {
 | 
			
		||||
    NSMutableArray *queryItems = [NSMutableArray arrayWithCapacity:[queryParameters count]];
 | 
			
		||||
 | 
			
		||||
    // sort the custom parameter keys so that we have deterministic parameter
 | 
			
		||||
    // order for unit tests
 | 
			
		||||
    NSArray *queryKeys = [queryParameters allKeys];
 | 
			
		||||
    NSArray *sortedQueryKeys = [queryKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
 | 
			
		||||
 | 
			
		||||
    for (NSString *paramKey in sortedQueryKeys) {
 | 
			
		||||
      NSString *paramValue = [queryParameters valueForKey:paramKey];
 | 
			
		||||
 | 
			
		||||
      NSString *paramItem = [NSString stringWithFormat:@"%@=%@",
 | 
			
		||||
                             [self stringByURLEncodingStringParameter:paramKey],
 | 
			
		||||
                             [self stringByURLEncodingStringParameter:paramValue]];
 | 
			
		||||
 | 
			
		||||
      [queryItems addObject:paramItem];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSString *paramStr = [queryItems componentsJoinedByString:@"&"];
 | 
			
		||||
 | 
			
		||||
    BOOL hasQMark = ([urlString rangeOfString:@"?"].location == NSNotFound);
 | 
			
		||||
    char joiner = hasQMark ? '?' : '&';
 | 
			
		||||
    fullURLString = [NSString stringWithFormat:@"%@%c%@",
 | 
			
		||||
                     urlString, joiner, paramStr];
 | 
			
		||||
  } else {
 | 
			
		||||
    fullURLString = urlString;
 | 
			
		||||
  }
 | 
			
		||||
  NSURL *result = [NSURL URLWithString:fullURLString];
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Collections
 | 
			
		||||
 | 
			
		||||
+ (NSMutableDictionary *)newStaticDictionary {
 | 
			
		||||
  NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
 | 
			
		||||
 | 
			
		||||
  // make the dictionary ineligible for garbage collection
 | 
			
		||||
#if !GTL_IPHONE
 | 
			
		||||
  [[NSGarbageCollector defaultCollector] disableCollectorForPointer:dict];
 | 
			
		||||
#endif
 | 
			
		||||
  return dict;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)mergedClassDictionaryForSelector:(SEL)selector
 | 
			
		||||
                                        startClass:(Class)startClass
 | 
			
		||||
                                     ancestorClass:(Class)ancestorClass
 | 
			
		||||
                                             cache:(NSMutableDictionary *)cache {
 | 
			
		||||
  NSDictionary *result;
 | 
			
		||||
  @synchronized(cache) {
 | 
			
		||||
    result = [cache objectForKey:startClass];
 | 
			
		||||
    if (result == nil) {
 | 
			
		||||
      // Collect the class's dictionary.
 | 
			
		||||
      NSDictionary *classDict = [startClass performSelector:selector];
 | 
			
		||||
 | 
			
		||||
      // Collect the parent class's merged dictionary.
 | 
			
		||||
      NSDictionary *parentClassMergedDict;
 | 
			
		||||
      if ([startClass isEqual:ancestorClass]) {
 | 
			
		||||
        parentClassMergedDict = nil;
 | 
			
		||||
      } else {
 | 
			
		||||
        Class parentClass = class_getSuperclass(startClass);
 | 
			
		||||
        parentClassMergedDict =
 | 
			
		||||
          [GTLUtilities mergedClassDictionaryForSelector:selector
 | 
			
		||||
                                              startClass:parentClass
 | 
			
		||||
                                           ancestorClass:ancestorClass
 | 
			
		||||
                                                   cache:cache];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Merge this class's into the parent's so things properly override.
 | 
			
		||||
      NSMutableDictionary *mergeDict;
 | 
			
		||||
      if (parentClassMergedDict != nil) {
 | 
			
		||||
        mergeDict =
 | 
			
		||||
          [NSMutableDictionary dictionaryWithDictionary:parentClassMergedDict];
 | 
			
		||||
      } else {
 | 
			
		||||
        mergeDict = [NSMutableDictionary dictionary];
 | 
			
		||||
      }
 | 
			
		||||
      if (classDict != nil) {
 | 
			
		||||
        [mergeDict addEntriesFromDictionary:classDict];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Make an immutable version.
 | 
			
		||||
      result = [NSDictionary dictionaryWithDictionary:mergeDict];
 | 
			
		||||
 | 
			
		||||
      // Save it.
 | 
			
		||||
      [cache setObject:result forKey:(id<NSCopying>)startClass];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  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
 | 
			
		||||
// being nil. We'll use this utility instead.
 | 
			
		||||
BOOL GTL_AreEqualOrBothNil(id obj1, id obj2) {
 | 
			
		||||
  if (obj1 == obj2) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
  if (obj1 && obj2) {
 | 
			
		||||
    BOOL areEqual = [obj1 isEqual:obj2];
 | 
			
		||||
    return areEqual;
 | 
			
		||||
  }
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL GTL_AreBoolsEqual(BOOL b1, BOOL b2) {
 | 
			
		||||
  // avoid comparison problems with boolean types by negating
 | 
			
		||||
  // both booleans
 | 
			
		||||
  return (!b1 == !b2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSNumber *GTL_EnsureNSNumber(NSNumber *num) {
 | 
			
		||||
  if ([num isKindOfClass:[NSString class]]) {
 | 
			
		||||
    NSDecimalNumber *reallyNum;
 | 
			
		||||
    // Force the parse to use '.' as the number seperator.
 | 
			
		||||
    static NSLocale *usLocale = nil;
 | 
			
		||||
    @synchronized([GTLUtilities class]) {
 | 
			
		||||
      if (usLocale == nil) {
 | 
			
		||||
        usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
 | 
			
		||||
      }
 | 
			
		||||
      reallyNum = [NSDecimalNumber decimalNumberWithString:(NSString*)num
 | 
			
		||||
                                                    locale:(id)usLocale];
 | 
			
		||||
    }
 | 
			
		||||
    if (reallyNum != nil) {
 | 
			
		||||
      num = reallyNum;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return num;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										439
									
								
								External/google-plus-ios-sdk/OpenSource/GTMDefines.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,439 @@
 | 
			
		||||
//
 | 
			
		||||
// GTMDefines.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
#include <AvailabilityMacros.h>
 | 
			
		||||
#include <TargetConditionals.h>
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE
 | 
			
		||||
#include <Availability.h>
 | 
			
		||||
#endif //  TARGET_OS_IPHONE
 | 
			
		||||
 | 
			
		||||
// Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
 | 
			
		||||
#ifndef MAC_OS_X_VERSION_10_5
 | 
			
		||||
  #define MAC_OS_X_VERSION_10_5 1050
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MAC_OS_X_VERSION_10_6
 | 
			
		||||
  #define MAC_OS_X_VERSION_10_6 1060
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MAC_OS_X_VERSION_10_7
 | 
			
		||||
  #define MAC_OS_X_VERSION_10_7 1070
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Not all __IPHONE_X macros defined in past SDKs
 | 
			
		||||
#ifndef __IPHONE_3_0
 | 
			
		||||
  #define __IPHONE_3_0 30000
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __IPHONE_3_1
 | 
			
		||||
  #define __IPHONE_3_1 30100
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __IPHONE_3_2
 | 
			
		||||
  #define __IPHONE_3_2 30200
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __IPHONE_4_0
 | 
			
		||||
  #define __IPHONE_4_0 40000
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __IPHONE_4_3
 | 
			
		||||
  #define __IPHONE_4_3 40300
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef __IPHONE_5_0
 | 
			
		||||
  #define __IPHONE_5_0 50000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// CPP symbols that can be overridden in a prefix to control how the toolbox
 | 
			
		||||
// is compiled.
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
 | 
			
		||||
// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
 | 
			
		||||
// when a validation fails. If you implement your own validators, you may want
 | 
			
		||||
// to control their internals using the same macros for consistency.
 | 
			
		||||
#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
 | 
			
		||||
  #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Give ourselves a consistent way to do inlines.  Apple's macros even use
 | 
			
		||||
// a few different actual definitions, so we're based off of the foundation
 | 
			
		||||
// one.
 | 
			
		||||
#if !defined(GTM_INLINE)
 | 
			
		||||
  #if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
 | 
			
		||||
    #define GTM_INLINE static __inline__ __attribute__((always_inline))
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTM_INLINE static __inline__
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Give ourselves a consistent way of doing externs that links up nicely
 | 
			
		||||
// when mixing objc and objc++
 | 
			
		||||
#if !defined (GTM_EXTERN)
 | 
			
		||||
  #if defined __cplusplus
 | 
			
		||||
    #define GTM_EXTERN extern "C"
 | 
			
		||||
    #define GTM_EXTERN_C_BEGIN extern "C" {
 | 
			
		||||
    #define GTM_EXTERN_C_END }
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTM_EXTERN extern
 | 
			
		||||
    #define GTM_EXTERN_C_BEGIN
 | 
			
		||||
    #define GTM_EXTERN_C_END
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Give ourselves a consistent way of exporting things if we have visibility
 | 
			
		||||
// set to hidden.
 | 
			
		||||
#if !defined (GTM_EXPORT)
 | 
			
		||||
  #define GTM_EXPORT __attribute__((visibility("default")))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Give ourselves a consistent way of declaring something as unused. This
 | 
			
		||||
// doesn't use __unused because that is only supported in gcc 4.2 and greater.
 | 
			
		||||
#if !defined (GTM_UNUSED)
 | 
			
		||||
#define GTM_UNUSED(x) ((void)(x))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// _GTMDevLog & _GTMDevAssert
 | 
			
		||||
//
 | 
			
		||||
// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
 | 
			
		||||
// developer level errors.  This implementation simply macros to NSLog/NSAssert.
 | 
			
		||||
// It is not intended to be a general logging/reporting system.
 | 
			
		||||
//
 | 
			
		||||
// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
 | 
			
		||||
// for a little more background on the usage of these macros.
 | 
			
		||||
//
 | 
			
		||||
//    _GTMDevLog           log some error/problem in debug builds
 | 
			
		||||
//    _GTMDevAssert        assert if conditon isn't met w/in a method/function
 | 
			
		||||
//                           in all builds.
 | 
			
		||||
//
 | 
			
		||||
// To replace this system, just provide different macro definitions in your
 | 
			
		||||
// prefix header.  Remember, any implementation you provide *must* be thread
 | 
			
		||||
// safe since this could be called by anything in what ever situtation it has
 | 
			
		||||
// been placed in.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// We only define the simple macros if nothing else has defined this.
 | 
			
		||||
#ifndef _GTMDevLog
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
  #define _GTMDevLog(...) NSLog(__VA_ARGS__)
 | 
			
		||||
#else
 | 
			
		||||
  #define _GTMDevLog(...) do { } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _GTMDevLog
 | 
			
		||||
 | 
			
		||||
#ifndef _GTMDevAssert
 | 
			
		||||
// we directly invoke the NSAssert handler so we can pass on the varargs
 | 
			
		||||
// (NSAssert doesn't have a macro we can use that takes varargs)
 | 
			
		||||
#if !defined(NS_BLOCK_ASSERTIONS)
 | 
			
		||||
  #define _GTMDevAssert(condition, ...)                                       \
 | 
			
		||||
    do {                                                                      \
 | 
			
		||||
      if (!(condition)) {                                                     \
 | 
			
		||||
        [[NSAssertionHandler currentHandler]                                  \
 | 
			
		||||
            handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
 | 
			
		||||
                               file:[NSString stringWithUTF8String:__FILE__]  \
 | 
			
		||||
                         lineNumber:__LINE__                                  \
 | 
			
		||||
                        description:__VA_ARGS__];                             \
 | 
			
		||||
      }                                                                       \
 | 
			
		||||
    } while(0)
 | 
			
		||||
#else // !defined(NS_BLOCK_ASSERTIONS)
 | 
			
		||||
  #define _GTMDevAssert(condition, ...) do { } while (0)
 | 
			
		||||
#endif // !defined(NS_BLOCK_ASSERTIONS)
 | 
			
		||||
 | 
			
		||||
#endif // _GTMDevAssert
 | 
			
		||||
 | 
			
		||||
// _GTMCompileAssert
 | 
			
		||||
// _GTMCompileAssert is an assert that is meant to fire at compile time if you
 | 
			
		||||
// want to check things at compile instead of runtime. For example if you
 | 
			
		||||
// want to check that a wchar is 4 bytes instead of 2 you would use
 | 
			
		||||
// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
 | 
			
		||||
// Note that the second "arg" is not in quotes, and must be a valid processor
 | 
			
		||||
// symbol in it's own right (no spaces, punctuation etc).
 | 
			
		||||
 | 
			
		||||
// Wrapping this in an #ifndef allows external groups to define their own
 | 
			
		||||
// compile time assert scheme.
 | 
			
		||||
#ifndef _GTMCompileAssert
 | 
			
		||||
  // We got this technique from here:
 | 
			
		||||
  // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
 | 
			
		||||
 | 
			
		||||
  #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
 | 
			
		||||
  #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
 | 
			
		||||
  #define _GTMCompileAssert(test, msg) \
 | 
			
		||||
    typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
 | 
			
		||||
#endif // _GTMCompileAssert
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// CPP symbols defined based on the project settings so the GTM code has
 | 
			
		||||
// simple things to test against w/o scattering the knowledge of project
 | 
			
		||||
// setting through all the code.
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// Provide a single constant CPP symbol that all of GTM uses for ifdefing
 | 
			
		||||
// iPhone code.
 | 
			
		||||
#if TARGET_OS_IPHONE // iPhone SDK
 | 
			
		||||
  // For iPhone specific stuff
 | 
			
		||||
  #define GTM_IPHONE_SDK 1
 | 
			
		||||
  #if TARGET_IPHONE_SIMULATOR
 | 
			
		||||
    #define GTM_IPHONE_SIMULATOR 1
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTM_IPHONE_DEVICE 1
 | 
			
		||||
  #endif  // TARGET_IPHONE_SIMULATOR
 | 
			
		||||
  // By default, GTM has provided it's own unittesting support, define this
 | 
			
		||||
  // to use the support provided by Xcode, especially for the Xcode4 support
 | 
			
		||||
  // for unittesting.
 | 
			
		||||
  #ifndef GTM_IPHONE_USE_SENTEST
 | 
			
		||||
    #define GTM_IPHONE_USE_SENTEST 0
 | 
			
		||||
  #endif
 | 
			
		||||
#else
 | 
			
		||||
  // For MacOS specific stuff
 | 
			
		||||
  #define GTM_MACOS_SDK 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Some of our own availability macros
 | 
			
		||||
#if GTM_MACOS_SDK
 | 
			
		||||
#define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
 | 
			
		||||
#define GTM_AVAILABLE_ONLY_ON_MACOS
 | 
			
		||||
#else
 | 
			
		||||
#define GTM_AVAILABLE_ONLY_ON_IPHONE
 | 
			
		||||
#define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Provide a symbol to include/exclude extra code for GC support.  (This mainly
 | 
			
		||||
// just controls the inclusion of finalize methods).
 | 
			
		||||
#ifndef GTM_SUPPORT_GC
 | 
			
		||||
  #if GTM_IPHONE_SDK
 | 
			
		||||
    // iPhone never needs GC
 | 
			
		||||
    #define GTM_SUPPORT_GC 0
 | 
			
		||||
  #else
 | 
			
		||||
    // We can't find a symbol to tell if GC is supported/required, so best we
 | 
			
		||||
    // do on Mac targets is include it if we're on 10.5 or later.
 | 
			
		||||
    #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
 | 
			
		||||
      #define GTM_SUPPORT_GC 0
 | 
			
		||||
    #else
 | 
			
		||||
      #define GTM_SUPPORT_GC 1
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// To simplify support for 64bit (and Leopard in general), we provide the type
 | 
			
		||||
// defines for non Leopard SDKs
 | 
			
		||||
#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
 | 
			
		||||
 // NSInteger/NSUInteger and Max/Mins
 | 
			
		||||
  #ifndef NSINTEGER_DEFINED
 | 
			
		||||
    #if __LP64__ || NS_BUILD_32_LIKE_64
 | 
			
		||||
      typedef long NSInteger;
 | 
			
		||||
      typedef unsigned long NSUInteger;
 | 
			
		||||
    #else
 | 
			
		||||
      typedef int NSInteger;
 | 
			
		||||
      typedef unsigned int NSUInteger;
 | 
			
		||||
    #endif
 | 
			
		||||
    #define NSIntegerMax    LONG_MAX
 | 
			
		||||
    #define NSIntegerMin    LONG_MIN
 | 
			
		||||
    #define NSUIntegerMax   ULONG_MAX
 | 
			
		||||
    #define NSINTEGER_DEFINED 1
 | 
			
		||||
  #endif  // NSINTEGER_DEFINED
 | 
			
		||||
  // CGFloat
 | 
			
		||||
  #ifndef CGFLOAT_DEFINED
 | 
			
		||||
    #if defined(__LP64__) && __LP64__
 | 
			
		||||
      // This really is an untested path (64bit on Tiger?)
 | 
			
		||||
      typedef double CGFloat;
 | 
			
		||||
      #define CGFLOAT_MIN DBL_MIN
 | 
			
		||||
      #define CGFLOAT_MAX DBL_MAX
 | 
			
		||||
      #define CGFLOAT_IS_DOUBLE 1
 | 
			
		||||
    #else /* !defined(__LP64__) || !__LP64__ */
 | 
			
		||||
      typedef float CGFloat;
 | 
			
		||||
      #define CGFLOAT_MIN FLT_MIN
 | 
			
		||||
      #define CGFLOAT_MAX FLT_MAX
 | 
			
		||||
      #define CGFLOAT_IS_DOUBLE 0
 | 
			
		||||
    #endif /* !defined(__LP64__) || !__LP64__ */
 | 
			
		||||
    #define CGFLOAT_DEFINED 1
 | 
			
		||||
  #endif // CGFLOAT_DEFINED
 | 
			
		||||
#endif  // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
 | 
			
		||||
 | 
			
		||||
// Some support for advanced clang static analysis functionality
 | 
			
		||||
// See http://clang-analyzer.llvm.org/annotations.html
 | 
			
		||||
#ifndef __has_feature      // Optional.
 | 
			
		||||
  #define __has_feature(x) 0 // Compatibility with non-clang compilers.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NS_RETURNS_RETAINED
 | 
			
		||||
  #if __has_feature(attribute_ns_returns_retained)
 | 
			
		||||
    #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
 | 
			
		||||
  #else
 | 
			
		||||
    #define NS_RETURNS_RETAINED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NS_RETURNS_NOT_RETAINED
 | 
			
		||||
  #if __has_feature(attribute_ns_returns_not_retained)
 | 
			
		||||
    #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
 | 
			
		||||
  #else
 | 
			
		||||
    #define NS_RETURNS_NOT_RETAINED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CF_RETURNS_RETAINED
 | 
			
		||||
  #if __has_feature(attribute_cf_returns_retained)
 | 
			
		||||
    #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 | 
			
		||||
  #else
 | 
			
		||||
    #define CF_RETURNS_RETAINED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CF_RETURNS_NOT_RETAINED
 | 
			
		||||
  #if __has_feature(attribute_cf_returns_not_retained)
 | 
			
		||||
    #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
 | 
			
		||||
  #else
 | 
			
		||||
    #define CF_RETURNS_NOT_RETAINED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NS_CONSUMED
 | 
			
		||||
  #if __has_feature(attribute_ns_consumed)
 | 
			
		||||
    #define NS_CONSUMED __attribute__((ns_consumed))
 | 
			
		||||
  #else
 | 
			
		||||
    #define NS_CONSUMED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CF_CONSUMED
 | 
			
		||||
  #if __has_feature(attribute_cf_consumed)
 | 
			
		||||
    #define CF_CONSUMED __attribute__((cf_consumed))
 | 
			
		||||
  #else
 | 
			
		||||
    #define CF_CONSUMED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NS_CONSUMES_SELF
 | 
			
		||||
  #if __has_feature(attribute_ns_consumes_self)
 | 
			
		||||
    #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
 | 
			
		||||
  #else
 | 
			
		||||
    #define NS_CONSUMES_SELF
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Defined on 10.6 and above.
 | 
			
		||||
#ifndef NS_FORMAT_ARGUMENT
 | 
			
		||||
  #define NS_FORMAT_ARGUMENT(A)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Defined on 10.6 and above.
 | 
			
		||||
#ifndef NS_FORMAT_FUNCTION
 | 
			
		||||
  #define NS_FORMAT_FUNCTION(F,A)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Defined on 10.6 and above.
 | 
			
		||||
#ifndef CF_FORMAT_ARGUMENT
 | 
			
		||||
  #define CF_FORMAT_ARGUMENT(A)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Defined on 10.6 and above.
 | 
			
		||||
#ifndef CF_FORMAT_FUNCTION
 | 
			
		||||
  #define CF_FORMAT_FUNCTION(F,A)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef GTM_NONNULL
 | 
			
		||||
  #define GTM_NONNULL(x) __attribute__((nonnull(x)))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Invalidates the initializer from which it's called.
 | 
			
		||||
#ifndef GTMInvalidateInitializer
 | 
			
		||||
  #if __has_feature(objc_arc)
 | 
			
		||||
    #define GTMInvalidateInitializer() \
 | 
			
		||||
      do { \
 | 
			
		||||
        _GTMDevAssert(NO, @"Invalid initializer."); \
 | 
			
		||||
        return nil; \
 | 
			
		||||
      } while (0)
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTMInvalidateInitializer() \
 | 
			
		||||
      do { \
 | 
			
		||||
        [self release]; \
 | 
			
		||||
        _GTMDevAssert(NO, @"Invalid initializer."); \
 | 
			
		||||
        return nil; \
 | 
			
		||||
      } while (0)
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __OBJC__
 | 
			
		||||
 | 
			
		||||
// Declared here so that it can easily be used for logging tracking if
 | 
			
		||||
// necessary. See GTMUnitTestDevLog.h for details.
 | 
			
		||||
@class NSString;
 | 
			
		||||
GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2);
 | 
			
		||||
 | 
			
		||||
// Macro to allow you to create NSStrings out of other macros.
 | 
			
		||||
// #define FOO foo
 | 
			
		||||
// NSString *fooString = GTM_NSSTRINGIFY(FOO);
 | 
			
		||||
#if !defined (GTM_NSSTRINGIFY)
 | 
			
		||||
  #define GTM_NSSTRINGIFY_INNER(x) @#x
 | 
			
		||||
  #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Macro to allow fast enumeration when building for 10.5 or later, and
 | 
			
		||||
// reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration
 | 
			
		||||
// does keys, so pick the right thing, nothing is done on the FastEnumeration
 | 
			
		||||
// side to be sure you're getting what you wanted.
 | 
			
		||||
#ifndef GTM_FOREACH_OBJECT
 | 
			
		||||
  #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
    #define GTM_FOREACH_ENUMEREE(element, enumeration) \
 | 
			
		||||
      for (element in enumeration)
 | 
			
		||||
    #define GTM_FOREACH_OBJECT(element, collection) \
 | 
			
		||||
      for (element in collection)
 | 
			
		||||
    #define GTM_FOREACH_KEY(element, collection) \
 | 
			
		||||
      for (element in collection)
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTM_FOREACH_ENUMEREE(element, enumeration) \
 | 
			
		||||
      for (NSEnumerator *_ ## element ## _enum = enumeration; \
 | 
			
		||||
           (element = [_ ## element ## _enum nextObject]) != nil; )
 | 
			
		||||
    #define GTM_FOREACH_OBJECT(element, collection) \
 | 
			
		||||
      GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
 | 
			
		||||
    #define GTM_FOREACH_KEY(element, collection) \
 | 
			
		||||
      GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
// To simplify support for both Leopard and Snow Leopard we declare
 | 
			
		||||
// the Snow Leopard protocols that we need here.
 | 
			
		||||
#if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
 | 
			
		||||
#define GTM_10_6_PROTOCOLS_DEFINED 1
 | 
			
		||||
@protocol NSConnectionDelegate
 | 
			
		||||
@end
 | 
			
		||||
@protocol NSAnimationDelegate
 | 
			
		||||
@end
 | 
			
		||||
@protocol NSImageDelegate
 | 
			
		||||
@end
 | 
			
		||||
@protocol NSTabViewDelegate
 | 
			
		||||
@end
 | 
			
		||||
#endif  // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
 | 
			
		||||
 | 
			
		||||
// GTM_SEL_STRING is for specifying selector (usually property) names to KVC
 | 
			
		||||
// or KVO methods.
 | 
			
		||||
// In debug it will generate warnings for undeclared selectors if
 | 
			
		||||
// -Wunknown-selector is turned on.
 | 
			
		||||
// In release it will have no runtime overhead.
 | 
			
		||||
#ifndef GTM_SEL_STRING
 | 
			
		||||
  #ifdef DEBUG
 | 
			
		||||
    #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
 | 
			
		||||
  #else
 | 
			
		||||
    #define GTM_SEL_STRING(selName) @#selName
 | 
			
		||||
  #endif  // DEBUG
 | 
			
		||||
#endif  // GTM_SEL_STRING
 | 
			
		||||
 | 
			
		||||
#endif // __OBJC__
 | 
			
		||||
							
								
								
									
										72
									
								
								External/google-plus-ios-sdk/OpenSource/GTMGarbageCollection.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,72 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMGarbageCollection.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTMDefines.h"
 | 
			
		||||
 | 
			
		||||
// This allows us to easily move our code from GC to non GC.
 | 
			
		||||
// They are no-ops unless we are require Leopard or above.
 | 
			
		||||
// See 
 | 
			
		||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/index.html
 | 
			
		||||
// and
 | 
			
		||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html#//apple_ref/doc/uid/TP40006687-SW1
 | 
			
		||||
// for details.
 | 
			
		||||
 | 
			
		||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) && !GTM_IPHONE_SDK
 | 
			
		||||
// General use would be to call this through GTMCFAutorelease
 | 
			
		||||
// but there may be a reason the you want to make something collectable
 | 
			
		||||
// but not autoreleased, especially in pure GC code where you don't
 | 
			
		||||
// want to bother with the nop autorelease. Done as a define instead of an 
 | 
			
		||||
// inline so that tools like Clang's scan-build don't report code as leaking.
 | 
			
		||||
#define GTMNSMakeCollectable(cf) ((id)NSMakeCollectable(cf))
 | 
			
		||||
 | 
			
		||||
// GTMNSMakeUncollectable is for global maps, etc. that we don't
 | 
			
		||||
// want released ever. You should still retain these in non-gc code.
 | 
			
		||||
GTM_INLINE void GTMNSMakeUncollectable(id object) {
 | 
			
		||||
  [[NSGarbageCollector defaultCollector] disableCollectorForPointer:object];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hopefully no code really needs this, but GTMIsGarbageCollectionEnabled is
 | 
			
		||||
// a common way to check at runtime if GC is on.
 | 
			
		||||
// There are some places where GC doesn't work w/ things w/in Apple's
 | 
			
		||||
// frameworks, so this is here so GTM unittests and detect it, and not run
 | 
			
		||||
// individual tests to work around bugs in Apple's frameworks.
 | 
			
		||||
GTM_INLINE BOOL GTMIsGarbageCollectionEnabled(void) {
 | 
			
		||||
  return ([NSGarbageCollector defaultCollector] != nil);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define GTMNSMakeCollectable(cf) ((id)(cf))
 | 
			
		||||
 | 
			
		||||
GTM_INLINE void GTMNSMakeUncollectable(id object) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GTM_INLINE BOOL GTMIsGarbageCollectionEnabled(void) {
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// GTMCFAutorelease makes a CF object collectable in GC mode, or adds it 
 | 
			
		||||
// to the autorelease pool in non-GC mode. Either way it is taken care
 | 
			
		||||
// of. Done as a define instead of an inline so that tools like Clang's
 | 
			
		||||
// scan-build don't report code as leaking.
 | 
			
		||||
#define GTMCFAutorelease(cf) ([GTMNSMakeCollectable(cf) autorelease])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										187
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,187 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTMHTTPFetchHistory.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Users of the GTMHTTPFetcher class may optionally create and set a fetch
 | 
			
		||||
// history object.  The fetch history provides "memory" between subsequent
 | 
			
		||||
// fetches, including:
 | 
			
		||||
//
 | 
			
		||||
// - For fetch responses with Etag headers, the fetch history
 | 
			
		||||
//   remembers the response headers. Future fetcher requests to the same URL
 | 
			
		||||
//   will be given an "If-None-Match" header, telling the server to return
 | 
			
		||||
//   a 304 Not Modified status if the response is unchanged, reducing the
 | 
			
		||||
//   server load and network traffic.
 | 
			
		||||
//
 | 
			
		||||
// - Optionally, the fetch history can cache the ETagged data that was returned
 | 
			
		||||
//   in the responses that contained Etag headers. If a later fetch
 | 
			
		||||
//   results in a 304 status, the fetcher will return the cached ETagged data
 | 
			
		||||
//   to the client along with a 200 status, hiding the 304.
 | 
			
		||||
//
 | 
			
		||||
// - The fetch history can track cookies.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#import "GTMHTTPFetcher.h"
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTMHTTPFETCHHISTORY_DEFINE_GLOBALS
 | 
			
		||||
  #define _EXTERN
 | 
			
		||||
  #define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
  #if defined(__cplusplus)
 | 
			
		||||
    #define _EXTERN extern "C"
 | 
			
		||||
  #else
 | 
			
		||||
    #define _EXTERN extern
 | 
			
		||||
  #endif
 | 
			
		||||
  #define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// default data cache size for when we're caching responses to handle "not
 | 
			
		||||
// modified" errors for the client
 | 
			
		||||
#if GTM_IPHONE
 | 
			
		||||
// iPhone: up to 1MB memory
 | 
			
		||||
_EXTERN const NSUInteger kGTMDefaultETaggedDataCacheMemoryCapacity _INITIALIZE_AS(1*1024*1024);
 | 
			
		||||
#else
 | 
			
		||||
// Mac OS X: up to 15MB memory
 | 
			
		||||
_EXTERN const NSUInteger kGTMDefaultETaggedDataCacheMemoryCapacity _INITIALIZE_AS(15*1024*1024);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// forward declarations
 | 
			
		||||
@class GTMURLCache;
 | 
			
		||||
@class GTMCookieStorage;
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetchHistory : NSObject <GTMHTTPFetchHistoryProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  GTMURLCache *etaggedDataCache_;
 | 
			
		||||
  BOOL shouldRememberETags_;
 | 
			
		||||
  BOOL shouldCacheETaggedData_;        // if NO, then only headers are cached
 | 
			
		||||
  GTMCookieStorage *cookieStorage_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// With caching enabled, previously-cached data will be returned instead of
 | 
			
		||||
// 304 Not Modified responses when repeating a fetch of an URL that previously
 | 
			
		||||
// included an ETag header in its response
 | 
			
		||||
@property (assign) BOOL shouldRememberETags;     // default: NO
 | 
			
		||||
@property (assign) BOOL shouldCacheETaggedData;  // default: NO
 | 
			
		||||
 | 
			
		||||
// the default ETag data cache capacity is kGTMDefaultETaggedDataCacheMemoryCapacity
 | 
			
		||||
@property (assign) NSUInteger memoryCapacity;
 | 
			
		||||
 | 
			
		||||
@property (retain) GTMCookieStorage *cookieStorage;
 | 
			
		||||
 | 
			
		||||
- (id)initWithMemoryCapacity:(NSUInteger)totalBytes
 | 
			
		||||
      shouldCacheETaggedData:(BOOL)shouldCacheETaggedData;
 | 
			
		||||
 | 
			
		||||
- (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet;
 | 
			
		||||
 | 
			
		||||
- (void)clearETaggedDataCache;
 | 
			
		||||
- (void)clearHistory;
 | 
			
		||||
 | 
			
		||||
- (void)removeAllCookies;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// GTMURLCache and GTMCachedURLResponse have interfaces similar to their
 | 
			
		||||
// NSURLCache counterparts, in hopes that someday the NSURLCache versions
 | 
			
		||||
// can be used. But in 10.5.8, those are not reliable enough except when
 | 
			
		||||
// used with +setSharedURLCache. Our goal here is just to cache
 | 
			
		||||
// responses for handling If-None-Match requests that return
 | 
			
		||||
// "Not Modified" responses, not for replacing the general URL
 | 
			
		||||
// caches.
 | 
			
		||||
 | 
			
		||||
@interface GTMCachedURLResponse : NSObject {
 | 
			
		||||
 @private
 | 
			
		||||
  NSURLResponse *response_;
 | 
			
		||||
  NSData *data_;
 | 
			
		||||
  NSDate *useDate_;         // date this response was last saved or used
 | 
			
		||||
  NSDate *reservationDate_; // date this response's ETag was used
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@property (readonly) NSURLResponse* response;
 | 
			
		||||
@property (readonly) NSData* data;
 | 
			
		||||
 | 
			
		||||
// date the response was saved or last accessed
 | 
			
		||||
@property (retain) NSDate *useDate;
 | 
			
		||||
 | 
			
		||||
// date the response's ETag header was last used for a fetch request
 | 
			
		||||
@property (retain) NSDate *reservationDate;
 | 
			
		||||
 | 
			
		||||
- (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTMURLCache : NSObject {
 | 
			
		||||
  NSMutableDictionary *responses_; // maps request URL to GTMCachedURLResponse
 | 
			
		||||
  NSUInteger memoryCapacity_;      // capacity of NSDatas in the responses
 | 
			
		||||
  NSUInteger totalDataSize_;       // sum of sizes of NSDatas of all responses
 | 
			
		||||
  NSTimeInterval reservationInterval_; // reservation expiration interval
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@property (assign) NSUInteger memoryCapacity;
 | 
			
		||||
 | 
			
		||||
- (id)initWithMemoryCapacity:(NSUInteger)totalBytes;
 | 
			
		||||
 | 
			
		||||
- (GTMCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;
 | 
			
		||||
- (void)storeCachedResponse:(GTMCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;
 | 
			
		||||
- (void)removeCachedResponseForRequest:(NSURLRequest *)request;
 | 
			
		||||
- (void)removeAllCachedResponses;
 | 
			
		||||
 | 
			
		||||
// for unit testing
 | 
			
		||||
- (void)setReservationInterval:(NSTimeInterval)secs;
 | 
			
		||||
- (NSDictionary *)responses;
 | 
			
		||||
- (NSUInteger)totalDataSize;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTMCookieStorage : NSObject <GTMCookieStorageProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  // The cookie storage object manages an array holding cookies, but the array
 | 
			
		||||
  // is allocated externally (it may be in a fetcher object or the static
 | 
			
		||||
  // fetcher cookie array.)  See the fetcher's setCookieStorageMethod:
 | 
			
		||||
  // for allocation of this object and assignment of its cookies array.
 | 
			
		||||
  NSMutableArray *cookies_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add all NSHTTPCookies in the supplied array to the storage array,
 | 
			
		||||
// replacing cookies in the storage array as appropriate
 | 
			
		||||
// Side effect: removes expired cookies from the storage array
 | 
			
		||||
- (void)setCookies:(NSArray *)newCookies;
 | 
			
		||||
 | 
			
		||||
// retrieve all cookies appropriate for the given URL, considering
 | 
			
		||||
// domain, path, cookie name, expiration, security setting.
 | 
			
		||||
// Side effect: removes expired cookies from the storage array
 | 
			
		||||
- (NSArray *)cookiesForURL:(NSURL *)theURL;
 | 
			
		||||
 | 
			
		||||
// return a cookie 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 stored cookies should
 | 
			
		||||
// be valid (non-nil name, domains, paths)
 | 
			
		||||
- (NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie;
 | 
			
		||||
 | 
			
		||||
// remove any expired cookies, excluding cookies with nil expirations
 | 
			
		||||
- (void)removeExpiredCookies;
 | 
			
		||||
 | 
			
		||||
- (void)removeAllCookies;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										590
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetchHistory.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,590 @@
 | 
			
		||||
/* Copyright (c) 2010 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTMHTTPFetchHistory.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#define GTMHTTPFETCHHISTORY_DEFINE_GLOBALS 1
 | 
			
		||||
 | 
			
		||||
#import "GTMHTTPFetchHistory.h"
 | 
			
		||||
 | 
			
		||||
const NSTimeInterval kCachedURLReservationInterval = 60.0; // 1 minute
 | 
			
		||||
static NSString* const kGTMIfNoneMatchHeader = @"If-None-Match";
 | 
			
		||||
static NSString* const kGTMETagHeader = @"Etag";
 | 
			
		||||
 | 
			
		||||
@implementation GTMCookieStorage
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    cookies_ = [[NSMutableArray alloc] init];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [cookies_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
- (void)setCookies:(NSArray *)newCookies {
 | 
			
		||||
 | 
			
		||||
  @synchronized(cookies_) {
 | 
			
		||||
    [self removeExpiredCookies];
 | 
			
		||||
 | 
			
		||||
    for (NSHTTPCookie *newCookie in newCookies) {
 | 
			
		||||
      if ([[newCookie name] length] > 0
 | 
			
		||||
          && [[newCookie domain] length] > 0
 | 
			
		||||
          && [[newCookie path] length] > 0) {
 | 
			
		||||
 | 
			
		||||
        // remove the cookie if it's currently in the array
 | 
			
		||||
        NSHTTPCookie *oldCookie = [self cookieMatchingCookie:newCookie];
 | 
			
		||||
        if (oldCookie) {
 | 
			
		||||
          [cookies_ removeObjectIdenticalTo:oldCookie];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // make sure the cookie hasn't already expired
 | 
			
		||||
        NSDate *expiresDate = [newCookie expiresDate];
 | 
			
		||||
        if ((!expiresDate) || [expiresDate timeIntervalSinceNow] > 0) {
 | 
			
		||||
          [cookies_ addObject:newCookie];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      } else {
 | 
			
		||||
        NSAssert1(NO, @"Cookie incomplete: %@", newCookie);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)deleteCookie:(NSHTTPCookie *)cookie {
 | 
			
		||||
  @synchronized(cookies_) {
 | 
			
		||||
    NSHTTPCookie *foundCookie = [self cookieMatchingCookie:cookie];
 | 
			
		||||
    if (foundCookie) {
 | 
			
		||||
      [cookies_ removeObjectIdenticalTo:foundCookie];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
- (NSArray *)cookiesForURL:(NSURL *)theURL {
 | 
			
		||||
 | 
			
		||||
  NSMutableArray *foundCookies = nil;
 | 
			
		||||
 | 
			
		||||
  @synchronized(cookies_) {
 | 
			
		||||
    [self removeExpiredCookies];
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
    NSString *host = [[theURL host] lowercaseString];
 | 
			
		||||
    NSString *path = [theURL path];
 | 
			
		||||
    NSString *scheme = [theURL scheme];
 | 
			
		||||
 | 
			
		||||
    NSString *domain = nil;
 | 
			
		||||
    BOOL isLocalhostRetrieval = NO;
 | 
			
		||||
 | 
			
		||||
    if ([host isEqual:@"localhost"]) {
 | 
			
		||||
      isLocalhostRetrieval = YES;
 | 
			
		||||
    } else {
 | 
			
		||||
      if (host) {
 | 
			
		||||
        domain = [@"." stringByAppendingString:host];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSUInteger numberOfCookies = [cookies_ count];
 | 
			
		||||
    for (NSUInteger idx = 0; idx < numberOfCookies; idx++) {
 | 
			
		||||
 | 
			
		||||
      NSHTTPCookie *storedCookie = [cookies_ objectAtIndex:idx];
 | 
			
		||||
 | 
			
		||||
      NSString *cookieDomain = [[storedCookie domain] lowercaseString];
 | 
			
		||||
      NSString *cookiePath = [storedCookie path];
 | 
			
		||||
      BOOL cookieIsSecure = [storedCookie isSecure];
 | 
			
		||||
 | 
			
		||||
      BOOL isDomainOK;
 | 
			
		||||
 | 
			
		||||
      if (isLocalhostRetrieval) {
 | 
			
		||||
        // prior to 10.5.6, the domain stored into NSHTTPCookies for localhost
 | 
			
		||||
        // is "localhost.local"
 | 
			
		||||
        isDomainOK = [cookieDomain isEqual:@"localhost"]
 | 
			
		||||
          || [cookieDomain isEqual:@"localhost.local"];
 | 
			
		||||
      } else {
 | 
			
		||||
        isDomainOK = [domain hasSuffix:cookieDomain];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      BOOL isPathOK = [cookiePath isEqual:@"/"] || [path hasPrefix:cookiePath];
 | 
			
		||||
      BOOL isSecureOK = (!cookieIsSecure) || [scheme isEqual:@"https"];
 | 
			
		||||
 | 
			
		||||
      if (isDomainOK && isPathOK && isSecureOK) {
 | 
			
		||||
        if (foundCookies == nil) {
 | 
			
		||||
          foundCookies = [NSMutableArray arrayWithCapacity:1];
 | 
			
		||||
        }
 | 
			
		||||
        [foundCookies addObject:storedCookie];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  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
 | 
			
		||||
//
 | 
			
		||||
// Both the cookie being tested and all cookies in the storage array should
 | 
			
		||||
// be valid (non-nil name, domains, paths)
 | 
			
		||||
//
 | 
			
		||||
// note: this should only be called from inside a @synchronized(cookies_) block
 | 
			
		||||
- (NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie {
 | 
			
		||||
 | 
			
		||||
  NSUInteger numberOfCookies = [cookies_ count];
 | 
			
		||||
  NSString *name = [cookie name];
 | 
			
		||||
  NSString *domain = [cookie domain];
 | 
			
		||||
  NSString *path = [cookie path];
 | 
			
		||||
 | 
			
		||||
  NSAssert3(name && domain && path, @"Invalid cookie (name:%@ domain:%@ path:%@)",
 | 
			
		||||
            name, domain, path);
 | 
			
		||||
 | 
			
		||||
  for (NSUInteger idx = 0; idx < numberOfCookies; idx++) {
 | 
			
		||||
 | 
			
		||||
    NSHTTPCookie *storedCookie = [cookies_ objectAtIndex:idx];
 | 
			
		||||
 | 
			
		||||
    if ([[storedCookie name] isEqual:name]
 | 
			
		||||
        && [[storedCookie domain] isEqual:domain]
 | 
			
		||||
        && [[storedCookie path] isEqual:path]) {
 | 
			
		||||
 | 
			
		||||
      return storedCookie;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
- (void)removeExpiredCookies {
 | 
			
		||||
 | 
			
		||||
  // count backwards since we're deleting items from the array
 | 
			
		||||
  for (NSInteger idx = [cookies_ count] - 1; idx >= 0; idx--) {
 | 
			
		||||
 | 
			
		||||
    NSHTTPCookie *storedCookie = [cookies_ objectAtIndex:idx];
 | 
			
		||||
 | 
			
		||||
    NSDate *expiresDate = [storedCookie expiresDate];
 | 
			
		||||
    if (expiresDate && [expiresDate timeIntervalSinceNow] < 0) {
 | 
			
		||||
      [cookies_ removeObjectAtIndex:idx];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeAllCookies {
 | 
			
		||||
  @synchronized(cookies_) {
 | 
			
		||||
    [cookies_ removeAllObjects];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMCachedURLResponse
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@implementation GTMCachedURLResponse
 | 
			
		||||
 | 
			
		||||
@synthesize response = response_;
 | 
			
		||||
@synthesize data = data_;
 | 
			
		||||
@synthesize reservationDate = reservationDate_;
 | 
			
		||||
@synthesize useDate = useDate_;
 | 
			
		||||
 | 
			
		||||
- (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    response_ = [response retain];
 | 
			
		||||
    data_ = [data retain];
 | 
			
		||||
    useDate_ = [[NSDate alloc] init];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [response_ release];
 | 
			
		||||
  [data_ release];
 | 
			
		||||
  [useDate_ release];
 | 
			
		||||
  [reservationDate_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  NSString *reservationStr = reservationDate_ ?
 | 
			
		||||
    [NSString stringWithFormat:@" resDate:%@", reservationDate_] : @"";
 | 
			
		||||
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p: {bytes:%@ useDate:%@%@}",
 | 
			
		||||
          [self class], self,
 | 
			
		||||
          data_ ? [NSNumber numberWithInt:(int)[data_ length]] : nil,
 | 
			
		||||
          useDate_,
 | 
			
		||||
          reservationStr];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSComparisonResult)compareUseDate:(GTMCachedURLResponse *)other {
 | 
			
		||||
  return [useDate_ compare:[other useDate]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMURLCache
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@implementation GTMURLCache
 | 
			
		||||
 | 
			
		||||
@dynamic memoryCapacity;
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  return [self initWithMemoryCapacity:kGTMDefaultETaggedDataCacheMemoryCapacity];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithMemoryCapacity:(NSUInteger)totalBytes {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    memoryCapacity_ = totalBytes;
 | 
			
		||||
 | 
			
		||||
    responses_ = [[NSMutableDictionary alloc] initWithCapacity:5];
 | 
			
		||||
 | 
			
		||||
    reservationInterval_ = kCachedURLReservationInterval;
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [responses_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %p: {responses:%@}",
 | 
			
		||||
          [self class], self, [responses_ allValues]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setters/getters
 | 
			
		||||
 | 
			
		||||
- (void)pruneCacheResponses {
 | 
			
		||||
  // internal routine to remove the least-recently-used responses when the
 | 
			
		||||
  // cache has grown too large
 | 
			
		||||
  if (memoryCapacity_ >= totalDataSize_) return;
 | 
			
		||||
 | 
			
		||||
  // 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;
 | 
			
		||||
  // remove those (except ones still reserved) until the total data size is
 | 
			
		||||
  // reduced sufficiently
 | 
			
		||||
  for (NSURL *key in sortedKeys) {
 | 
			
		||||
    GTMCachedURLResponse *response = [responses_ objectForKey:key];
 | 
			
		||||
 | 
			
		||||
    NSDate *resDate = [response reservationDate];
 | 
			
		||||
    BOOL isResponseReserved = (resDate != nil)
 | 
			
		||||
      && ([resDate timeIntervalSinceNow] > -reservationInterval_);
 | 
			
		||||
 | 
			
		||||
    if (!isResponseReserved) {
 | 
			
		||||
      // 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 (memoryCapacity_ >= totalDataSize_) break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)storeCachedResponse:(GTMCachedURLResponse *)cachedResponse
 | 
			
		||||
                 forRequest:(NSURLRequest *)request {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    // remove any previous entry for this request
 | 
			
		||||
    [self removeCachedResponseForRequest:request];
 | 
			
		||||
 | 
			
		||||
    // cache this one only if it's not bigger than our cache
 | 
			
		||||
    NSUInteger storedSize = [[cachedResponse data] length];
 | 
			
		||||
    if (storedSize < memoryCapacity_) {
 | 
			
		||||
 | 
			
		||||
      NSURL *key = [request URL];
 | 
			
		||||
      [responses_ setObject:cachedResponse forKey:key];
 | 
			
		||||
      totalDataSize_ += storedSize;
 | 
			
		||||
 | 
			
		||||
      [self pruneCacheResponses];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTMCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
 | 
			
		||||
  GTMCachedURLResponse *response;
 | 
			
		||||
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    NSURL *key = [request URL];
 | 
			
		||||
    response = [[[responses_ objectForKey:key] retain] autorelease];
 | 
			
		||||
 | 
			
		||||
    // touch the date to indicate this was recently retrieved
 | 
			
		||||
    [response setUseDate:[NSDate date]];
 | 
			
		||||
  }
 | 
			
		||||
  return response;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeCachedResponseForRequest:(NSURLRequest *)request {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    NSURL *key = [request URL];
 | 
			
		||||
    totalDataSize_ -= [[[responses_ objectForKey:key] data] length];
 | 
			
		||||
    [responses_ removeObjectForKey:key];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeAllCachedResponses {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    [responses_ removeAllObjects];
 | 
			
		||||
    totalDataSize_ = 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)memoryCapacity {
 | 
			
		||||
  return memoryCapacity_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setMemoryCapacity:(NSUInteger)totalBytes {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    BOOL didShrink = (totalBytes < memoryCapacity_);
 | 
			
		||||
    memoryCapacity_ = totalBytes;
 | 
			
		||||
 | 
			
		||||
    if (didShrink) {
 | 
			
		||||
      [self pruneCacheResponses];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// methods for unit testing
 | 
			
		||||
- (void)setReservationInterval:(NSTimeInterval)secs {
 | 
			
		||||
  reservationInterval_ = secs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)responses {
 | 
			
		||||
  return responses_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)totalDataSize {
 | 
			
		||||
  return totalDataSize_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMHTTPFetchHistory
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetchHistory ()
 | 
			
		||||
- (NSString *)cachedETagForRequest:(NSURLRequest *)request;
 | 
			
		||||
- (void)removeCachedDataForRequest:(NSURLRequest *)request;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTMHTTPFetchHistory
 | 
			
		||||
 | 
			
		||||
@synthesize cookieStorage = cookieStorage_;
 | 
			
		||||
 | 
			
		||||
@dynamic shouldRememberETags;
 | 
			
		||||
@dynamic shouldCacheETaggedData;
 | 
			
		||||
@dynamic memoryCapacity;
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
 return [self initWithMemoryCapacity:kGTMDefaultETaggedDataCacheMemoryCapacity
 | 
			
		||||
              shouldCacheETaggedData:NO];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithMemoryCapacity:(NSUInteger)totalBytes
 | 
			
		||||
      shouldCacheETaggedData:(BOOL)shouldCacheETaggedData {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    etaggedDataCache_ = [[GTMURLCache alloc] initWithMemoryCapacity:totalBytes];
 | 
			
		||||
    shouldRememberETags_ = shouldCacheETaggedData;
 | 
			
		||||
    shouldCacheETaggedData_ = shouldCacheETaggedData;
 | 
			
		||||
    cookieStorage_ = [[GTMCookieStorage alloc] init];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [etaggedDataCache_ release];
 | 
			
		||||
  [cookieStorage_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (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
 | 
			
		||||
 | 
			
		||||
    // 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 (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];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)updateFetchHistoryWithRequest:(NSURLRequest *)request
 | 
			
		||||
                             response:(NSURLResponse *)response
 | 
			
		||||
                       downloadedData:(NSData *)downloadedData {
 | 
			
		||||
  if (![self shouldRememberETags]) return;
 | 
			
		||||
 | 
			
		||||
  if (![response respondsToSelector:@selector(allHeaderFields)]) return;
 | 
			
		||||
 | 
			
		||||
  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 (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;
 | 
			
		||||
 | 
			
		||||
      GTMCachedURLResponse *cachedResponse;
 | 
			
		||||
      cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
 | 
			
		||||
                                                                    data:dataToStore] autorelease];
 | 
			
		||||
      [etaggedDataCache_ storeCachedResponse:cachedResponse
 | 
			
		||||
                                forRequest:request];
 | 
			
		||||
    } else {
 | 
			
		||||
      [etaggedDataCache_ removeCachedResponseForRequest:request];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)cachedETagForRequest:(NSURLRequest *)request {
 | 
			
		||||
  GTMCachedURLResponse *cachedResponse;
 | 
			
		||||
  cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request];
 | 
			
		||||
 | 
			
		||||
  NSURLResponse *response = [cachedResponse response];
 | 
			
		||||
  NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields];
 | 
			
		||||
  NSString *cachedETag = [headers objectForKey:kGTMETagHeader];
 | 
			
		||||
  if (cachedETag) {
 | 
			
		||||
    // 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
 | 
			
		||||
    //
 | 
			
		||||
    // when the fetch completes, either the cached response will be replaced
 | 
			
		||||
    // with a new response, or the cachedDataForRequest: method below will
 | 
			
		||||
    // clear the reservation
 | 
			
		||||
    [cachedResponse setReservationDate:[NSDate date]];
 | 
			
		||||
  }
 | 
			
		||||
  return cachedETag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSData *)cachedDataForRequest:(NSURLRequest *)request {
 | 
			
		||||
  GTMCachedURLResponse *cachedResponse;
 | 
			
		||||
  cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request];
 | 
			
		||||
 | 
			
		||||
  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];
 | 
			
		||||
 | 
			
		||||
  return cachedData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeCachedDataForRequest:(NSURLRequest *)request {
 | 
			
		||||
  [etaggedDataCache_ removeCachedResponseForRequest:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearETaggedDataCache {
 | 
			
		||||
  [etaggedDataCache_ removeAllCachedResponses];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearHistory {
 | 
			
		||||
  [self clearETaggedDataCache];
 | 
			
		||||
  [cookieStorage_ removeAllCookies];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeAllCookies {
 | 
			
		||||
  [cookieStorage_ removeAllCookies];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldRememberETags {
 | 
			
		||||
  return shouldRememberETags_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setShouldRememberETags:(BOOL)flag {
 | 
			
		||||
  BOOL wasRemembering = shouldRememberETags_;
 | 
			
		||||
  shouldRememberETags_ = flag;
 | 
			
		||||
 | 
			
		||||
  if (wasRemembering && !flag) {
 | 
			
		||||
    // free up the cache memory
 | 
			
		||||
    [self clearETaggedDataCache];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldCacheETaggedData {
 | 
			
		||||
  return shouldCacheETaggedData_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setShouldCacheETaggedData:(BOOL)flag {
 | 
			
		||||
  BOOL wasCaching = shouldCacheETaggedData_;
 | 
			
		||||
  shouldCacheETaggedData_ = flag;
 | 
			
		||||
 | 
			
		||||
  if (flag) {
 | 
			
		||||
    self.shouldRememberETags = YES;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (wasCaching && !flag) {
 | 
			
		||||
    // users expect turning off caching to free up the cache memory
 | 
			
		||||
    [self clearETaggedDataCache];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)memoryCapacity {
 | 
			
		||||
  return [etaggedDataCache_ memoryCapacity];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setMemoryCapacity:(NSUInteger)totalBytes {
 | 
			
		||||
  [etaggedDataCache_ setMemoryCapacity:totalBytes];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										704
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,704 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTMHTTPFetcher.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// This is essentially a wrapper around NSURLConnection for POSTs and GETs.
 | 
			
		||||
// If setPostData: is called, then POST is assumed.
 | 
			
		||||
//
 | 
			
		||||
// When would you use this instead of NSURLConnection?
 | 
			
		||||
//
 | 
			
		||||
// - When you just want the result from a GET, POST, or PUT
 | 
			
		||||
// - When you want the "standard" behavior for connections (redirection handling
 | 
			
		||||
//   an so on)
 | 
			
		||||
// - When you want automatic retry on failures
 | 
			
		||||
// - When you want to avoid cookie collisions with Safari and other applications
 | 
			
		||||
// - When you are fetching resources with ETags and want to avoid the overhead
 | 
			
		||||
//   of repeated fetches of unchanged data
 | 
			
		||||
// - When you need to set a credential for the http operation
 | 
			
		||||
//
 | 
			
		||||
// This is assumed to be a one-shot fetch request; don't reuse the object
 | 
			
		||||
// for a second fetch.
 | 
			
		||||
//
 | 
			
		||||
// The fetcher may be created auto-released, in which case it will release
 | 
			
		||||
// itself after the fetch completion callback.  The fetcher is implicitly
 | 
			
		||||
// retained as long as a connection is pending.
 | 
			
		||||
//
 | 
			
		||||
// But if you may need to cancel the fetcher, retain it and have the delegate
 | 
			
		||||
// release the fetcher in the callbacks.
 | 
			
		||||
//
 | 
			
		||||
// Sample usage:
 | 
			
		||||
//
 | 
			
		||||
//  NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
 | 
			
		||||
//  GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
 | 
			
		||||
//
 | 
			
		||||
//  // optional upload body data
 | 
			
		||||
//  [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
//
 | 
			
		||||
//  [myFetcher beginFetchWithDelegate:self
 | 
			
		||||
//                  didFinishSelector:@selector(myFetcher:finishedWithData:error:)];
 | 
			
		||||
//
 | 
			
		||||
//  Upon fetch completion, the callback selector is invoked; it should have
 | 
			
		||||
//  this signature (you can use any callback method name you want so long as
 | 
			
		||||
//  the signature matches this):
 | 
			
		||||
//
 | 
			
		||||
//  - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error;
 | 
			
		||||
//
 | 
			
		||||
//  The block callback version looks like:
 | 
			
		||||
//
 | 
			
		||||
//  [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
 | 
			
		||||
//    if (error != nil) {
 | 
			
		||||
//      // status code or network error
 | 
			
		||||
//    } else {
 | 
			
		||||
//      // succeeded
 | 
			
		||||
//    }
 | 
			
		||||
//  }];
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// NOTE:  Fetches may retrieve data from the server even though the server
 | 
			
		||||
//        returned an error.  The failure selector is called when the server
 | 
			
		||||
//        status is >= 300, with an NSError having domain
 | 
			
		||||
//        kGTMHTTPFetcherStatusDomain and code set to the server status.
 | 
			
		||||
//
 | 
			
		||||
//        Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Downloading to disk:
 | 
			
		||||
//
 | 
			
		||||
// To have downloaded data saved directly to disk, specify either a path for the
 | 
			
		||||
// downloadPath property, or a file handle for the downloadFileHandle property.
 | 
			
		||||
// When downloading to disk, callbacks will be passed a nil for the NSData*
 | 
			
		||||
// arguments.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// HTTP methods and headers:
 | 
			
		||||
//
 | 
			
		||||
// Alternative HTTP methods, like PUT, and custom headers can be specified by
 | 
			
		||||
// creating the fetcher with an appropriate NSMutableURLRequest
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Proxies:
 | 
			
		||||
//
 | 
			
		||||
// Proxy handling is invisible so long as the system has a valid credential in
 | 
			
		||||
// the keychain, which is normally true (else most NSURL-based apps would have
 | 
			
		||||
// difficulty.)  But when there is a proxy authetication error, the the fetcher
 | 
			
		||||
// will call the failedWithError: method with the NSURLChallenge in the error's
 | 
			
		||||
// userInfo. The error method can get the challenge info like this:
 | 
			
		||||
//
 | 
			
		||||
//  NSURLAuthenticationChallenge *challenge
 | 
			
		||||
//     = [[error userInfo] objectForKey:kGTMHTTPFetcherErrorChallengeKey];
 | 
			
		||||
//  BOOL isProxyChallenge = [[challenge protectionSpace] isProxy];
 | 
			
		||||
//
 | 
			
		||||
// If a proxy error occurs, you can ask the user for the proxy username/password
 | 
			
		||||
// and call fetcher's setProxyCredential: to provide those for the
 | 
			
		||||
// next attempt to fetch.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Cookies:
 | 
			
		||||
//
 | 
			
		||||
// There are three supported mechanisms for remembering cookies between fetches.
 | 
			
		||||
//
 | 
			
		||||
// By default, GTMHTTPFetcher uses a mutable array held statically to track
 | 
			
		||||
// cookies for all instantiated fetchers. This avoids server cookies being set
 | 
			
		||||
// by servers for the application from interfering with Safari cookie settings,
 | 
			
		||||
// and vice versa.  The fetcher cookies are lost when the application quits.
 | 
			
		||||
//
 | 
			
		||||
// To rely instead on WebKit's global NSHTTPCookieStorage, call
 | 
			
		||||
// setCookieStorageMethod: with kGTMHTTPFetcherCookieStorageMethodSystemDefault.
 | 
			
		||||
//
 | 
			
		||||
// If the fetcher is created from a GTMHTTPFetcherService object
 | 
			
		||||
// then the cookie storage mechanism is set to use the cookie storage in the
 | 
			
		||||
// service object rather than the static storage.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Fetching for periodic checks:
 | 
			
		||||
//
 | 
			
		||||
// The fetcher object tracks ETag headers from responses and
 | 
			
		||||
// provide an "If-None-Match" header. This allows the server to save
 | 
			
		||||
// bandwidth by providing a status message instead of repeated response
 | 
			
		||||
// data.
 | 
			
		||||
//
 | 
			
		||||
// To get this behavior, create the fetcher from an GTMHTTPFetcherService object
 | 
			
		||||
// and look for a fetch callback error with code 304
 | 
			
		||||
// (kGTMHTTPFetcherStatusNotModified) like this:
 | 
			
		||||
//
 | 
			
		||||
// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error {
 | 
			
		||||
//    if ([error code] == kGTMHTTPFetcherStatusNotModified) {
 | 
			
		||||
//      // |data| is empty; use the data from the previous finishedWithData: for this URL
 | 
			
		||||
//    } else {
 | 
			
		||||
//      // handle other server status code
 | 
			
		||||
//    }
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Monitoring received data
 | 
			
		||||
//
 | 
			
		||||
// The optional received data selector can be set with setReceivedDataSelector:
 | 
			
		||||
// and should have the signature
 | 
			
		||||
//
 | 
			
		||||
//  - (void)myFetcher:(GTMHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar;
 | 
			
		||||
//
 | 
			
		||||
// The number bytes received so far is available as [fetcher downloadedLength].
 | 
			
		||||
// This number may go down if a redirect causes the download to begin again from
 | 
			
		||||
// a new server.
 | 
			
		||||
//
 | 
			
		||||
// If supplied by the server, the anticipated total download size is available
 | 
			
		||||
// as [[myFetcher response] expectedContentLength] (and may be -1 for unknown
 | 
			
		||||
// download sizes.)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Automatic retrying of fetches
 | 
			
		||||
//
 | 
			
		||||
// The fetcher can optionally create a timer and reattempt certain kinds of
 | 
			
		||||
// fetch failures (status codes 408, request timeout; 503, service unavailable;
 | 
			
		||||
// 504, gateway timeout; networking errors NSURLErrorTimedOut and
 | 
			
		||||
// NSURLErrorNetworkConnectionLost.)  The user may set a retry selector to
 | 
			
		||||
// customize the type of errors which will be retried.
 | 
			
		||||
//
 | 
			
		||||
// Retries are done in an exponential-backoff fashion (that is, after 1 second,
 | 
			
		||||
// 2, 4, 8, and so on.)
 | 
			
		||||
//
 | 
			
		||||
// Enabling automatic retries looks like this:
 | 
			
		||||
//  [myFetcher setRetryEnabled:YES];
 | 
			
		||||
//
 | 
			
		||||
// With retries enabled, the success or failure callbacks are called only
 | 
			
		||||
// when no more retries will be attempted. Calling the fetcher's stopFetching
 | 
			
		||||
// method will terminate the retry timer, without the finished or failure
 | 
			
		||||
// selectors being invoked.
 | 
			
		||||
//
 | 
			
		||||
// Optionally, the client may set the maximum retry interval:
 | 
			
		||||
//  [myFetcher setMaxRetryInterval:60.0]; // in seconds; default is 60 seconds
 | 
			
		||||
//                                        // for downloads, 600 for uploads
 | 
			
		||||
//
 | 
			
		||||
// Also optionally, the client may provide a callback selector to determine
 | 
			
		||||
// if a status code or other error should be retried.
 | 
			
		||||
//  [myFetcher setRetrySelector:@selector(myFetcher:willRetry:forError:)];
 | 
			
		||||
//
 | 
			
		||||
// If set, the retry selector should have the signature:
 | 
			
		||||
//   -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
 | 
			
		||||
// and return YES to set the retry timer or NO to fail without additional
 | 
			
		||||
// fetch attempts.
 | 
			
		||||
//
 | 
			
		||||
// The retry method may return the |suggestedWillRetry| argument to get the
 | 
			
		||||
// default retry behavior.  Server status codes are present in the
 | 
			
		||||
// error argument, and have the domain kGTMHTTPFetcherStatusDomain. The
 | 
			
		||||
// user's method may look something like this:
 | 
			
		||||
//
 | 
			
		||||
//  -(BOOL)myFetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error {
 | 
			
		||||
//
 | 
			
		||||
//    // perhaps examine [error domain] and [error code], or [fetcher retryCount]
 | 
			
		||||
//    //
 | 
			
		||||
//    // return YES to start the retry timer, NO to proceed to the failure
 | 
			
		||||
//    // callback, or |suggestedWillRetry| to get default behavior for the
 | 
			
		||||
//    // current error domain and code values.
 | 
			
		||||
//    return suggestedWillRetry;
 | 
			
		||||
//  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#if defined(GTL_TARGET_NAMESPACE)
 | 
			
		||||
  // we're using target namespace macros
 | 
			
		||||
  #import "GTLDefines.h"
 | 
			
		||||
#elif defined(GDATA_TARGET_NAMESPACE)
 | 
			
		||||
  #import "GDataDefines.h"
 | 
			
		||||
#else
 | 
			
		||||
  #if TARGET_OS_IPHONE
 | 
			
		||||
    #ifndef GTM_FOUNDATION_ONLY
 | 
			
		||||
      #define GTM_FOUNDATION_ONLY 1
 | 
			
		||||
    #endif
 | 
			
		||||
    #ifndef GTM_IPHONE
 | 
			
		||||
      #define GTM_IPHONE 1
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000)
 | 
			
		||||
  #define GTM_BACKGROUND_FETCHING 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTMHTTPFETCHER_DEFINE_GLOBALS
 | 
			
		||||
  #define _EXTERN
 | 
			
		||||
  #define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
  #if defined(__cplusplus)
 | 
			
		||||
    #define _EXTERN extern "C"
 | 
			
		||||
  #else
 | 
			
		||||
    #define _EXTERN extern
 | 
			
		||||
  #endif
 | 
			
		||||
  #define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// notifications
 | 
			
		||||
//
 | 
			
		||||
// fetch started and stopped, and fetch retry delay started and stopped
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherStartedNotification           _INITIALIZE_AS(@"kGTMHTTPFetcherStartedNotification");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherStoppedNotification           _INITIALIZE_AS(@"kGTMHTTPFetcherStoppedNotification");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherRetryDelayStartedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStartedNotification");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherRetryDelayStoppedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStoppedNotification");
 | 
			
		||||
 | 
			
		||||
// callback constants
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherErrorDomain       _INITIALIZE_AS(@"com.google.GTMHTTPFetcher");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherStatusDomain      _INITIALIZE_AS(@"com.google.HTTPStatus");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherErrorChallengeKey _INITIALIZE_AS(@"challenge");
 | 
			
		||||
_EXTERN NSString* const kGTMHTTPFetcherStatusDataKey     _INITIALIZE_AS(@"data");  // data returned with a kGTMHTTPFetcherStatusDomain error
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  kGTMHTTPFetcherErrorDownloadFailed = -1,
 | 
			
		||||
  kGTMHTTPFetcherErrorAuthenticationChallengeFailed = -2,
 | 
			
		||||
  kGTMHTTPFetcherErrorChunkUploadFailed = -3,
 | 
			
		||||
  kGTMHTTPFetcherErrorFileHandleException = -4,
 | 
			
		||||
  kGTMHTTPFetcherErrorBackgroundExpiration = -6,
 | 
			
		||||
 | 
			
		||||
  // The code kGTMHTTPFetcherErrorAuthorizationFailed (-5) has been removed;
 | 
			
		||||
  // look for status 401 instead.
 | 
			
		||||
 | 
			
		||||
  kGTMHTTPFetcherStatusNotModified = 304,
 | 
			
		||||
  kGTMHTTPFetcherStatusBadRequest = 400,
 | 
			
		||||
  kGTMHTTPFetcherStatusUnauthorized = 401,
 | 
			
		||||
  kGTMHTTPFetcherStatusForbidden = 403,
 | 
			
		||||
  kGTMHTTPFetcherStatusPreconditionFailed = 412
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// cookie storage methods
 | 
			
		||||
enum {
 | 
			
		||||
  kGTMHTTPFetcherCookieStorageMethodStatic = 0,
 | 
			
		||||
  kGTMHTTPFetcherCookieStorageMethodFetchHistory = 1,
 | 
			
		||||
  kGTMHTTPFetcherCookieStorageMethodSystemDefault = 2,
 | 
			
		||||
  kGTMHTTPFetcherCookieStorageMethodNone = 3
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...);
 | 
			
		||||
 | 
			
		||||
// Utility functions for applications self-identifying to servers via a
 | 
			
		||||
// user-agent header
 | 
			
		||||
 | 
			
		||||
// Make a proper app name without whitespace from the given string, removing
 | 
			
		||||
// whitespace and other characters that may be special parsed marks of
 | 
			
		||||
// the full user-agent string.
 | 
			
		||||
NSString *GTMCleanedUserAgentString(NSString *str);
 | 
			
		||||
 | 
			
		||||
// Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1"
 | 
			
		||||
NSString *GTMSystemVersionString(void);
 | 
			
		||||
 | 
			
		||||
// Make a generic name and version for the current application, like
 | 
			
		||||
// com.example.MyApp/1.2.3 relying on the bundle identifier and the
 | 
			
		||||
// CFBundleShortVersionString or CFBundleVersion.  If no bundle ID
 | 
			
		||||
// is available, the process name preceded by "proc_" is used.
 | 
			
		||||
NSString *GTMApplicationIdentifier(NSBundle *bundle);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}  // extern "C"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@class GTMHTTPFetcher;
 | 
			
		||||
 | 
			
		||||
@protocol GTMCookieStorageProtocol <NSObject>
 | 
			
		||||
// This protocol allows us to call into the service without requiring
 | 
			
		||||
// GTMCookieStorage sources in this project
 | 
			
		||||
//
 | 
			
		||||
// The public interface for cookie handling is the GTMCookieStorage class,
 | 
			
		||||
// accessible from a fetcher service object's fetchHistory or from the fetcher's
 | 
			
		||||
// +staticCookieStorage method.
 | 
			
		||||
- (NSArray *)cookiesForURL:(NSURL *)theURL;
 | 
			
		||||
- (void)setCookies:(NSArray *)newCookies;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol GTMHTTPFetchHistoryProtocol <NSObject>
 | 
			
		||||
// This protocol allows us to call the fetch history object without requiring
 | 
			
		||||
// GTMHTTPFetchHistory sources in this project
 | 
			
		||||
- (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet;
 | 
			
		||||
- (BOOL)shouldCacheETaggedData;
 | 
			
		||||
- (NSData *)cachedDataForRequest:(NSURLRequest *)request;
 | 
			
		||||
- (id <GTMCookieStorageProtocol>)cookieStorage;
 | 
			
		||||
- (void)updateFetchHistoryWithRequest:(NSURLRequest *)request
 | 
			
		||||
                             response:(NSURLResponse *)response
 | 
			
		||||
                       downloadedData:(NSData *)downloadedData;
 | 
			
		||||
- (void)removeCachedDataForRequest:(NSURLRequest *)request;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol GTMHTTPFetcherServiceProtocol <NSObject>
 | 
			
		||||
// This protocol allows us to call into the service without requiring
 | 
			
		||||
// GTMHTTPFetcherService sources in this project
 | 
			
		||||
- (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher;
 | 
			
		||||
- (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher;
 | 
			
		||||
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
 | 
			
		||||
- (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol GTMFetcherAuthorizationProtocol <NSObject>
 | 
			
		||||
@required
 | 
			
		||||
// This protocol allows us to call the authorizer without requiring its sources
 | 
			
		||||
// in this project
 | 
			
		||||
- (void)authorizeRequest:(NSMutableURLRequest *)request
 | 
			
		||||
                delegate:(id)delegate
 | 
			
		||||
       didFinishSelector:(SEL)sel;
 | 
			
		||||
 | 
			
		||||
- (void)stopAuthorization;
 | 
			
		||||
 | 
			
		||||
- (BOOL)isAuthorizingRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
- (BOOL)isAuthorizedRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
- (NSString *)userEmail;
 | 
			
		||||
 | 
			
		||||
@optional
 | 
			
		||||
@property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK
 | 
			
		||||
 | 
			
		||||
- (BOOL)primeForRefresh;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// GTMHTTPFetcher objects are used for async retrieval of an http get or post
 | 
			
		||||
//
 | 
			
		||||
// See additional comments at the beginning of this file
 | 
			
		||||
@interface GTMHTTPFetcher : NSObject {
 | 
			
		||||
 @protected
 | 
			
		||||
  NSMutableURLRequest *request_;
 | 
			
		||||
  NSURLConnection *connection_;
 | 
			
		||||
  NSMutableData *downloadedData_;
 | 
			
		||||
  NSString *downloadPath_;
 | 
			
		||||
  NSString *temporaryDownloadPath_;
 | 
			
		||||
  NSFileHandle *downloadFileHandle_;
 | 
			
		||||
  unsigned long long downloadedLength_;
 | 
			
		||||
  NSURLCredential *credential_;     // username & password
 | 
			
		||||
  NSURLCredential *proxyCredential_; // credential supplied to proxy servers
 | 
			
		||||
  NSData *postData_;
 | 
			
		||||
  NSInputStream *postStream_;
 | 
			
		||||
  NSMutableData *loggedStreamData_;
 | 
			
		||||
  NSURLResponse *response_;         // set in connection:didReceiveResponse:
 | 
			
		||||
  id delegate_;
 | 
			
		||||
  SEL finishedSel_;                 // should by implemented by delegate
 | 
			
		||||
  SEL sentDataSel_;                 // optional, set with setSentDataSelector
 | 
			
		||||
  SEL receivedDataSel_;             // optional, set with setReceivedDataSelector
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  void (^completionBlock_)(NSData *, NSError *);
 | 
			
		||||
  void (^receivedDataBlock_)(NSData *);
 | 
			
		||||
  void (^sentDataBlock_)(NSInteger, NSInteger, NSInteger);
 | 
			
		||||
  BOOL (^retryBlock_)(BOOL, NSError *);
 | 
			
		||||
#elif !__LP64__
 | 
			
		||||
  // placeholders: for 32-bit builds, keep the size of the object's ivar section
 | 
			
		||||
  // the same with and without blocks
 | 
			
		||||
  id completionPlaceholder_;
 | 
			
		||||
  id receivedDataPlaceholder_;
 | 
			
		||||
  id sentDataPlaceholder_;
 | 
			
		||||
  id retryPlaceholder_;
 | 
			
		||||
#endif
 | 
			
		||||
  BOOL hasConnectionEnded_;         // set if the connection need not be cancelled
 | 
			
		||||
  BOOL isCancellingChallenge_;      // set only when cancelling an auth challenge
 | 
			
		||||
  BOOL isStopNotificationNeeded_;   // set when start notification has been sent
 | 
			
		||||
  BOOL shouldFetchInBackground_;
 | 
			
		||||
#if GTM_BACKGROUND_FETCHING
 | 
			
		||||
  NSUInteger backgroundTaskIdentifer_; // UIBackgroundTaskIdentifier
 | 
			
		||||
#endif
 | 
			
		||||
  id userData_;                     // retained, if set by caller
 | 
			
		||||
  NSMutableDictionary *properties_; // more data retained for caller
 | 
			
		||||
  NSArray *runLoopModes_;           // optional, for 10.5 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_;
 | 
			
		||||
 | 
			
		||||
  id <GTMFetcherAuthorizationProtocol> authorizer_;
 | 
			
		||||
 | 
			
		||||
  // the service object that created and monitors this fetcher, if any
 | 
			
		||||
  id <GTMHTTPFetcherServiceProtocol> service_;
 | 
			
		||||
  NSString *serviceHost_;
 | 
			
		||||
  NSInteger servicePriority_;
 | 
			
		||||
  NSThread *thread_;
 | 
			
		||||
 | 
			
		||||
  BOOL isRetryEnabled_;             // user wants auto-retry
 | 
			
		||||
  SEL retrySel_;                    // optional; set with setRetrySelector
 | 
			
		||||
  NSTimer *retryTimer_;
 | 
			
		||||
  NSUInteger retryCount_;
 | 
			
		||||
  NSTimeInterval maxRetryInterval_; // default 600 seconds
 | 
			
		||||
  NSTimeInterval minRetryInterval_; // random between 1 and 2 seconds
 | 
			
		||||
  NSTimeInterval retryFactor_;      // default interval multiplier is 2
 | 
			
		||||
  NSTimeInterval lastRetryInterval_;
 | 
			
		||||
  BOOL hasAttemptedAuthRefresh_;
 | 
			
		||||
 | 
			
		||||
  NSString *comment_;               // comment for log
 | 
			
		||||
  NSString *log_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create a fetcher
 | 
			
		||||
//
 | 
			
		||||
// fetcherWithRequest will return an autoreleased fetcher, but if
 | 
			
		||||
// the connection is successfully created, the connection should retain the
 | 
			
		||||
// fetcher for the life of the connection as well. So the caller doesn't have
 | 
			
		||||
// to retain the fetcher explicitly unless they want to be able to cancel it.
 | 
			
		||||
+ (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
// Convenience methods that make a request, like +fetcherWithRequest
 | 
			
		||||
+ (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL;
 | 
			
		||||
+ (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString;
 | 
			
		||||
 | 
			
		||||
// Designated initializer
 | 
			
		||||
- (id)initWithRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
// Fetcher request
 | 
			
		||||
//
 | 
			
		||||
// The underlying request is mutable and may be modified by the caller
 | 
			
		||||
@property (retain) NSMutableURLRequest *mutableRequest;
 | 
			
		||||
 | 
			
		||||
// Setting the credential is optional; it is used if the connection receives
 | 
			
		||||
// an authentication challenge
 | 
			
		||||
@property (retain) NSURLCredential *credential;
 | 
			
		||||
 | 
			
		||||
// Setting the proxy credential is optional; it is used if the connection
 | 
			
		||||
// receives an authentication challenge from a proxy
 | 
			
		||||
@property (retain) NSURLCredential *proxyCredential;
 | 
			
		||||
 | 
			
		||||
// If post data or stream is not set, then a GET retrieval method is assumed
 | 
			
		||||
@property (retain) NSData *postData;
 | 
			
		||||
@property (retain) NSInputStream *postStream;
 | 
			
		||||
 | 
			
		||||
// The default cookie storage method is kGTMHTTPFetcherCookieStorageMethodStatic
 | 
			
		||||
// without a fetch history set, and kGTMHTTPFetcherCookieStorageMethodFetchHistory
 | 
			
		||||
// with a fetch history set
 | 
			
		||||
//
 | 
			
		||||
// Applications needing control of cookies across a sequence of fetches should
 | 
			
		||||
// create fetchers from a GTMHTTPFetcherService object (which encapsulates
 | 
			
		||||
// fetch history) for a well-defined cookie store
 | 
			
		||||
@property (assign) NSInteger cookieStorageMethod;
 | 
			
		||||
 | 
			
		||||
+ (id <GTMCookieStorageProtocol>)staticCookieStorage;
 | 
			
		||||
 | 
			
		||||
// Object to add authorization to the request, if needed
 | 
			
		||||
@property (retain) id <GTMFetcherAuthorizationProtocol> authorizer;
 | 
			
		||||
 | 
			
		||||
// The service object that created and monitors this fetcher, if any
 | 
			
		||||
@property (retain) id <GTMHTTPFetcherServiceProtocol> service;
 | 
			
		||||
 | 
			
		||||
// The host, if any, used to classify this fetcher in the fetcher service
 | 
			
		||||
@property (copy) NSString *serviceHost;
 | 
			
		||||
 | 
			
		||||
// The priority, if any, used for starting fetchers in the fetcher service
 | 
			
		||||
//
 | 
			
		||||
// Lower values are higher priority; the default is 0, and values may
 | 
			
		||||
// be negative or positive. This priority affects only the start order of
 | 
			
		||||
// fetchers that are being delayed by a fetcher service.
 | 
			
		||||
@property (assign) NSInteger servicePriority;
 | 
			
		||||
 | 
			
		||||
// The thread used to run this fetcher in the fetcher service
 | 
			
		||||
@property (retain) NSThread *thread;
 | 
			
		||||
 | 
			
		||||
// The delegate is retained during the connection
 | 
			
		||||
@property (retain) id delegate;
 | 
			
		||||
 | 
			
		||||
// On iOS 4 and later, the fetch may optionally continue while the app is in the
 | 
			
		||||
// background until finished or stopped by OS expiration
 | 
			
		||||
//
 | 
			
		||||
// The default value is NO
 | 
			
		||||
//
 | 
			
		||||
// For Mac OS X, background fetches are always supported, and this property
 | 
			
		||||
// is ignored
 | 
			
		||||
@property (assign) BOOL shouldFetchInBackground;
 | 
			
		||||
 | 
			
		||||
// The delegate's optional sentData selector may be used to monitor upload
 | 
			
		||||
// progress. It should have a signature like:
 | 
			
		||||
//  - (void)myFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
//              didSendBytes:(NSInteger)bytesSent
 | 
			
		||||
//            totalBytesSent:(NSInteger)totalBytesSent
 | 
			
		||||
//  totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend;
 | 
			
		||||
//
 | 
			
		||||
// +doesSupportSentDataCallback indicates if this delegate method is supported
 | 
			
		||||
+ (BOOL)doesSupportSentDataCallback;
 | 
			
		||||
 | 
			
		||||
@property (assign) SEL sentDataSelector;
 | 
			
		||||
 | 
			
		||||
// The delegate's optional receivedData selector may be used to monitor download
 | 
			
		||||
// progress. It should have a signature like:
 | 
			
		||||
//  - (void)myFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
//       receivedData:(NSData *)dataReceivedSoFar;
 | 
			
		||||
//
 | 
			
		||||
// The dataReceived argument will be nil when downloading to a path or to a
 | 
			
		||||
// file handle.
 | 
			
		||||
//
 | 
			
		||||
// Applications should not use this method to accumulate the received data;
 | 
			
		||||
// the callback method or block supplied to the beginFetch call will have
 | 
			
		||||
// the complete NSData received.
 | 
			
		||||
@property (assign) SEL receivedDataSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
// The full interface to the block is provided rather than just a typedef for
 | 
			
		||||
// its parameter list in order to get more useful code completion in the Xcode
 | 
			
		||||
// editor
 | 
			
		||||
@property (copy) void (^sentDataBlock)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend);
 | 
			
		||||
 | 
			
		||||
// The dataReceived argument will be nil when downloading to a path or to
 | 
			
		||||
// a file handle
 | 
			
		||||
@property (copy) void (^receivedDataBlock)(NSData *dataReceivedSoFar);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// retrying; see comments at the top of the file.  Calling
 | 
			
		||||
// setRetryEnabled(YES) resets the min and max retry intervals.
 | 
			
		||||
@property (assign, getter=isRetryEnabled) BOOL retryEnabled;
 | 
			
		||||
 | 
			
		||||
// Retry selector or block is optional for retries.
 | 
			
		||||
//
 | 
			
		||||
// If present, it should have the signature:
 | 
			
		||||
//   -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
 | 
			
		||||
// and return YES to cause a retry.  See comments at the top of this file.
 | 
			
		||||
@property (assign) SEL retrySelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
@property (copy) BOOL (^retryBlock)(BOOL suggestedWillRetry, NSError *error);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Retry intervals must be strictly less than maxRetryInterval, else
 | 
			
		||||
// they will be limited to maxRetryInterval and no further retries will
 | 
			
		||||
// be attempted.  Setting maxRetryInterval to 0.0 will reset it to the
 | 
			
		||||
// default value, 600 seconds.
 | 
			
		||||
 | 
			
		||||
@property (assign) NSTimeInterval maxRetryInterval;
 | 
			
		||||
 | 
			
		||||
// Starting retry interval.  Setting minRetryInterval to 0.0 will reset it
 | 
			
		||||
// to a random value between 1.0 and 2.0 seconds.  Clients should normally not
 | 
			
		||||
// call this except for unit testing.
 | 
			
		||||
@property (assign) NSTimeInterval minRetryInterval;
 | 
			
		||||
 | 
			
		||||
// Multiplier used to increase the interval between retries, typically 2.0.
 | 
			
		||||
// Clients should not need to call this.
 | 
			
		||||
@property (assign) double retryFactor;
 | 
			
		||||
 | 
			
		||||
// Number of retries attempted
 | 
			
		||||
@property (readonly) NSUInteger retryCount;
 | 
			
		||||
 | 
			
		||||
// interval delay to precede next retry
 | 
			
		||||
@property (readonly) NSTimeInterval nextRetryInterval;
 | 
			
		||||
 | 
			
		||||
// Begin fetching the request
 | 
			
		||||
//
 | 
			
		||||
// The delegate can optionally implement the finished selectors or pass NULL
 | 
			
		||||
// for it.
 | 
			
		||||
//
 | 
			
		||||
// Returns YES if the fetch is initiated.  The delegate is retained between
 | 
			
		||||
// the beginFetch call until after the finish callback.
 | 
			
		||||
//
 | 
			
		||||
// An error is passed to the callback for server statuses 300 or
 | 
			
		||||
// higher, with the status stored as the error object's code.
 | 
			
		||||
//
 | 
			
		||||
// finishedSEL has a signature like:
 | 
			
		||||
//   - (void)fetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error;
 | 
			
		||||
//
 | 
			
		||||
// If the application has specified a downloadPath or downloadFileHandle
 | 
			
		||||
// for the fetcher, the data parameter passed to the callback will be nil.
 | 
			
		||||
 | 
			
		||||
- (BOOL)beginFetchWithDelegate:(id)delegate
 | 
			
		||||
             didFinishSelector:(SEL)finishedSEL;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
- (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Returns YES if this is in the process of fetching a URL
 | 
			
		||||
- (BOOL)isFetching;
 | 
			
		||||
 | 
			
		||||
// Cancel the fetch of the request that's currently in progress
 | 
			
		||||
- (void)stopFetching;
 | 
			
		||||
 | 
			
		||||
// Return the status code from the server response
 | 
			
		||||
@property (readonly) NSInteger statusCode;
 | 
			
		||||
 | 
			
		||||
// Return the http headers from the response
 | 
			
		||||
@property (retain, readonly) NSDictionary *responseHeaders;
 | 
			
		||||
 | 
			
		||||
// The response, once it's been received
 | 
			
		||||
@property (retain) NSURLResponse *response;
 | 
			
		||||
 | 
			
		||||
// Bytes downloaded so far
 | 
			
		||||
@property (readonly) unsigned long long downloadedLength;
 | 
			
		||||
 | 
			
		||||
// Buffer of currently-downloaded data
 | 
			
		||||
@property (readonly, retain) NSData *downloadedData;
 | 
			
		||||
 | 
			
		||||
// Path in which to non-atomically create a file for storing the downloaded data
 | 
			
		||||
//
 | 
			
		||||
// The path must be set before fetching begins.  The download file handle
 | 
			
		||||
// will be created for the path, and can be used to monitor progress. If a file
 | 
			
		||||
// already exists at the path, it will be overwritten.
 | 
			
		||||
@property (copy) NSString *downloadPath;
 | 
			
		||||
 | 
			
		||||
// If downloadFileHandle is set, data received is immediately appended to
 | 
			
		||||
// the file handle rather than being accumulated in the downloadedData property
 | 
			
		||||
//
 | 
			
		||||
// The file handle supplied must allow writing and support seekToFileOffset:,
 | 
			
		||||
// and must be set before fetching begins.  Setting a download path will
 | 
			
		||||
// override the file handle property.
 | 
			
		||||
@property (retain) NSFileHandle *downloadFileHandle;
 | 
			
		||||
 | 
			
		||||
// The optional fetchHistory object is used for a sequence of fetchers to
 | 
			
		||||
// remember ETags, cache ETagged data, and store cookies.  Typically, this
 | 
			
		||||
// is set by a GTMFetcherService object when it creates a fetcher.
 | 
			
		||||
//
 | 
			
		||||
// Side effect: setting fetch history implicitly calls setCookieStorageMethod:
 | 
			
		||||
@property (retain) id <GTMHTTPFetchHistoryProtocol> fetchHistory;
 | 
			
		||||
 | 
			
		||||
// userData is retained for the convenience of the caller
 | 
			
		||||
@property (retain) id userData;
 | 
			
		||||
 | 
			
		||||
// Stored property values are retained for the convenience of the caller
 | 
			
		||||
@property (copy) NSMutableDictionary *properties;
 | 
			
		||||
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
 | 
			
		||||
- (id)propertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
- (void)addPropertiesFromDictionary:(NSDictionary *)dict;
 | 
			
		||||
 | 
			
		||||
// Comments are useful for logging
 | 
			
		||||
@property (copy) NSString *comment;
 | 
			
		||||
 | 
			
		||||
- (void)setCommentWithFormat:(id)format, ...;
 | 
			
		||||
 | 
			
		||||
// Log of request and response, if logging is enabled
 | 
			
		||||
@property (copy) NSString *log;
 | 
			
		||||
 | 
			
		||||
// Using the fetcher while a modal dialog is displayed requires setting the
 | 
			
		||||
// run-loop modes to include NSModalPanelRunLoopMode
 | 
			
		||||
@property (retain) NSArray *runLoopModes;
 | 
			
		||||
 | 
			
		||||
// Users who wish to replace GTMHTTPFetcher's use of NSURLConnection
 | 
			
		||||
// can do so globally here.  The replacement should be a subclass of
 | 
			
		||||
// NSURLConnection.
 | 
			
		||||
+ (Class)connectionClass;
 | 
			
		||||
+ (void)setConnectionClass:(Class)theClass;
 | 
			
		||||
 | 
			
		||||
// Spin the run loop, discarding events, until the fetch has completed
 | 
			
		||||
//
 | 
			
		||||
// This is only for use in testing or in tools without a user interface.
 | 
			
		||||
//
 | 
			
		||||
// Synchronous fetches should never be done by shipping apps; they are
 | 
			
		||||
// sufficient reason for rejection from the app store.
 | 
			
		||||
- (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds;
 | 
			
		||||
 | 
			
		||||
#if STRIP_GTM_FETCH_LOGGING
 | 
			
		||||
// if logging is stripped, provide a stub for the main method
 | 
			
		||||
// for controlling logging
 | 
			
		||||
+ (void)setLoggingEnabled:(BOOL)flag;
 | 
			
		||||
#endif // STRIP_GTM_FETCH_LOGGING
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										1741
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcher.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										85
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,85 @@
 | 
			
		||||
/* Copyright (c) 2010 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "GTMHTTPFetcher.h"
 | 
			
		||||
 | 
			
		||||
// GTM HTTP Logging
 | 
			
		||||
//
 | 
			
		||||
// All traffic using GTMHTTPFetcher can be easily logged.  Call
 | 
			
		||||
//
 | 
			
		||||
//   [GTMHTTPFetcher setLoggingEnabled:YES];
 | 
			
		||||
//
 | 
			
		||||
// to begin generating log files.
 | 
			
		||||
//
 | 
			
		||||
// Log files are put into a folder on the desktop called "GTMHTTPDebugLogs"
 | 
			
		||||
// unless another directory is specified with +setLoggingDirectory.
 | 
			
		||||
//
 | 
			
		||||
// In the iPhone simulator, the default logs location is the user's home
 | 
			
		||||
// directory in ~/Library/Application Support.  On the iPhone device, the
 | 
			
		||||
// default logs location is the application's documents directory on the device.
 | 
			
		||||
//
 | 
			
		||||
// Tip: use the Finder's "Sort By Date" to find the most recent logs.
 | 
			
		||||
//
 | 
			
		||||
// Each run of an application gets a separate set of log files.  An html
 | 
			
		||||
// file is generated to simplify browsing the run's http transactions.
 | 
			
		||||
// The html file includes javascript links for inline viewing of uploaded
 | 
			
		||||
// and downloaded data.
 | 
			
		||||
//
 | 
			
		||||
// A symlink is created in the logs folder to simplify finding the html file
 | 
			
		||||
// for the latest run of the application; the symlink is called
 | 
			
		||||
//
 | 
			
		||||
//   AppName_http_log_newest.html
 | 
			
		||||
//
 | 
			
		||||
// For better viewing of XML logs, use Camino or Firefox rather than Safari.
 | 
			
		||||
//
 | 
			
		||||
// Each fetcher may be given a comment to be inserted as a label in the logs,
 | 
			
		||||
// such as
 | 
			
		||||
//   [fetcher setCommentWithFormat:@"retrieve item %@", itemName];
 | 
			
		||||
//
 | 
			
		||||
// Projects may define STRIP_GTM_FETCH_LOGGING to remove logging code.
 | 
			
		||||
 | 
			
		||||
#if !STRIP_GTM_FETCH_LOGGING
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetcher (GTMHTTPFetcherLogging)
 | 
			
		||||
 | 
			
		||||
// Note: the default logs directory is ~/Desktop/GTMHTTPDebugLogs; it will be
 | 
			
		||||
// created as needed.  If a custom directory is set, the directory should
 | 
			
		||||
// already exist.
 | 
			
		||||
+ (void)setLoggingDirectory:(NSString *)path;
 | 
			
		||||
+ (NSString *)loggingDirectory;
 | 
			
		||||
 | 
			
		||||
// client apps can turn logging on and off
 | 
			
		||||
+ (void)setLoggingEnabled:(BOOL)flag;
 | 
			
		||||
+ (BOOL)isLoggingEnabled;
 | 
			
		||||
 | 
			
		||||
// client apps can turn off logging to a file if they want to only check
 | 
			
		||||
// the fetcher's log property
 | 
			
		||||
+ (void)setLoggingToFileEnabled:(BOOL)flag;
 | 
			
		||||
+ (BOOL)isLoggingToFileEnabled;
 | 
			
		||||
 | 
			
		||||
// client apps can optionally specify process name and date string used in
 | 
			
		||||
// log file names
 | 
			
		||||
+ (void)setLoggingProcessName:(NSString *)str;
 | 
			
		||||
+ (NSString *)loggingProcessName;
 | 
			
		||||
 | 
			
		||||
+ (void)setLoggingDateStamp:(NSString *)str;
 | 
			
		||||
+ (NSString *)loggingDateStamp;
 | 
			
		||||
 | 
			
		||||
// internal; called by fetcher
 | 
			
		||||
- (void)logFetchWithError:(NSError *)error;
 | 
			
		||||
- (BOOL)logCapturePostStream;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1042
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherLogging.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										118
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,118 @@
 | 
			
		||||
/* Copyright (c) 2010 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTMHTTPFetcherService.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// The fetcher service class maintains a history to be used by a sequence
 | 
			
		||||
// of fetchers objects generated by the service.
 | 
			
		||||
//
 | 
			
		||||
// Fetchers that do not need to share a history may be generated independently,
 | 
			
		||||
// like
 | 
			
		||||
//
 | 
			
		||||
//   GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
 | 
			
		||||
//
 | 
			
		||||
// Fetchers that should share cookies or an ETagged data cache should be
 | 
			
		||||
// generated by a common GTMHTTPFetcherService instance, like
 | 
			
		||||
//
 | 
			
		||||
//   GTMHTTPFetcherService *myFetcherService = [[GTMHTTPFetcherService alloc] init];
 | 
			
		||||
//   GTMHTTPFetcher* myFirstFetcher = [myFetcherService fetcherWithRequest:request1];
 | 
			
		||||
//   GTMHTTPFetcher* mySecondFetcher = [myFetcherService fetcherWithRequest:request2];
 | 
			
		||||
 | 
			
		||||
#import "GTMHTTPFetcher.h"
 | 
			
		||||
#import "GTMHTTPFetchHistory.h"
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetcherService : NSObject<GTMHTTPFetcherServiceProtocol> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSMutableDictionary *delayedHosts_;
 | 
			
		||||
  NSMutableDictionary *runningHosts_;
 | 
			
		||||
  NSUInteger maxRunningFetchersPerHost_;
 | 
			
		||||
 | 
			
		||||
  GTMHTTPFetchHistory *fetchHistory_;
 | 
			
		||||
  NSArray *runLoopModes_;
 | 
			
		||||
  NSString *userAgent_;
 | 
			
		||||
  NSTimeInterval timeout_;
 | 
			
		||||
  NSURLCredential *credential_;       // username & password
 | 
			
		||||
  NSURLCredential *proxyCredential_;  // credential supplied to proxy servers
 | 
			
		||||
  NSInteger cookieStorageMethod_;
 | 
			
		||||
 | 
			
		||||
  BOOL shouldFetchInBackground_;
 | 
			
		||||
 | 
			
		||||
  id <GTMFetcherAuthorizationProtocol> authorizer_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create a fetcher
 | 
			
		||||
//
 | 
			
		||||
// These methods will return an autoreleased fetcher, but if
 | 
			
		||||
// the fetcher is successfully created, the connection will retain the
 | 
			
		||||
// fetcher for the life of the connection as well. So the caller doesn't have
 | 
			
		||||
// to retain the fetcher explicitly unless they want to be able to monitor
 | 
			
		||||
// or cancel it.
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL;
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString;
 | 
			
		||||
- (id)fetcherWithRequest:(NSURLRequest *)request
 | 
			
		||||
            fetcherClass:(Class)fetcherClass;
 | 
			
		||||
 | 
			
		||||
// Queues of delayed and running fetchers. Each dictionary contains arrays
 | 
			
		||||
// of fetchers, keyed by host
 | 
			
		||||
//
 | 
			
		||||
// A max value of 0 means no fetchers should be delayed.
 | 
			
		||||
//
 | 
			
		||||
// The default limit is 10 simultaneous fetchers targeting each host.
 | 
			
		||||
@property (assign) NSUInteger maxRunningFetchersPerHost;
 | 
			
		||||
@property (retain, readonly) NSDictionary *delayedHosts;
 | 
			
		||||
@property (retain, readonly) NSDictionary *runningHosts;
 | 
			
		||||
 | 
			
		||||
- (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher;
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)numberOfFetchers;        // running + delayed fetchers
 | 
			
		||||
- (NSUInteger)numberOfRunningFetchers;
 | 
			
		||||
- (NSUInteger)numberOfDelayedFetchers;
 | 
			
		||||
 | 
			
		||||
- (void)stopAllFetchers;
 | 
			
		||||
 | 
			
		||||
// Properties to be applied to each fetcher;
 | 
			
		||||
// see GTMHTTPFetcher.h for descriptions
 | 
			
		||||
@property (copy) NSString *userAgent;
 | 
			
		||||
@property (assign) NSTimeInterval timeout;
 | 
			
		||||
@property (retain) NSArray *runLoopModes;
 | 
			
		||||
@property (retain) NSURLCredential *credential;
 | 
			
		||||
@property (retain) NSURLCredential *proxyCredential;
 | 
			
		||||
@property (assign) BOOL shouldFetchInBackground;
 | 
			
		||||
 | 
			
		||||
// Fetch history
 | 
			
		||||
@property (retain) GTMHTTPFetchHistory *fetchHistory;
 | 
			
		||||
 | 
			
		||||
@property (assign) NSInteger cookieStorageMethod;
 | 
			
		||||
@property (assign) BOOL shouldRememberETags;      // default: NO
 | 
			
		||||
@property (assign) BOOL shouldCacheETaggedData;   // default: NO
 | 
			
		||||
 | 
			
		||||
- (void)clearETaggedDataCache;
 | 
			
		||||
- (void)clearHistory;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) id <GTMFetcherAuthorizationProtocol> authorizer;
 | 
			
		||||
 | 
			
		||||
// Spin the run loop, discarding events, until all running and delayed fetchers
 | 
			
		||||
// have completed
 | 
			
		||||
//
 | 
			
		||||
// This is only for use in testing or in tools without a user interface.
 | 
			
		||||
//
 | 
			
		||||
// Synchronous fetches should never be done by shipping apps; they are
 | 
			
		||||
// sufficient reason for rejection from the app store.
 | 
			
		||||
- (void)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										441
									
								
								External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,441 @@
 | 
			
		||||
/* Copyright (c) 2010 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  GTMHTTPFetcherService.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTMHTTPFetcherService.h"
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetcher (ServiceMethods)
 | 
			
		||||
- (BOOL)beginFetchMayDelay:(BOOL)mayDelay
 | 
			
		||||
              mayAuthorize:(BOOL)mayAuthorize;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTMHTTPFetcherService ()
 | 
			
		||||
@property (retain, readwrite) NSDictionary *delayedHosts;
 | 
			
		||||
@property (retain, readwrite) NSDictionary *runningHosts;
 | 
			
		||||
 | 
			
		||||
- (void)detachAuthorizer;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTMHTTPFetcherService
 | 
			
		||||
 | 
			
		||||
@synthesize maxRunningFetchersPerHost = maxRunningFetchersPerHost_,
 | 
			
		||||
            userAgent = userAgent_,
 | 
			
		||||
            timeout = timeout_,
 | 
			
		||||
            runLoopModes = runLoopModes_,
 | 
			
		||||
            credential = credential_,
 | 
			
		||||
            proxyCredential = proxyCredential_,
 | 
			
		||||
            cookieStorageMethod = cookieStorageMethod_,
 | 
			
		||||
            shouldFetchInBackground = shouldFetchInBackground_,
 | 
			
		||||
            fetchHistory = fetchHistory_;
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    fetchHistory_ = [[GTMHTTPFetchHistory alloc] init];
 | 
			
		||||
    delayedHosts_ = [[NSMutableDictionary alloc] init];
 | 
			
		||||
    runningHosts_ = [[NSMutableDictionary alloc] init];
 | 
			
		||||
    cookieStorageMethod_ = kGTMHTTPFetcherCookieStorageMethodFetchHistory;
 | 
			
		||||
 | 
			
		||||
    maxRunningFetchersPerHost_ = 10;
 | 
			
		||||
}
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [self detachAuthorizer];
 | 
			
		||||
 | 
			
		||||
  [delayedHosts_ release];
 | 
			
		||||
  [runningHosts_ release];
 | 
			
		||||
  [fetchHistory_ release];
 | 
			
		||||
  [userAgent_ release];
 | 
			
		||||
  [runLoopModes_ release];
 | 
			
		||||
  [credential_ release];
 | 
			
		||||
  [proxyCredential_ release];
 | 
			
		||||
  [authorizer_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Generate a new fetcher
 | 
			
		||||
 | 
			
		||||
- (id)fetcherWithRequest:(NSURLRequest *)request
 | 
			
		||||
            fetcherClass:(Class)fetcherClass {
 | 
			
		||||
  GTMHTTPFetcher *fetcher = [fetcherClass fetcherWithRequest:request];
 | 
			
		||||
 | 
			
		||||
  fetcher.fetchHistory = self.fetchHistory;
 | 
			
		||||
  fetcher.runLoopModes = self.runLoopModes;
 | 
			
		||||
  fetcher.cookieStorageMethod = self.cookieStorageMethod;
 | 
			
		||||
  fetcher.credential = self.credential;
 | 
			
		||||
  fetcher.proxyCredential = self.proxyCredential;
 | 
			
		||||
  fetcher.shouldFetchInBackground = self.shouldFetchInBackground;
 | 
			
		||||
  fetcher.authorizer = self.authorizer;
 | 
			
		||||
  fetcher.service = self;
 | 
			
		||||
 | 
			
		||||
  NSString *userAgent = self.userAgent;
 | 
			
		||||
  if ([userAgent length] > 0
 | 
			
		||||
      && [request valueForHTTPHeaderField:@"User-Agent"] == nil) {
 | 
			
		||||
    [fetcher.mutableRequest setValue:userAgent
 | 
			
		||||
                  forHTTPHeaderField:@"User-Agent"];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSTimeInterval timeout = self.timeout;
 | 
			
		||||
  if (timeout > 0.0) {
 | 
			
		||||
    [fetcher.mutableRequest setTimeoutInterval:timeout];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return fetcher;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request {
 | 
			
		||||
  return [self fetcherWithRequest:request
 | 
			
		||||
                     fetcherClass:[GTMHTTPFetcher class]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL {
 | 
			
		||||
  return [self fetcherWithRequest:[NSURLRequest requestWithURL:requestURL]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString {
 | 
			
		||||
  return [self fetcherWithURL:[NSURL URLWithString:requestURLString]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Queue Management
 | 
			
		||||
 | 
			
		||||
- (void)addRunningFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
                  forHost:(NSString *)host {
 | 
			
		||||
  // Add to the array of running fetchers for this host, creating the array
 | 
			
		||||
  // if needed
 | 
			
		||||
  NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
 | 
			
		||||
  if (runningForHost == nil) {
 | 
			
		||||
    runningForHost = [NSMutableArray arrayWithObject:fetcher];
 | 
			
		||||
    [runningHosts_ setObject:runningForHost forKey:host];
 | 
			
		||||
  } else {
 | 
			
		||||
    [runningForHost addObject:fetcher];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)addDelayedFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
                  forHost:(NSString *)host {
 | 
			
		||||
  // Add to the array of delayed fetchers for this host, creating the array
 | 
			
		||||
  // if needed
 | 
			
		||||
  NSMutableArray *delayedForHost = [delayedHosts_ objectForKey:host];
 | 
			
		||||
  if (delayedForHost == nil) {
 | 
			
		||||
    delayedForHost = [NSMutableArray arrayWithObject:fetcher];
 | 
			
		||||
    [delayedHosts_ setObject:delayedForHost forKey:host];
 | 
			
		||||
  } else {
 | 
			
		||||
    [delayedForHost addObject:fetcher];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (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);
 | 
			
		||||
  }
 | 
			
		||||
  return isDelayed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher {
 | 
			
		||||
  // Entry point from the fetcher
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    NSString *host = [[[fetcher mutableRequest] URL] host];
 | 
			
		||||
 | 
			
		||||
    if ([host length] == 0) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
      NSAssert1(0, @"%@ lacks host", fetcher);
 | 
			
		||||
#endif
 | 
			
		||||
      return YES;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
 | 
			
		||||
    if (runningForHost != nil
 | 
			
		||||
        && [runningForHost indexOfObjectIdenticalTo:fetcher] != NSNotFound) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
      NSAssert1(0, @"%@ was already running", fetcher);
 | 
			
		||||
#endif
 | 
			
		||||
      return YES;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We'll save the host that serves as the key for this fetcher's array
 | 
			
		||||
    // to avoid any chance of the underlying request changing, stranding
 | 
			
		||||
    // the fetcher in the wrong array
 | 
			
		||||
    fetcher.serviceHost = host;
 | 
			
		||||
    fetcher.thread = [NSThread currentThread];
 | 
			
		||||
 | 
			
		||||
    if (maxRunningFetchersPerHost_ == 0
 | 
			
		||||
        || maxRunningFetchersPerHost_ > [runningForHost count]) {
 | 
			
		||||
      [self addRunningFetcher:fetcher forHost:host];
 | 
			
		||||
      return YES;
 | 
			
		||||
    } else {
 | 
			
		||||
      [self addDelayedFetcher:fetcher forHost:host];
 | 
			
		||||
      return NO;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fetcher start and stop methods, invoked on the appropriate thread for
 | 
			
		||||
// the fetcher
 | 
			
		||||
- (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];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)stopFetcherOnCurrentThread:(GTMHTTPFetcher *)fetcher {
 | 
			
		||||
  [fetcher stopFetching];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (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];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher {
 | 
			
		||||
  // Entry point from the fetcher
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    NSString *host = fetcher.serviceHost;
 | 
			
		||||
    if (!host) {
 | 
			
		||||
      // fetcher has been stopped previously
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
 | 
			
		||||
    [runningForHost removeObject:fetcher];
 | 
			
		||||
 | 
			
		||||
    NSMutableArray *delayedForHost = [delayedHosts_ objectForKey:host];
 | 
			
		||||
    [delayedForHost removeObject:fetcher];
 | 
			
		||||
 | 
			
		||||
    while ([delayedForHost count] > 0
 | 
			
		||||
           && [runningForHost count] < maxRunningFetchersPerHost_) {
 | 
			
		||||
      // Start another delayed fetcher running, scanning for the minimum
 | 
			
		||||
      // priority value, defaulting to FIFO for equal priorities
 | 
			
		||||
      GTMHTTPFetcher *nextFetcher = nil;
 | 
			
		||||
      for (GTMHTTPFetcher *delayedFetcher in delayedForHost) {
 | 
			
		||||
        if (nextFetcher == nil
 | 
			
		||||
            || delayedFetcher.servicePriority < nextFetcher.servicePriority) {
 | 
			
		||||
          nextFetcher = delayedFetcher;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [self addRunningFetcher:nextFetcher forHost:host];
 | 
			
		||||
      runningForHost = [runningHosts_ objectForKey:host];
 | 
			
		||||
 | 
			
		||||
      [delayedForHost removeObjectIdenticalTo:nextFetcher];
 | 
			
		||||
      [self startFetcher:nextFetcher];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ([runningForHost count] == 0) {
 | 
			
		||||
      // None left; remove the empty array
 | 
			
		||||
      [runningHosts_ removeObjectForKey:host];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ([delayedForHost count] == 0) {
 | 
			
		||||
      [delayedHosts_ removeObjectForKey:host];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The fetcher is no longer in the running or the delayed array,
 | 
			
		||||
    // so remove its host and thread properties
 | 
			
		||||
    fetcher.serviceHost = nil;
 | 
			
		||||
    fetcher.thread = nil;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)numberOfFetchers {
 | 
			
		||||
  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];
 | 
			
		||||
  }
 | 
			
		||||
  return sum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)numberOfDelayedFetchers {
 | 
			
		||||
  NSUInteger sum = 0;
 | 
			
		||||
  for (NSString *host in delayedHosts_) {
 | 
			
		||||
    NSArray *fetchers = [delayedHosts_ objectForKey:host];
 | 
			
		||||
    sum += [fetchers count];
 | 
			
		||||
  }
 | 
			
		||||
  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];
 | 
			
		||||
 | 
			
		||||
  for (NSArray *delayedForHost in delayedForHosts) {
 | 
			
		||||
    for (GTMHTTPFetcher *fetcher in delayedForHost) {
 | 
			
		||||
      [self stopFetcher:fetcher];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSArray *runningForHosts = [runningHosts_ allValues];
 | 
			
		||||
  [runningHosts_ removeAllObjects];
 | 
			
		||||
 | 
			
		||||
  for (NSArray *runningForHost in runningForHosts) {
 | 
			
		||||
    for (GTMHTTPFetcher *fetcher in runningForHost) {
 | 
			
		||||
      [self stopFetcher:fetcher];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Fetch History Settings
 | 
			
		||||
 | 
			
		||||
// Turn on data caching to receive a copy of previously-retrieved objects.
 | 
			
		||||
// Otherwise, fetches may return status 304 (No Change) rather than actual data
 | 
			
		||||
- (void)setShouldCacheETaggedData:(BOOL)flag {
 | 
			
		||||
  self.fetchHistory.shouldCacheETaggedData = flag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldCacheETaggedData {
 | 
			
		||||
  return self.fetchHistory.shouldCacheETaggedData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setETaggedDataCacheCapacity:(NSUInteger)totalBytes {
 | 
			
		||||
  self.fetchHistory.memoryCapacity = totalBytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSUInteger)ETaggedDataCacheCapacity {
 | 
			
		||||
  return self.fetchHistory.memoryCapacity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setShouldRememberETags:(BOOL)flag {
 | 
			
		||||
  self.fetchHistory.shouldRememberETags = flag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldRememberETags {
 | 
			
		||||
  return self.fetchHistory.shouldRememberETags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reset the ETag cache to avoid getting a Not Modified status
 | 
			
		||||
// based on prior queries
 | 
			
		||||
- (void)clearETaggedDataCache {
 | 
			
		||||
  [self.fetchHistory clearETaggedDataCache];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearHistory {
 | 
			
		||||
  [self clearETaggedDataCache];
 | 
			
		||||
  [self.fetchHistory removeAllCookies];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Synchronous Wait for Unit Testing
 | 
			
		||||
 | 
			
		||||
- (void)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds {
 | 
			
		||||
  NSDate* giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds];
 | 
			
		||||
 | 
			
		||||
  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];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Accessors
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)runningHosts {
 | 
			
		||||
  return runningHosts_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setRunningHosts:(NSDictionary *)dict {
 | 
			
		||||
  [runningHosts_ autorelease];
 | 
			
		||||
  runningHosts_ = [dict mutableCopy];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)delayedHosts {
 | 
			
		||||
  return delayedHosts_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setDelayedHosts:(NSDictionary *)dict {
 | 
			
		||||
  [delayedHosts_ autorelease];
 | 
			
		||||
  delayedHosts_ = [dict mutableCopy];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id <GTMFetcherAuthorizationProtocol>)authorizer {
 | 
			
		||||
  return authorizer_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAuthorizer:(id <GTMFetcherAuthorizationProtocol>)obj {
 | 
			
		||||
  if (obj != authorizer_) {
 | 
			
		||||
    [self detachAuthorizer];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [authorizer_ autorelease];
 | 
			
		||||
  authorizer_ = [obj retain];
 | 
			
		||||
 | 
			
		||||
  // Use the fetcher service for the authorization fetches if the auth
 | 
			
		||||
  // object supports fetcher services
 | 
			
		||||
  if ([authorizer_ respondsToSelector:@selector(setFetcherService:)]) {
 | 
			
		||||
    [authorizer_ setFetcherService:self];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)detachAuthorizer {
 | 
			
		||||
  // This method is called by the fetcher service's dealloc and setAuthorizer:
 | 
			
		||||
  // methods; do not override.
 | 
			
		||||
  //
 | 
			
		||||
  // The fetcher service retains the authorizer, and the authorizer has a
 | 
			
		||||
  // weak pointer to the fetcher service (a non-zeroing pointer for
 | 
			
		||||
  // compatibility with iOS 4 and Mac OS X 10.5/10.6.)
 | 
			
		||||
  //
 | 
			
		||||
  // When this fetcher service no longer uses the authorizer, we want to remove
 | 
			
		||||
  // the authorizer's dependence on the fetcher service.  Authorizers can still
 | 
			
		||||
  // function without a fetcher service.
 | 
			
		||||
  if ([authorizer_ respondsToSelector:@selector(fetcherService)]) {
 | 
			
		||||
    GTMHTTPFetcherService *authFS = [authorizer_ fetcherService];
 | 
			
		||||
    if (authFS == self) {
 | 
			
		||||
      [authorizer_ setFetcherService:nil];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										504
									
								
								External/google-plus-ios-sdk/OpenSource/GTMLogger.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,504 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMLogger.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Key Abstractions
 | 
			
		||||
// ----------------
 | 
			
		||||
//
 | 
			
		||||
// This file declares multiple classes and protocols that are used by the
 | 
			
		||||
// GTMLogger logging system. The 4 main abstractions used in this file are the
 | 
			
		||||
// following:
 | 
			
		||||
//
 | 
			
		||||
//   * logger (GTMLogger) - The main logging class that users interact with. It
 | 
			
		||||
//   has methods for logging at different levels and uses a log writer, a log
 | 
			
		||||
//   formatter, and a log filter to get the job done.
 | 
			
		||||
//
 | 
			
		||||
//   * log writer (GTMLogWriter) - Writes a given string to some log file, where
 | 
			
		||||
//   a "log file" can be a physical file on disk, a POST over HTTP to some URL,
 | 
			
		||||
//   or even some in-memory structure (e.g., a ring buffer).
 | 
			
		||||
//
 | 
			
		||||
//   * log formatter (GTMLogFormatter) - Given a format string and arguments as
 | 
			
		||||
//   a va_list, returns a single formatted NSString. A "formatted string" could
 | 
			
		||||
//   be a string with the date prepended, a string with values in a CSV format,
 | 
			
		||||
//   or even a string of XML.
 | 
			
		||||
//
 | 
			
		||||
//   * log filter (GTMLogFilter) - Given a formatted log message as an NSString
 | 
			
		||||
//   and the level at which the message is to be logged, this class will decide
 | 
			
		||||
//   whether the given message should be logged or not. This is a flexible way
 | 
			
		||||
//   to filter out messages logged at a certain level, messages that contain
 | 
			
		||||
//   certain text, or filter nothing out at all. This gives the caller the
 | 
			
		||||
//   flexibility to dynamically enable debug logging in Release builds.
 | 
			
		||||
//
 | 
			
		||||
// This file also declares some classes to handle the common log writer, log
 | 
			
		||||
// formatter, and log filter cases. Callers can also create their own writers,
 | 
			
		||||
// formatters, and filters and they can even build them on top of the ones
 | 
			
		||||
// declared here. Keep in mind that your custom writer/formatter/filter may be
 | 
			
		||||
// called from multiple threads, so it must be thread-safe.
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "GTMDefines.h"
 | 
			
		||||
 | 
			
		||||
// Predeclaration of used protocols that are declared later in this file.
 | 
			
		||||
@protocol GTMLogWriter, GTMLogFormatter, GTMLogFilter;
 | 
			
		||||
 | 
			
		||||
// GTMLogger
 | 
			
		||||
//
 | 
			
		||||
// GTMLogger is the primary user-facing class for an object-oriented logging
 | 
			
		||||
// system. It is built on the concept of log formatters (GTMLogFormatter), log
 | 
			
		||||
// writers (GTMLogWriter), and log filters (GTMLogFilter). When a message is
 | 
			
		||||
// sent to a GTMLogger to log a message, the message is formatted using the log
 | 
			
		||||
// formatter, then the log filter is consulted to see if the message should be
 | 
			
		||||
// logged, and if so, the message is sent to the log writer to be written out.
 | 
			
		||||
//
 | 
			
		||||
// GTMLogger is intended to be a flexible and thread-safe logging solution. Its
 | 
			
		||||
// flexibility comes from the fact that GTMLogger instances can be customized
 | 
			
		||||
// with user defined formatters, filters, and writers. And these writers,
 | 
			
		||||
// filters, and formatters can be combined, stacked, and customized in arbitrary
 | 
			
		||||
// ways to suit the needs at hand. For example, multiple writers can be used at
 | 
			
		||||
// the same time, and a GTMLogger instance can even be used as another
 | 
			
		||||
// GTMLogger's writer. This allows for arbitrarily deep logging trees.
 | 
			
		||||
//
 | 
			
		||||
// A standard GTMLogger uses a writer that sends messages to standard out, a
 | 
			
		||||
// formatter that smacks a timestamp and a few other bits of interesting
 | 
			
		||||
// information on the message, and a filter that filters out debug messages from
 | 
			
		||||
// release builds. Using the standard log settings, a log message will look like
 | 
			
		||||
// the following:
 | 
			
		||||
//
 | 
			
		||||
//   2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] foo=<Foo: 0x123>
 | 
			
		||||
//
 | 
			
		||||
// The output contains the date and time of the log message, the name of the
 | 
			
		||||
// process followed by its process ID/thread ID, the log level at which the
 | 
			
		||||
// message was logged (in the previous example the level was 1:
 | 
			
		||||
// kGTMLoggerLevelDebug), and finally, the user-specified log message itself (in
 | 
			
		||||
// this case, the log message was @"foo=%@", foo).
 | 
			
		||||
//
 | 
			
		||||
// Multiple instances of GTMLogger can be created, each configured their own
 | 
			
		||||
// way.  Though GTMLogger is not a singleton (in the GoF sense), it does provide
 | 
			
		||||
// access to a shared (i.e., globally accessible) GTMLogger instance. This makes
 | 
			
		||||
// it convenient for all code in a process to use the same GTMLogger instance.
 | 
			
		||||
// The shared GTMLogger instance can also be configured in an arbitrary, and
 | 
			
		||||
// these configuration changes will affect all code that logs through the shared
 | 
			
		||||
// instance.
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Log Levels
 | 
			
		||||
// ----------
 | 
			
		||||
// GTMLogger has 3 different log levels: Debug, Info, and Error. GTMLogger
 | 
			
		||||
// doesn't take any special action based on the log level; it simply forwards
 | 
			
		||||
// this information on to formatters, filters, and writers, each of which may
 | 
			
		||||
// optionally take action based on the level. Since log level filtering is
 | 
			
		||||
// performed at runtime, log messages are typically not filtered out at compile
 | 
			
		||||
// time.  The exception to this rule is that calls to the GTMLoggerDebug() macro
 | 
			
		||||
// *ARE* filtered out of non-DEBUG builds. This is to be backwards compatible
 | 
			
		||||
// with behavior that many developers are currently used to. Note that this
 | 
			
		||||
// means that GTMLoggerDebug(@"hi") will be compiled out of Release builds, but
 | 
			
		||||
// [[GTMLogger sharedLogger] logDebug:@"hi"] will NOT be compiled out.
 | 
			
		||||
//
 | 
			
		||||
// Standard loggers are created with the GTMLogLevelFilter log filter, which
 | 
			
		||||
// filters out certain log messages based on log level, and some other settings.
 | 
			
		||||
//
 | 
			
		||||
// In addition to the -logDebug:, -logInfo:, and -logError: methods defined on
 | 
			
		||||
// GTMLogger itself, there are also C macros that make usage of the shared
 | 
			
		||||
// GTMLogger instance very convenient. These macros are:
 | 
			
		||||
//
 | 
			
		||||
//   GTMLoggerDebug(...)
 | 
			
		||||
//   GTMLoggerInfo(...)
 | 
			
		||||
//   GTMLoggerError(...)
 | 
			
		||||
//
 | 
			
		||||
// Again, a notable feature of these macros is that GTMLogDebug() calls *will be
 | 
			
		||||
// compiled out of non-DEBUG builds*.
 | 
			
		||||
//
 | 
			
		||||
// Standard Loggers
 | 
			
		||||
// ----------------
 | 
			
		||||
// GTMLogger has the concept of "standard loggers". A standard logger is simply
 | 
			
		||||
// a logger that is pre-configured with some standard/common writer, formatter,
 | 
			
		||||
// and filter combination. Standard loggers are created using the creation
 | 
			
		||||
// methods beginning with "standard". The alternative to a standard logger is a
 | 
			
		||||
// regular logger, which will send messages to stdout, with no special
 | 
			
		||||
// formatting, and no filtering.
 | 
			
		||||
//
 | 
			
		||||
// How do I use GTMLogger?
 | 
			
		||||
// ----------------------
 | 
			
		||||
// The typical way you will want to use GTMLogger is to simply use the
 | 
			
		||||
// GTMLogger*() macros for logging from code. That way we can easily make
 | 
			
		||||
// changes to the GTMLogger class and simply update the macros accordingly. Only
 | 
			
		||||
// your application startup code (perhaps, somewhere in main()) should use the
 | 
			
		||||
// GTMLogger class directly in order to configure the shared logger, which all
 | 
			
		||||
// of the code using the macros will be using. Again, this is just the typical
 | 
			
		||||
// situation.
 | 
			
		||||
//
 | 
			
		||||
// To be complete, there are cases where you may want to use GTMLogger directly,
 | 
			
		||||
// or even create separate GTMLogger instances for some reason. That's fine,
 | 
			
		||||
// too.
 | 
			
		||||
//
 | 
			
		||||
// Examples
 | 
			
		||||
// --------
 | 
			
		||||
// The following show some common GTMLogger use cases.
 | 
			
		||||
//
 | 
			
		||||
// 1. You want to log something as simply as possible. Also, this call will only
 | 
			
		||||
//    appear in debug builds. In non-DEBUG builds it will be completely removed.
 | 
			
		||||
//
 | 
			
		||||
//      GTMLoggerDebug(@"foo = %@", foo);
 | 
			
		||||
//
 | 
			
		||||
// 2. The previous example is similar to the following. The major difference is
 | 
			
		||||
//    that the previous call (example 1) will be compiled out of Release builds
 | 
			
		||||
//    but this statement will not be compiled out.
 | 
			
		||||
//
 | 
			
		||||
//      [[GTMLogger sharedLogger] logDebug:@"foo = %@", foo];
 | 
			
		||||
//
 | 
			
		||||
// 3. Send all logging output from the shared logger to a file. We do this by
 | 
			
		||||
//    creating an NSFileHandle for writing associated with a file, and setting
 | 
			
		||||
//    that file handle as the logger's writer.
 | 
			
		||||
//
 | 
			
		||||
//      NSFileHandle *f = [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log"
 | 
			
		||||
//                                                          create:YES];
 | 
			
		||||
//      [[GTMLogger sharedLogger] setWriter:f];
 | 
			
		||||
//      GTMLoggerError(@"hi");  // This will be sent to /tmp/f.log
 | 
			
		||||
//
 | 
			
		||||
// 4. Create a new GTMLogger that will log to a file. This example differs from
 | 
			
		||||
//    the previous one because here we create a new GTMLogger that is different
 | 
			
		||||
//    from the shared logger.
 | 
			
		||||
//
 | 
			
		||||
//      GTMLogger *logger = [GTMLogger standardLoggerWithPath:@"/tmp/temp.log"];
 | 
			
		||||
//      [logger logInfo:@"hi temp log file"];
 | 
			
		||||
//
 | 
			
		||||
// 5. Create a logger that writes to stdout and does NOT do any formatting to
 | 
			
		||||
//    the log message. This might be useful, for example, when writing a help
 | 
			
		||||
//    screen for a command-line tool to standard output.
 | 
			
		||||
//
 | 
			
		||||
//      GTMLogger *logger = [GTMLogger logger];
 | 
			
		||||
//      [logger logInfo:@"%@ version 0.1 usage", progName];
 | 
			
		||||
//
 | 
			
		||||
// 6. Send log output to stdout AND to a log file. The trick here is that
 | 
			
		||||
//    NSArrays function as composite log writers, which means when an array is
 | 
			
		||||
//    set as the log writer, it forwards all logging messages to all of its
 | 
			
		||||
//    contained GTMLogWriters.
 | 
			
		||||
//
 | 
			
		||||
//      // Create array of GTMLogWriters
 | 
			
		||||
//      NSArray *writers = [NSArray arrayWithObjects:
 | 
			
		||||
//          [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log" create:YES],
 | 
			
		||||
//          [NSFileHandle fileHandleWithStandardOutput], nil];
 | 
			
		||||
//
 | 
			
		||||
//      GTMLogger *logger = [GTMLogger standardLogger];
 | 
			
		||||
//      [logger setWriter:writers];
 | 
			
		||||
//      [logger logInfo:@"hi"];  // Output goes to stdout and /tmp/f.log
 | 
			
		||||
//
 | 
			
		||||
// For futher details on log writers, formatters, and filters, see the
 | 
			
		||||
// documentation below.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: GTMLogger is application level logging.  By default it does nothing
 | 
			
		||||
// with _GTMDevLog/_GTMDevAssert (see GTMDefines.h).  An application can choose
 | 
			
		||||
// to bridge _GTMDevLog/_GTMDevAssert to GTMLogger by providing macro
 | 
			
		||||
// definitions in its prefix header (see GTMDefines.h for how one would do
 | 
			
		||||
// that).
 | 
			
		||||
//
 | 
			
		||||
@interface GTMLogger : NSObject {
 | 
			
		||||
 @private
 | 
			
		||||
  id<GTMLogWriter> writer_;
 | 
			
		||||
  id<GTMLogFormatter> formatter_;
 | 
			
		||||
  id<GTMLogFilter> filter_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Accessors for the shared logger instance
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Returns a shared/global standard GTMLogger instance. Callers should typically
 | 
			
		||||
// use this method to get a GTMLogger instance, unless they explicitly want
 | 
			
		||||
// their own instance to configure for their own needs. This is the only method
 | 
			
		||||
// that returns a shared instance; all the rest return new GTMLogger instances.
 | 
			
		||||
+ (id)sharedLogger;
 | 
			
		||||
 | 
			
		||||
// Sets the shared logger instance to |logger|. Future calls to +sharedLogger
 | 
			
		||||
// will return |logger| instead.
 | 
			
		||||
+ (void)setSharedLogger:(GTMLogger *)logger;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Creation methods
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Returns a new autoreleased GTMLogger instance that will log to stdout, using
 | 
			
		||||
// the GTMLogStandardFormatter, and the GTMLogLevelFilter filter.
 | 
			
		||||
+ (id)standardLogger;
 | 
			
		||||
 | 
			
		||||
// Same as +standardLogger, but logs to stderr.
 | 
			
		||||
+ (id)standardLoggerWithStderr;
 | 
			
		||||
 | 
			
		||||
// Same as +standardLogger but levels >= kGTMLoggerLevelError are routed to
 | 
			
		||||
// stderr, everything else goes to stdout.
 | 
			
		||||
+ (id)standardLoggerWithStdoutAndStderr;
 | 
			
		||||
 | 
			
		||||
// Returns a new standard GTMLogger instance with a log writer that will
 | 
			
		||||
// write to the file at |path|, and will use the GTMLogStandardFormatter and
 | 
			
		||||
// GTMLogLevelFilter classes. If |path| does not exist, it will be created.
 | 
			
		||||
+ (id)standardLoggerWithPath:(NSString *)path;
 | 
			
		||||
 | 
			
		||||
// Returns an autoreleased GTMLogger instance that will use the specified
 | 
			
		||||
// |writer|, |formatter|, and |filter|.
 | 
			
		||||
+ (id)loggerWithWriter:(id<GTMLogWriter>)writer
 | 
			
		||||
             formatter:(id<GTMLogFormatter>)formatter
 | 
			
		||||
                filter:(id<GTMLogFilter>)filter;
 | 
			
		||||
 | 
			
		||||
// Returns an autoreleased GTMLogger instance that logs to stdout, with the
 | 
			
		||||
// basic formatter, and no filter. The returned logger differs from the logger
 | 
			
		||||
// returned by +standardLogger because this one does not do any filtering and
 | 
			
		||||
// does not do any special log formatting; this is the difference between a
 | 
			
		||||
// "regular" logger and a "standard" logger.
 | 
			
		||||
+ (id)logger;
 | 
			
		||||
 | 
			
		||||
// Designated initializer. This method returns a GTMLogger initialized with the
 | 
			
		||||
// specified |writer|, |formatter|, and |filter|. See the setter methods below
 | 
			
		||||
// for what values will be used if nil is passed for a parameter.
 | 
			
		||||
- (id)initWithWriter:(id<GTMLogWriter>)writer
 | 
			
		||||
           formatter:(id<GTMLogFormatter>)formatter
 | 
			
		||||
              filter:(id<GTMLogFilter>)filter;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Logging  methods
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Logs a message at the debug level (kGTMLoggerLevelDebug).
 | 
			
		||||
- (void)logDebug:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
 | 
			
		||||
// Logs a message at the info level (kGTMLoggerLevelInfo).
 | 
			
		||||
- (void)logInfo:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
 | 
			
		||||
// Logs a message at the error level (kGTMLoggerLevelError).
 | 
			
		||||
- (void)logError:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
 | 
			
		||||
// Logs a message at the assert level (kGTMLoggerLevelAssert).
 | 
			
		||||
- (void)logAssert:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Accessors
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Accessor methods for the log writer. If the log writer is set to nil,
 | 
			
		||||
// [NSFileHandle fileHandleWithStandardOutput] is used.
 | 
			
		||||
- (id<GTMLogWriter>)writer;
 | 
			
		||||
- (void)setWriter:(id<GTMLogWriter>)writer;
 | 
			
		||||
 | 
			
		||||
// Accessor methods for the log formatter. If the log formatter is set to nil,
 | 
			
		||||
// GTMLogBasicFormatter is used. This formatter will format log messages in a
 | 
			
		||||
// plain printf style.
 | 
			
		||||
- (id<GTMLogFormatter>)formatter;
 | 
			
		||||
- (void)setFormatter:(id<GTMLogFormatter>)formatter;
 | 
			
		||||
 | 
			
		||||
// Accessor methods for the log filter. If the log filter is set to nil,
 | 
			
		||||
// GTMLogNoFilter is used, which allows all log messages through.
 | 
			
		||||
- (id<GTMLogFilter>)filter;
 | 
			
		||||
- (void)setFilter:(id<GTMLogFilter>)filter;
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogger
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Helper functions that are used by the convenience GTMLogger*() macros that
 | 
			
		||||
// enable the logging of function names.
 | 
			
		||||
@interface GTMLogger (GTMLoggerMacroHelpers)
 | 
			
		||||
- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ...
 | 
			
		||||
  NS_FORMAT_FUNCTION(2, 3);
 | 
			
		||||
- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ...
 | 
			
		||||
  NS_FORMAT_FUNCTION(2, 3);
 | 
			
		||||
- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ...
 | 
			
		||||
  NS_FORMAT_FUNCTION(2, 3);
 | 
			
		||||
- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ...
 | 
			
		||||
  NS_FORMAT_FUNCTION(2, 3);
 | 
			
		||||
@end  // GTMLoggerMacroHelpers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// The convenience macros are only defined if they haven't already been defined.
 | 
			
		||||
#ifndef GTMLoggerInfo
 | 
			
		||||
 | 
			
		||||
// Convenience macros that log to the shared GTMLogger instance. These macros
 | 
			
		||||
// are how users should typically log to GTMLogger. Notice that GTMLoggerDebug()
 | 
			
		||||
// calls will be compiled out of non-Debug builds.
 | 
			
		||||
#define GTMLoggerDebug(...)  \
 | 
			
		||||
  [[GTMLogger sharedLogger] logFuncDebug:__func__ msg:__VA_ARGS__]
 | 
			
		||||
#define GTMLoggerInfo(...)   \
 | 
			
		||||
  [[GTMLogger sharedLogger] logFuncInfo:__func__ msg:__VA_ARGS__]
 | 
			
		||||
#define GTMLoggerError(...)  \
 | 
			
		||||
  [[GTMLogger sharedLogger] logFuncError:__func__ msg:__VA_ARGS__]
 | 
			
		||||
#define GTMLoggerAssert(...) \
 | 
			
		||||
  [[GTMLogger sharedLogger] logFuncAssert:__func__ msg:__VA_ARGS__]
 | 
			
		||||
 | 
			
		||||
// If we're not in a debug build, remove the GTMLoggerDebug statements. This
 | 
			
		||||
// makes calls to GTMLoggerDebug "compile out" of Release builds
 | 
			
		||||
#ifndef DEBUG
 | 
			
		||||
#undef GTMLoggerDebug
 | 
			
		||||
#define GTMLoggerDebug(...) do {} while(0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // !defined(GTMLoggerInfo)
 | 
			
		||||
 | 
			
		||||
// Log levels.
 | 
			
		||||
typedef enum {
 | 
			
		||||
  kGTMLoggerLevelUnknown,
 | 
			
		||||
  kGTMLoggerLevelDebug,
 | 
			
		||||
  kGTMLoggerLevelInfo,
 | 
			
		||||
  kGTMLoggerLevelError,
 | 
			
		||||
  kGTMLoggerLevelAssert,
 | 
			
		||||
} GTMLoggerLevel;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//   Log Writers
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Protocol to be implemented by a GTMLogWriter instance.
 | 
			
		||||
@protocol GTMLogWriter <NSObject>
 | 
			
		||||
// Writes the given log message to where the log writer is configured to write.
 | 
			
		||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level;
 | 
			
		||||
@end  // GTMLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Simple category on NSFileHandle that makes NSFileHandles valid log writers.
 | 
			
		||||
// This is convenient because something like, say, +fileHandleWithStandardError
 | 
			
		||||
// now becomes a valid log writer. Log messages are written to the file handle
 | 
			
		||||
// with a newline appended.
 | 
			
		||||
@interface NSFileHandle (GTMFileHandleLogWriter) <GTMLogWriter>
 | 
			
		||||
// Opens the file at |path| in append mode, and creates the file with |mode|
 | 
			
		||||
// if it didn't previously exist.
 | 
			
		||||
+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode;
 | 
			
		||||
@end  // NSFileHandle
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// This category makes NSArray a GTMLogWriter that can be composed of other
 | 
			
		||||
// GTMLogWriters. This is the classic Composite GoF design pattern. When the
 | 
			
		||||
// GTMLogWriter -logMessage:level: message is sent to the array, the array
 | 
			
		||||
// forwards the message to all of its elements that implement the GTMLogWriter
 | 
			
		||||
// protocol.
 | 
			
		||||
//
 | 
			
		||||
// This is useful in situations where you would like to send log output to
 | 
			
		||||
// multiple log writers at the same time. Simply create an NSArray of the log
 | 
			
		||||
// writers you wish to use, then set the array as the "writer" for your
 | 
			
		||||
// GTMLogger instance.
 | 
			
		||||
@interface NSArray (GTMArrayCompositeLogWriter) <GTMLogWriter>
 | 
			
		||||
@end  // GTMArrayCompositeLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// This category adapts the GTMLogger interface so that it can be used as a log
 | 
			
		||||
// writer; it's an "adapter" in the GoF Adapter pattern sense.
 | 
			
		||||
//
 | 
			
		||||
// This is useful when you want to configure a logger to log to a specific
 | 
			
		||||
// writer with a specific formatter and/or filter. But you want to also compose
 | 
			
		||||
// that with a different log writer that may have its own formatter and/or
 | 
			
		||||
// filter.
 | 
			
		||||
@interface GTMLogger (GTMLoggerLogWriter) <GTMLogWriter>
 | 
			
		||||
@end  // GTMLoggerLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//   Log Formatters
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Protocol to be implemented by a GTMLogFormatter instance.
 | 
			
		||||
@protocol GTMLogFormatter <NSObject>
 | 
			
		||||
// Returns a formatted string using the format specified in |fmt| and the va
 | 
			
		||||
// args specified in |args|.
 | 
			
		||||
- (NSString *)stringForFunc:(NSString *)func
 | 
			
		||||
                 withFormat:(NSString *)fmt
 | 
			
		||||
                     valist:(va_list)args
 | 
			
		||||
                      level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
 | 
			
		||||
@end  // GTMLogFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// A basic log formatter that formats a string the same way that NSLog (or
 | 
			
		||||
// printf) would. It does not do anything fancy, nor does it add any data of its
 | 
			
		||||
// own.
 | 
			
		||||
@interface GTMLogBasicFormatter : NSObject <GTMLogFormatter>
 | 
			
		||||
 | 
			
		||||
// Helper method for prettying C99 __func__ and GCC __PRETTY_FUNCTION__
 | 
			
		||||
- (NSString *)prettyNameForFunc:(NSString *)func;
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogBasicFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// A log formatter that formats the log string like the basic formatter, but
 | 
			
		||||
// also prepends a timestamp and some basic process info to the message, as
 | 
			
		||||
// shown in the following sample output.
 | 
			
		||||
//   2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] log mesage here
 | 
			
		||||
@interface GTMLogStandardFormatter : GTMLogBasicFormatter {
 | 
			
		||||
 @private
 | 
			
		||||
  NSDateFormatter *dateFormatter_;  // yyyy-MM-dd HH:mm:ss.SSS
 | 
			
		||||
  NSString *pname_;
 | 
			
		||||
  pid_t pid_;
 | 
			
		||||
}
 | 
			
		||||
@end  // GTMLogStandardFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//   Log Filters
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Protocol to be imlemented by a GTMLogFilter instance.
 | 
			
		||||
@protocol GTMLogFilter <NSObject>
 | 
			
		||||
// Returns YES if |msg| at |level| should be filtered out; NO otherwise.
 | 
			
		||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level;
 | 
			
		||||
@end  // GTMLogFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// A log filter that filters messages at the kGTMLoggerLevelDebug level out of
 | 
			
		||||
// non-debug builds. Messages at the kGTMLoggerLevelInfo level are also filtered
 | 
			
		||||
// out of non-debug builds unless GTMVerboseLogging is set in the environment or
 | 
			
		||||
// the processes's defaults. Messages at the kGTMLoggerLevelError level are
 | 
			
		||||
// never filtered.
 | 
			
		||||
@interface GTMLogLevelFilter : NSObject <GTMLogFilter>
 | 
			
		||||
@end  // GTMLogLevelFilter
 | 
			
		||||
 | 
			
		||||
// A simple log filter that does NOT filter anything out;
 | 
			
		||||
// -filterAllowsMessage:level will always return YES. This can be a convenient
 | 
			
		||||
// way to enable debug-level logging in release builds (if you so desire).
 | 
			
		||||
@interface GTMLogNoFilter : NSObject <GTMLogFilter>
 | 
			
		||||
@end  // GTMLogNoFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Base class for custom level filters. Not for direct use, use the minimum
 | 
			
		||||
// or maximum level subclasses below.
 | 
			
		||||
@interface GTMLogAllowedLevelFilter : NSObject <GTMLogFilter> {
 | 
			
		||||
 @private
 | 
			
		||||
  NSIndexSet *allowedLevels_;
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// A log filter that allows you to set a minimum log level. Messages below this
 | 
			
		||||
// level will be filtered.
 | 
			
		||||
@interface GTMLogMininumLevelFilter : GTMLogAllowedLevelFilter
 | 
			
		||||
 | 
			
		||||
// Designated initializer, logs at levels < |level| will be filtered.
 | 
			
		||||
- (id)initWithMinimumLevel:(GTMLoggerLevel)level;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// A log filter that allows you to set a maximum log level. Messages whose level
 | 
			
		||||
// exceeds this level will be filtered. This is really only useful if you have
 | 
			
		||||
// a composite GTMLogger that is sending the other messages elsewhere.
 | 
			
		||||
@interface GTMLogMaximumLevelFilter : GTMLogAllowedLevelFilter
 | 
			
		||||
 | 
			
		||||
// Designated initializer, logs at levels > |level| will be filtered.
 | 
			
		||||
- (id)initWithMaximumLevel:(GTMLoggerLevel)level;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// For subclasses only
 | 
			
		||||
@interface GTMLogger (PrivateMethods)
 | 
			
		||||
 | 
			
		||||
- (void)logInternalFunc:(const char *)func
 | 
			
		||||
                 format:(NSString *)fmt
 | 
			
		||||
                 valist:(va_list)args
 | 
			
		||||
                  level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										598
									
								
								External/google-plus-ios-sdk/OpenSource/GTMLogger.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,598 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMLogger.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTMLogger.h"
 | 
			
		||||
#import "GTMGarbageCollection.h"
 | 
			
		||||
#import <fcntl.h>
 | 
			
		||||
#import <unistd.h>
 | 
			
		||||
#import <stdlib.h>
 | 
			
		||||
#import <pthread.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogger
 | 
			
		||||
 | 
			
		||||
// Returns a pointer to the shared logger instance. If none exists, a standard
 | 
			
		||||
// logger is created and returned.
 | 
			
		||||
+ (id)sharedLogger {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    if (gSharedLogger == nil) {
 | 
			
		||||
      gSharedLogger = [[self standardLogger] retain];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return [[gSharedLogger retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (void)setSharedLogger:(GTMLogger *)logger {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    [gSharedLogger autorelease];
 | 
			
		||||
    gSharedLogger = [logger retain];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)standardLogger {
 | 
			
		||||
  // Don't trust NSFileHandle not to throw
 | 
			
		||||
  @try {
 | 
			
		||||
    id<GTMLogWriter> writer = [NSFileHandle fileHandleWithStandardOutput];
 | 
			
		||||
    id<GTMLogFormatter> fr = [[[GTMLogStandardFormatter alloc] init]
 | 
			
		||||
                                 autorelease];
 | 
			
		||||
    id<GTMLogFilter> filter = [[[GTMLogLevelFilter alloc] init] autorelease];
 | 
			
		||||
    return [[[self alloc] initWithWriter:writer
 | 
			
		||||
                               formatter:fr
 | 
			
		||||
                                  filter:filter] autorelease];
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)standardLoggerWithStderr {
 | 
			
		||||
  // Don't trust NSFileHandle not to throw
 | 
			
		||||
  @try {
 | 
			
		||||
    id me = [self standardLogger];
 | 
			
		||||
    [me setWriter:[NSFileHandle fileHandleWithStandardError]];
 | 
			
		||||
    return me;
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)standardLoggerWithStdoutAndStderr {
 | 
			
		||||
  // We're going to take advantage of the GTMLogger to GTMLogWriter adaptor
 | 
			
		||||
  // and create a composite logger that an outer "standard" logger can use
 | 
			
		||||
  // as a writer. Our inner loggers should apply no formatting since the main
 | 
			
		||||
  // logger does that and we want the caller to be able to change formatters
 | 
			
		||||
  // or add writers without knowing the inner structure of our composite.
 | 
			
		||||
 | 
			
		||||
  // Don't trust NSFileHandle not to throw
 | 
			
		||||
  @try {
 | 
			
		||||
    GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init] 
 | 
			
		||||
                                          autorelease];
 | 
			
		||||
    GTMLogger *stdoutLogger =
 | 
			
		||||
        [self loggerWithWriter:[NSFileHandle fileHandleWithStandardOutput]
 | 
			
		||||
                     formatter:formatter
 | 
			
		||||
                        filter:[[[GTMLogMaximumLevelFilter alloc]
 | 
			
		||||
                                  initWithMaximumLevel:kGTMLoggerLevelInfo]
 | 
			
		||||
                                      autorelease]];
 | 
			
		||||
    GTMLogger *stderrLogger =
 | 
			
		||||
        [self loggerWithWriter:[NSFileHandle fileHandleWithStandardError]
 | 
			
		||||
                     formatter:formatter
 | 
			
		||||
                        filter:[[[GTMLogMininumLevelFilter alloc]
 | 
			
		||||
                                  initWithMinimumLevel:kGTMLoggerLevelError]
 | 
			
		||||
                                      autorelease]];
 | 
			
		||||
    GTMLogger *compositeWriter =
 | 
			
		||||
        [self loggerWithWriter:[NSArray arrayWithObjects:
 | 
			
		||||
                                   stdoutLogger, stderrLogger, nil]
 | 
			
		||||
                     formatter:formatter
 | 
			
		||||
                        filter:[[[GTMLogNoFilter alloc] init] autorelease]];
 | 
			
		||||
    GTMLogger *outerLogger = [self standardLogger];
 | 
			
		||||
    [outerLogger setWriter:compositeWriter];
 | 
			
		||||
    return outerLogger;
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)standardLoggerWithPath:(NSString *)path {
 | 
			
		||||
  @try {
 | 
			
		||||
    NSFileHandle *fh = [NSFileHandle fileHandleForLoggingAtPath:path mode:0644];
 | 
			
		||||
    if (fh == nil) return nil;
 | 
			
		||||
    id me = [self standardLogger];
 | 
			
		||||
    [me setWriter:fh];
 | 
			
		||||
    return me;
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)loggerWithWriter:(id<GTMLogWriter>)writer
 | 
			
		||||
             formatter:(id<GTMLogFormatter>)formatter
 | 
			
		||||
                filter:(id<GTMLogFilter>)filter {
 | 
			
		||||
  return [[[self alloc] initWithWriter:writer
 | 
			
		||||
                             formatter:formatter
 | 
			
		||||
                                filter:filter] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)logger {
 | 
			
		||||
  return [[[self alloc] init] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  return [self initWithWriter:nil formatter:nil filter:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithWriter:(id<GTMLogWriter>)writer
 | 
			
		||||
           formatter:(id<GTMLogFormatter>)formatter
 | 
			
		||||
              filter:(id<GTMLogFilter>)filter {
 | 
			
		||||
  if ((self = [super init])) {
 | 
			
		||||
    [self setWriter:writer];
 | 
			
		||||
    [self setFormatter:formatter];
 | 
			
		||||
    [self setFilter:filter];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  // Unlikely, but |writer_| may be an NSFileHandle, which can throw
 | 
			
		||||
  @try {
 | 
			
		||||
    [formatter_ release];
 | 
			
		||||
    [filter_ release];
 | 
			
		||||
    [writer_ release];
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id<GTMLogWriter>)writer {
 | 
			
		||||
  return [[writer_ retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setWriter:(id<GTMLogWriter>)writer {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    [writer_ autorelease];
 | 
			
		||||
    writer_ = nil;
 | 
			
		||||
    if (writer == nil) {
 | 
			
		||||
      // Try to use stdout, but don't trust NSFileHandle
 | 
			
		||||
      @try {
 | 
			
		||||
        writer_ = [[NSFileHandle fileHandleWithStandardOutput] retain];
 | 
			
		||||
      }
 | 
			
		||||
      @catch (id e) {
 | 
			
		||||
        // Leave |writer_| nil
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      writer_ = [writer retain];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id<GTMLogFormatter>)formatter {
 | 
			
		||||
  return [[formatter_ retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setFormatter:(id<GTMLogFormatter>)formatter {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    [formatter_ autorelease];
 | 
			
		||||
    formatter_ = nil;
 | 
			
		||||
    if (formatter == nil) {
 | 
			
		||||
      @try {
 | 
			
		||||
        formatter_ = [[GTMLogBasicFormatter alloc] init];
 | 
			
		||||
      }
 | 
			
		||||
      @catch (id e) {
 | 
			
		||||
        // Leave |formatter_| nil
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      formatter_ = [formatter retain];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id<GTMLogFilter>)filter {
 | 
			
		||||
  return [[filter_ retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setFilter:(id<GTMLogFilter>)filter {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    [filter_ autorelease];
 | 
			
		||||
    filter_ = nil;
 | 
			
		||||
    if (filter == nil) {
 | 
			
		||||
      @try {
 | 
			
		||||
        filter_ = [[GTMLogNoFilter alloc] init];
 | 
			
		||||
      }
 | 
			
		||||
      @catch (id e) {
 | 
			
		||||
        // Leave |filter_| nil
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      filter_ = [filter retain];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logDebug:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelDebug];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logInfo:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelInfo];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logError:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelError];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logAssert:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelAssert];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogger
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogger (GTMLoggerMacroHelpers)
 | 
			
		||||
 | 
			
		||||
- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelDebug];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelInfo];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelError];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ... {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, fmt);
 | 
			
		||||
  [self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelAssert];
 | 
			
		||||
  va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLoggerMacroHelpers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogger (PrivateMethods)
 | 
			
		||||
 | 
			
		||||
- (void)logInternalFunc:(const char *)func
 | 
			
		||||
                 format:(NSString *)fmt
 | 
			
		||||
                 valist:(va_list)args
 | 
			
		||||
                  level:(GTMLoggerLevel)level {
 | 
			
		||||
  // Primary point where logging happens, logging should never throw, catch
 | 
			
		||||
  // everything.
 | 
			
		||||
  @try {
 | 
			
		||||
    NSString *fname = func ? [NSString stringWithUTF8String:func] : nil;
 | 
			
		||||
    NSString *msg = [formatter_ stringForFunc:fname
 | 
			
		||||
                                   withFormat:fmt
 | 
			
		||||
                                       valist:args
 | 
			
		||||
                                        level:level];
 | 
			
		||||
    if (msg && [filter_ filterAllowsMessage:msg level:level])
 | 
			
		||||
      [writer_ logMessage:msg level:level];
 | 
			
		||||
  }
 | 
			
		||||
  @catch (id e) {
 | 
			
		||||
    // Ignored
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // PrivateMethods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation NSFileHandle (GTMFileHandleLogWriter)
 | 
			
		||||
 | 
			
		||||
+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode {
 | 
			
		||||
  int fd = -1;
 | 
			
		||||
  if (path) {
 | 
			
		||||
    int flags = O_WRONLY | O_APPEND | O_CREAT;
 | 
			
		||||
    fd = open([path fileSystemRepresentation], flags, mode);
 | 
			
		||||
  }
 | 
			
		||||
  if (fd == -1) return nil;
 | 
			
		||||
  return [[[self alloc] initWithFileDescriptor:fd
 | 
			
		||||
                                closeOnDealloc:YES] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    // Closed pipes should not generate exceptions in our caller. Catch here
 | 
			
		||||
    // as well [GTMLogger logInternalFunc:...] so that an exception in this
 | 
			
		||||
    // writer does not prevent other writers from having a chance.
 | 
			
		||||
    @try {
 | 
			
		||||
      NSString *line = [NSString stringWithFormat:@"%@\n", msg];
 | 
			
		||||
      [self writeData:[line dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
    }
 | 
			
		||||
    @catch (id e) {
 | 
			
		||||
      // Ignored
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMFileHandleLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation NSArray (GTMArrayCompositeLogWriter)
 | 
			
		||||
 | 
			
		||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
  @synchronized(self) {
 | 
			
		||||
    id<GTMLogWriter> child = nil;
 | 
			
		||||
    GTM_FOREACH_OBJECT(child, self) {
 | 
			
		||||
      if ([child conformsToProtocol:@protocol(GTMLogWriter)])
 | 
			
		||||
        [child logMessage:msg level:level];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMArrayCompositeLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogger (GTMLoggerLogWriter)
 | 
			
		||||
 | 
			
		||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
  switch (level) {
 | 
			
		||||
    case kGTMLoggerLevelDebug:
 | 
			
		||||
      [self logDebug:@"%@", msg];
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelInfo:
 | 
			
		||||
      [self logInfo:@"%@", msg];
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelError:
 | 
			
		||||
      [self logError:@"%@", msg];
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelAssert:
 | 
			
		||||
      [self logAssert:@"%@", msg];
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      // Ignore the message.
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLoggerLogWriter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogBasicFormatter
 | 
			
		||||
 | 
			
		||||
- (NSString *)prettyNameForFunc:(NSString *)func {
 | 
			
		||||
  NSString *name = [func stringByTrimmingCharactersInSet:
 | 
			
		||||
                     [NSCharacterSet whitespaceAndNewlineCharacterSet]];
 | 
			
		||||
  NSString *function = @"(unknown)";
 | 
			
		||||
  if ([name length]) {
 | 
			
		||||
    if (// Objective C __func__ and __PRETTY_FUNCTION__
 | 
			
		||||
        [name hasPrefix:@"-["] || [name hasPrefix:@"+["] ||
 | 
			
		||||
        // C++ __PRETTY_FUNCTION__ and other preadorned formats
 | 
			
		||||
        [name hasSuffix:@")"]) {
 | 
			
		||||
      function = name;
 | 
			
		||||
    } else {
 | 
			
		||||
      // Assume C99 __func__
 | 
			
		||||
      function = [NSString stringWithFormat:@"%@()", name];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return function;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringForFunc:(NSString *)func
 | 
			
		||||
                 withFormat:(NSString *)fmt
 | 
			
		||||
                     valist:(va_list)args
 | 
			
		||||
                      level:(GTMLoggerLevel)level {
 | 
			
		||||
  // Performance note: We may want to do a quick check here to see if |fmt|
 | 
			
		||||
  // contains a '%', and if not, simply return 'fmt'.
 | 
			
		||||
  if (!(fmt && args)) return nil;
 | 
			
		||||
  return [[[NSString alloc] initWithFormat:fmt arguments:args] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogBasicFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogStandardFormatter
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  if ((self = [super init])) {
 | 
			
		||||
    dateFormatter_ = [[NSDateFormatter alloc] init];
 | 
			
		||||
    [dateFormatter_ setFormatterBehavior:NSDateFormatterBehavior10_4];
 | 
			
		||||
    [dateFormatter_ setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
 | 
			
		||||
    pname_ = [[[NSProcessInfo processInfo] processName] copy];
 | 
			
		||||
    pid_ = [[NSProcessInfo processInfo] processIdentifier];
 | 
			
		||||
    if (!(dateFormatter_ && pname_)) {
 | 
			
		||||
      [self release];
 | 
			
		||||
      return nil;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [dateFormatter_ release];
 | 
			
		||||
  [pname_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringForFunc:(NSString *)func
 | 
			
		||||
                 withFormat:(NSString *)fmt
 | 
			
		||||
                     valist:(va_list)args
 | 
			
		||||
                      level:(GTMLoggerLevel)level {
 | 
			
		||||
  NSString *tstamp = nil;
 | 
			
		||||
  @synchronized (dateFormatter_) {
 | 
			
		||||
    tstamp = [dateFormatter_ stringFromDate:[NSDate date]];
 | 
			
		||||
  }
 | 
			
		||||
  return [NSString stringWithFormat:@"%@ %@[%d/%p] [lvl=%d] %@ %@",
 | 
			
		||||
           tstamp, pname_, pid_, pthread_self(),
 | 
			
		||||
           level, [self prettyNameForFunc:func],
 | 
			
		||||
           // |super| has guard for nil |fmt| and |args|
 | 
			
		||||
           [super stringForFunc:func withFormat:fmt valist:args level:level]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogStandardFormatter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogLevelFilter
 | 
			
		||||
 | 
			
		||||
// Check the environment and the user preferences for the GTMVerboseLogging key
 | 
			
		||||
// to see if verbose logging has been enabled. The environment variable will
 | 
			
		||||
// override the defaults setting, so check the environment first.
 | 
			
		||||
// COV_NF_START
 | 
			
		||||
static BOOL IsVerboseLoggingEnabled(void) {
 | 
			
		||||
  static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging";
 | 
			
		||||
  NSString *value = [[[NSProcessInfo processInfo] environment]
 | 
			
		||||
                        objectForKey:kVerboseLoggingKey];
 | 
			
		||||
  if (value) {
 | 
			
		||||
    // Emulate [NSString boolValue] for pre-10.5
 | 
			
		||||
    value = [value stringByTrimmingCharactersInSet:
 | 
			
		||||
                [NSCharacterSet whitespaceAndNewlineCharacterSet]];
 | 
			
		||||
    if ([[value uppercaseString] hasPrefix:@"Y"] ||
 | 
			
		||||
        [[value uppercaseString] hasPrefix:@"T"] ||
 | 
			
		||||
        [value intValue]) {
 | 
			
		||||
      return YES;
 | 
			
		||||
    } else {
 | 
			
		||||
      return NO;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return [[NSUserDefaults standardUserDefaults] boolForKey:kVerboseLoggingKey];
 | 
			
		||||
}
 | 
			
		||||
// COV_NF_END
 | 
			
		||||
 | 
			
		||||
// In DEBUG builds, log everything. If we're not in a debug build we'll assume
 | 
			
		||||
// that we're in a Release build.
 | 
			
		||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  return YES;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  BOOL allow = YES;
 | 
			
		||||
 | 
			
		||||
  switch (level) {
 | 
			
		||||
    case kGTMLoggerLevelDebug:
 | 
			
		||||
      allow = NO;
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelInfo:
 | 
			
		||||
      allow = IsVerboseLoggingEnabled();
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelError:
 | 
			
		||||
      allow = YES;
 | 
			
		||||
      break;
 | 
			
		||||
    case kGTMLoggerLevelAssert:
 | 
			
		||||
      allow = YES;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      allow = YES;
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return allow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogLevelFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogNoFilter
 | 
			
		||||
 | 
			
		||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
  return YES;  // Allow everything through
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogNoFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogAllowedLevelFilter
 | 
			
		||||
 | 
			
		||||
// Private designated initializer
 | 
			
		||||
- (id)initWithAllowedLevels:(NSIndexSet *)levels {
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    allowedLevels_ = [levels retain];
 | 
			
		||||
    // Cap min/max level
 | 
			
		||||
    if (!allowedLevels_ ||
 | 
			
		||||
        // NSIndexSet is unsigned so only check the high bound, but need to
 | 
			
		||||
        // check both first and last index because NSIndexSet appears to allow
 | 
			
		||||
        // wraparound.
 | 
			
		||||
        ([allowedLevels_ firstIndex] > kGTMLoggerLevelAssert) ||
 | 
			
		||||
        ([allowedLevels_ lastIndex] > kGTMLoggerLevelAssert)) {
 | 
			
		||||
      [self release];
 | 
			
		||||
      return nil;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
  // Allow all levels in default init
 | 
			
		||||
  return [self initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
 | 
			
		||||
             NSMakeRange(kGTMLoggerLevelUnknown,
 | 
			
		||||
                 (kGTMLoggerLevelAssert - kGTMLoggerLevelUnknown + 1))]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [allowedLevels_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
 | 
			
		||||
  return [allowedLevels_ containsIndex:level];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogAllowedLevelFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogMininumLevelFilter
 | 
			
		||||
 | 
			
		||||
- (id)initWithMinimumLevel:(GTMLoggerLevel)level {
 | 
			
		||||
  return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
 | 
			
		||||
             NSMakeRange(level,
 | 
			
		||||
                         (kGTMLoggerLevelAssert - level + 1))]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogMininumLevelFilter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation GTMLogMaximumLevelFilter
 | 
			
		||||
 | 
			
		||||
- (id)initWithMaximumLevel:(GTMLoggerLevel)level {
 | 
			
		||||
  return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
 | 
			
		||||
             NSMakeRange(kGTMLoggerLevelUnknown, level + 1)]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end  // GTMLogMaximumLevelFilter
 | 
			
		||||
							
								
								
									
										88
									
								
								External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,88 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMMethodCheck.h
 | 
			
		||||
//  
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import <stdio.h>
 | 
			
		||||
#import <sysexits.h>
 | 
			
		||||
 | 
			
		||||
/// A macro for enforcing debug time checks to make sure all required methods are linked in
 | 
			
		||||
// 
 | 
			
		||||
// When using categories, it can be very easy to forget to include the
 | 
			
		||||
// implementation of a category. 
 | 
			
		||||
// Let's say you had a class foo that depended on method bar of class baz, and
 | 
			
		||||
// method bar was implemented as a member of a category.
 | 
			
		||||
// You could add the following code:
 | 
			
		||||
// @implementation foo
 | 
			
		||||
// GTM_METHOD_CHECK(baz, bar)
 | 
			
		||||
// @end
 | 
			
		||||
// and the code would check to make sure baz was implemented just before main
 | 
			
		||||
// was called. This works for both dynamic libraries, and executables.
 | 
			
		||||
//
 | 
			
		||||
// Classes (or one of their superclasses) being checked must conform to the 
 | 
			
		||||
// NSObject protocol. We will check this, and spit out a warning if a class does 
 | 
			
		||||
// not conform to NSObject.
 | 
			
		||||
//
 | 
			
		||||
// This is not compiled into release builds.
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
// If you get an error for GTMMethodCheckMethodChecker not being defined, 
 | 
			
		||||
// you need to link in GTMMethodCheck.m. We keep it hidden so that we can have 
 | 
			
		||||
// it living in several separate images without conflict.
 | 
			
		||||
// Functions with the ((constructor)) attribute are called after all +loads
 | 
			
		||||
// have been called. See "Initializing Objective-C Classes" in 
 | 
			
		||||
// http://developer.apple.com/documentation/DeveloperTools/Conceptual/DynamicLibraries/Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-DontLinkElementID_20
 | 
			
		||||
  
 | 
			
		||||
__attribute__ ((constructor, visibility("hidden"))) void GTMMethodCheckMethodChecker(void);
 | 
			
		||||
  
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This is the "magic".
 | 
			
		||||
// A) we need a multi layer define here so that the stupid preprocessor
 | 
			
		||||
//    expands __LINE__ out the way we want it. We need LINE so that each of
 | 
			
		||||
//    out GTM_METHOD_CHECKs generates a unique class method for the class.
 | 
			
		||||
#define GTM_METHOD_CHECK(class, method) GTM_METHOD_CHECK_INNER(class, method, __LINE__)
 | 
			
		||||
#define GTM_METHOD_CHECK_INNER(class, method, line) GTM_METHOD_CHECK_INNER_INNER(class, method, line)
 | 
			
		||||
 | 
			
		||||
// B) Create up a class method called xxGMethodCheckMethod+class+line that the 
 | 
			
		||||
//    GTMMethodCheckMethodChecker function can look for and call. We
 | 
			
		||||
//    look for GTMMethodCheckMethodChecker to enforce linkage of
 | 
			
		||||
//    GTMMethodCheck.m.
 | 
			
		||||
#define GTM_METHOD_CHECK_INNER_INNER(class, method, line) \
 | 
			
		||||
+ (void)xxGTMMethodCheckMethod ## class ## line { \
 | 
			
		||||
  void (*addr)() = GTMMethodCheckMethodChecker; \
 | 
			
		||||
  if (addr && ![class instancesRespondToSelector:@selector(method)] \
 | 
			
		||||
      && ![class respondsToSelector:@selector(method)]) { \
 | 
			
		||||
    fprintf(stderr, "%s:%d: error: We need method '%s' to be linked in for class '%s'\n", \
 | 
			
		||||
            __FILE__, line, #method, #class); \
 | 
			
		||||
    exit(EX_SOFTWARE); \
 | 
			
		||||
  } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // !DEBUG
 | 
			
		||||
 | 
			
		||||
// Do nothing in release.
 | 
			
		||||
#define GTM_METHOD_CHECK(class, method)
 | 
			
		||||
 | 
			
		||||
#endif  // DEBUG
 | 
			
		||||
							
								
								
									
										161
									
								
								External/google-plus-ios-sdk/OpenSource/GTMMethodCheck.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,161 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMMethodCheck.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Don't want any of this in release builds
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
#import "GTMDefines.h"
 | 
			
		||||
#import "GTMMethodCheck.h"
 | 
			
		||||
#import "GTMObjC2Runtime.h"
 | 
			
		||||
#import <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
// Checks to see if the cls passed in (or one of it's superclasses) conforms
 | 
			
		||||
// to NSObject protocol. Inheriting from NSObject is the easiest way to do this
 | 
			
		||||
// but not all classes (i.e. NSProxy) inherit from NSObject. Also, some classes
 | 
			
		||||
// inherit from Object instead of NSObject which is fine, and we'll count as
 | 
			
		||||
// conforming to NSObject for our needs.
 | 
			
		||||
static BOOL ConformsToNSObjectProtocol(Class cls) {
 | 
			
		||||
  // If we get nil, obviously doesn't conform.
 | 
			
		||||
  if (!cls) return NO;
 | 
			
		||||
  const char *className = class_getName(cls);
 | 
			
		||||
  if (!className) return NO;
 | 
			
		||||
 | 
			
		||||
  // We're going to assume that all Apple classes will work
 | 
			
		||||
  // (and aren't being checked)
 | 
			
		||||
  // Note to apple: why doesn't obj-c have real namespaces instead of two
 | 
			
		||||
  // letter hacks? If you name your own classes starting with NS this won't
 | 
			
		||||
  // work for you.
 | 
			
		||||
  // Some classes (like _NSZombie) start with _NS.
 | 
			
		||||
  // On Leopard we have to look for CFObject as well.
 | 
			
		||||
  // On iPhone we check Object as well
 | 
			
		||||
  if ((strncmp(className, "NS", 2) == 0)
 | 
			
		||||
       || (strncmp(className, "_NS", 3) == 0)
 | 
			
		||||
       || (strncmp(className, "__NS", 4) == 0)
 | 
			
		||||
       || (strcmp(className, "CFObject") == 0)
 | 
			
		||||
       || (strcmp(className, "__IncompleteProtocol") == 0)
 | 
			
		||||
#if GTM_IPHONE_SDK
 | 
			
		||||
       || (strcmp(className, "Object") == 0)
 | 
			
		||||
#endif
 | 
			
		||||
    ) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
// iPhone SDK does not define the |Object| class, so we instead test for the
 | 
			
		||||
// |NSObject| class.
 | 
			
		||||
#if GTM_IPHONE_SDK
 | 
			
		||||
  // Iterate through all the protocols |cls| supports looking for NSObject.
 | 
			
		||||
  if (cls == [NSObject class]
 | 
			
		||||
      || class_conformsToProtocol(cls, @protocol(NSObject))) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  // Iterate through all the protocols |cls| supports looking for NSObject.
 | 
			
		||||
  if (cls == [Object class]
 | 
			
		||||
      || class_conformsToProtocol(cls, @protocol(NSObject))) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Recursively check the superclasses.
 | 
			
		||||
  return ConformsToNSObjectProtocol(class_getSuperclass(cls));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GTMMethodCheckMethodChecker(void) {
 | 
			
		||||
  // Run through all the classes looking for class methods that are
 | 
			
		||||
  // prefixed with xxGMMethodCheckMethod. If it finds one, it calls it.
 | 
			
		||||
  // See GTMMethodCheck.h to see what it does.
 | 
			
		||||
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | 
			
		||||
  int numClasses = 0;
 | 
			
		||||
  int newNumClasses = objc_getClassList(NULL, 0);
 | 
			
		||||
  int i;
 | 
			
		||||
  Class *classes = NULL;
 | 
			
		||||
  while (numClasses < newNumClasses) {
 | 
			
		||||
    numClasses = newNumClasses;
 | 
			
		||||
    classes = realloc(classes, sizeof(Class) * numClasses);
 | 
			
		||||
    _GTMDevAssert(classes, @"Unable to allocate memory for classes");
 | 
			
		||||
    newNumClasses = objc_getClassList(classes, numClasses);
 | 
			
		||||
  }
 | 
			
		||||
  for (i = 0; i < numClasses && classes; ++i) {
 | 
			
		||||
    Class cls = classes[i];
 | 
			
		||||
 | 
			
		||||
    // Since we are directly calling objc_msgSend, we need to conform to
 | 
			
		||||
    // @protocol(NSObject), or else we will tumble into a _objc_msgForward
 | 
			
		||||
    // recursive loop when we try and call a function by name.
 | 
			
		||||
    if (!ConformsToNSObjectProtocol(cls)) {
 | 
			
		||||
      // COV_NF_START
 | 
			
		||||
      _GTMDevLog(@"GTMMethodCheckMethodChecker: Class %s does not conform to "
 | 
			
		||||
                 "@protocol(NSObject), so won't be checked",
 | 
			
		||||
                 class_getName(cls));
 | 
			
		||||
      continue;
 | 
			
		||||
      // COV_NF_END
 | 
			
		||||
    }
 | 
			
		||||
    // Since we are looking for a class method (+xxGMMethodCheckMethod...)
 | 
			
		||||
    // we need to query the isa pointer to see what methods it support, but
 | 
			
		||||
    // send the method (if it's supported) to the class itself.
 | 
			
		||||
    unsigned int count;
 | 
			
		||||
    Class metaClass = objc_getMetaClass(class_getName(cls));
 | 
			
		||||
    Method *methods = class_copyMethodList(metaClass, &count);
 | 
			
		||||
    unsigned int j;
 | 
			
		||||
    for (j = 0; j < count; ++j) {
 | 
			
		||||
      SEL selector = method_getName(methods[j]);
 | 
			
		||||
      const char *name = sel_getName(selector);
 | 
			
		||||
      if (strstr(name, "xxGTMMethodCheckMethod") == name) {
 | 
			
		||||
        // Check to make sure that the method we are checking comes
 | 
			
		||||
        // from the same image that we are in. Since GTMMethodCheckMethodChecker
 | 
			
		||||
        // is not exported, we should always find the copy in our local
 | 
			
		||||
        // image. We compare the address of it's image with the address of
 | 
			
		||||
        // the image which implements the method we want to check. If
 | 
			
		||||
        // they match we continue. This does two things:
 | 
			
		||||
        // a) minimizes the amount of calls we make to the xxxGTMMethodCheck
 | 
			
		||||
        //    methods. They should only be called once.
 | 
			
		||||
        // b) prevents initializers for various classes being called too early
 | 
			
		||||
        Dl_info methodCheckerInfo;
 | 
			
		||||
        if (!dladdr(GTMMethodCheckMethodChecker,
 | 
			
		||||
                    &methodCheckerInfo)) {
 | 
			
		||||
          // COV_NF_START
 | 
			
		||||
          // Don't know how to force this case in a unittest.
 | 
			
		||||
          // Certainly hope we never see it.
 | 
			
		||||
          _GTMDevLog(@"GTMMethodCheckMethodChecker: Unable to get dladdr info "
 | 
			
		||||
                "for GTMMethodCheckMethodChecker while introspecting +[%s %s]]",
 | 
			
		||||
                class_getName(cls), name);
 | 
			
		||||
          continue;
 | 
			
		||||
          // COV_NF_END
 | 
			
		||||
        }
 | 
			
		||||
        Dl_info methodInfo;
 | 
			
		||||
        if (!dladdr(method_getImplementation(methods[j]),
 | 
			
		||||
                    &methodInfo)) {
 | 
			
		||||
          // COV_NF_START
 | 
			
		||||
          // Don't know how to force this case in a unittest
 | 
			
		||||
          // Certainly hope we never see it.
 | 
			
		||||
          _GTMDevLog(@"GTMMethodCheckMethodChecker: Unable to get dladdr info "
 | 
			
		||||
                     "for %s while introspecting +[%s %s]]", name,
 | 
			
		||||
                     class_getName(cls), name);
 | 
			
		||||
          continue;
 | 
			
		||||
          // COV_NF_END
 | 
			
		||||
        }
 | 
			
		||||
        if (methodCheckerInfo.dli_fbase == methodInfo.dli_fbase) {
 | 
			
		||||
          objc_msgSend(cls, selector);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    free(methods);
 | 
			
		||||
  }
 | 
			
		||||
  free(classes);
 | 
			
		||||
  [pool drain];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // DEBUG
 | 
			
		||||
							
								
								
									
										36
									
								
								External/google-plus-ios-sdk/OpenSource/GTMNSDictionary+URLArguments.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,36 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMNSDictionary+URLArguments.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
/// Utility for building a URL or POST argument string.
 | 
			
		||||
@interface NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
 | 
			
		||||
 | 
			
		||||
/// Returns a dictionary of the decoded key-value pairs in a http arguments
 | 
			
		||||
/// string of the form key1=value1&key2=value2&...&keyN=valueN.
 | 
			
		||||
/// Keys and values will be unescaped automatically.
 | 
			
		||||
/// Only the first value for a repeated key is returned.
 | 
			
		||||
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString;
 | 
			
		||||
 | 
			
		||||
/// Gets a string representation of the dictionary in the form
 | 
			
		||||
/// key1=value1&key2=value2&...&keyN=valueN, suitable for use as either
 | 
			
		||||
/// URL arguments (after a '?') or POST body. Keys and values will be escaped
 | 
			
		||||
/// automatically, so should be unescaped in the dictionary.
 | 
			
		||||
- (NSString *)gtm_httpArgumentsString;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										71
									
								
								External/google-plus-ios-sdk/OpenSource/GTMNSDictionary+URLArguments.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,71 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMNSDictionary+URLArguments.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTMNSDictionary+URLArguments.h"
 | 
			
		||||
#import "GTMNSString+URLArguments.h"
 | 
			
		||||
#import "GTMMethodCheck.h"
 | 
			
		||||
#import "GTMDefines.h"
 | 
			
		||||
 | 
			
		||||
@implementation NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
 | 
			
		||||
 | 
			
		||||
GTM_METHOD_CHECK(NSString, gtm_stringByEscapingForURLArgument);
 | 
			
		||||
GTM_METHOD_CHECK(NSString, gtm_stringByUnescapingFromURLArgument);
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString {
 | 
			
		||||
  NSMutableDictionary* ret = [NSMutableDictionary dictionary];
 | 
			
		||||
  NSArray* components = [argString componentsSeparatedByString:@"&"];
 | 
			
		||||
  NSString* component;
 | 
			
		||||
  // Use reverse order so that the first occurrence of a key replaces
 | 
			
		||||
  // those subsequent.
 | 
			
		||||
  GTM_FOREACH_ENUMEREE(component, [components reverseObjectEnumerator]) {
 | 
			
		||||
    if ([component length] == 0)
 | 
			
		||||
      continue;
 | 
			
		||||
    NSRange pos = [component rangeOfString:@"="];
 | 
			
		||||
    NSString *key;
 | 
			
		||||
    NSString *val;
 | 
			
		||||
    if (pos.location == NSNotFound) {
 | 
			
		||||
      key = [component gtm_stringByUnescapingFromURLArgument];
 | 
			
		||||
      val = @"";
 | 
			
		||||
    } else {
 | 
			
		||||
      key = [[component substringToIndex:pos.location]
 | 
			
		||||
             gtm_stringByUnescapingFromURLArgument];
 | 
			
		||||
      val = [[component substringFromIndex:pos.location + pos.length]
 | 
			
		||||
             gtm_stringByUnescapingFromURLArgument];
 | 
			
		||||
    }
 | 
			
		||||
    // gtm_stringByUnescapingFromURLArgument returns nil on invalid UTF8
 | 
			
		||||
    // and NSMutableDictionary raises an exception when passed nil values.
 | 
			
		||||
    if (!key) key = @"";
 | 
			
		||||
    if (!val) val = @"";
 | 
			
		||||
    [ret setObject:val forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)gtm_httpArgumentsString {
 | 
			
		||||
  NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:[self count]];
 | 
			
		||||
  NSString* key;
 | 
			
		||||
  GTM_FOREACH_KEY(key, self) {
 | 
			
		||||
    [arguments addObject:[NSString stringWithFormat:@"%@=%@",
 | 
			
		||||
                          [key gtm_stringByEscapingForURLArgument],
 | 
			
		||||
                          [[[self objectForKey:key] description] gtm_stringByEscapingForURLArgument]]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return [arguments componentsJoinedByString:@"&"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										41
									
								
								External/google-plus-ios-sdk/OpenSource/GTMNSString+URLArguments.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,41 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMNSString+URLArguments.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
/// Utilities for encoding and decoding URL arguments.
 | 
			
		||||
@interface NSString (GTMNSStringURLArgumentsAdditions)
 | 
			
		||||
 | 
			
		||||
/// Returns a string that is escaped properly to be a URL argument.
 | 
			
		||||
//
 | 
			
		||||
/// This differs from stringByAddingPercentEscapesUsingEncoding: in that it
 | 
			
		||||
/// will escape all the reserved characters (per RFC 3986
 | 
			
		||||
/// <http://www.ietf.org/rfc/rfc3986.txt>) which
 | 
			
		||||
/// stringByAddingPercentEscapesUsingEncoding would leave.
 | 
			
		||||
///
 | 
			
		||||
/// This will also escape '%', so this should not be used on a string that has
 | 
			
		||||
/// already been escaped unless double-escaping is the desired result.
 | 
			
		||||
- (NSString*)gtm_stringByEscapingForURLArgument;
 | 
			
		||||
 | 
			
		||||
/// Returns the unescaped version of a URL argument
 | 
			
		||||
//
 | 
			
		||||
/// This has the same behavior as stringByReplacingPercentEscapesUsingEncoding:,
 | 
			
		||||
/// except that it will also convert '+' to space.
 | 
			
		||||
- (NSString*)gtm_stringByUnescapingFromURLArgument;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										45
									
								
								External/google-plus-ios-sdk/OpenSource/GTMNSString+URLArguments.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,45 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMNSString+URLArguments.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2006-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTMNSString+URLArguments.h"
 | 
			
		||||
#import "GTMGarbageCollection.h"
 | 
			
		||||
 | 
			
		||||
@implementation NSString (GTMNSStringURLArgumentsAdditions)
 | 
			
		||||
 | 
			
		||||
- (NSString*)gtm_stringByEscapingForURLArgument {
 | 
			
		||||
  // Encode all the reserved characters, per RFC 3986
 | 
			
		||||
  // (<http://www.ietf.org/rfc/rfc3986.txt>)
 | 
			
		||||
  CFStringRef escaped = 
 | 
			
		||||
    CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
 | 
			
		||||
                                            (CFStringRef)self,
 | 
			
		||||
                                            NULL,
 | 
			
		||||
                                            (CFStringRef)@"!*'();:@&=+$,/?%#[]",
 | 
			
		||||
                                            kCFStringEncodingUTF8);
 | 
			
		||||
  return GTMCFAutorelease(escaped);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString*)gtm_stringByUnescapingFromURLArgument {
 | 
			
		||||
  NSMutableString *resultString = [NSMutableString stringWithString:self];
 | 
			
		||||
  [resultString replaceOccurrencesOfString:@"+"
 | 
			
		||||
                                withString:@" "
 | 
			
		||||
                                   options:NSLiteralSearch
 | 
			
		||||
                                     range:NSMakeRange(0, [resultString length])];
 | 
			
		||||
  return [resultString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										325
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,325 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
 | 
			
		||||
// This class implements the OAuth 2 protocol for authorizing requests.
 | 
			
		||||
// http://tools.ietf.org/html/draft-ietf-oauth-v2
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
// GTMHTTPFetcher.h brings in GTLDefines/GDataDefines
 | 
			
		||||
#import "GTMHTTPFetcher.h"
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTMOAUTH2AUTHENTICATION_DEFINE_GLOBALS
 | 
			
		||||
  #define _EXTERN
 | 
			
		||||
  #define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
  #if defined(__cplusplus)
 | 
			
		||||
    #define _EXTERN extern "C"
 | 
			
		||||
  #else
 | 
			
		||||
    #define _EXTERN extern
 | 
			
		||||
  #endif
 | 
			
		||||
  #define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Until all OAuth 2 providers are up to the same spec, we'll provide a crude
 | 
			
		||||
// way here to override the "Bearer" string in the Authorization header
 | 
			
		||||
#ifndef GTM_OAUTH2_BEARER
 | 
			
		||||
#define GTM_OAUTH2_BEARER "Bearer"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Service provider name allows stored authorization to be associated with
 | 
			
		||||
// the authorizing service
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ServiceProviderGoogle _INITIALIZE_AS(@"Google");
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMOAuth2SignIn constants, included here for use by clients
 | 
			
		||||
//
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorDomain  _INITIALIZE_AS(@"com.google.GTMOAuth2");
 | 
			
		||||
 | 
			
		||||
// Error userInfo keys
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorMessageKey _INITIALIZE_AS(@"error");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorRequestKey _INITIALIZE_AS(@"request");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorJSONKey    _INITIALIZE_AS(@"json");
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  // Error code indicating that the window was prematurely closed
 | 
			
		||||
  kGTMOAuth2ErrorWindowClosed          = -1000,
 | 
			
		||||
  kGTMOAuth2ErrorAuthorizationFailed   = -1001,
 | 
			
		||||
  kGTMOAuth2ErrorTokenExpired          = -1002,
 | 
			
		||||
  kGTMOAuth2ErrorTokenUnavailable      = -1003,
 | 
			
		||||
  kGTMOAuth2ErrorUnauthorizableRequest = -1004
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Notifications for token fetches
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchStarted        _INITIALIZE_AS(@"kGTMOAuth2FetchStarted");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchStopped        _INITIALIZE_AS(@"kGTMOAuth2FetchStopped");
 | 
			
		||||
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetcherKey          _INITIALIZE_AS(@"fetcher");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchTypeKey        _INITIALIZE_AS(@"FetchType");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchTypeToken      _INITIALIZE_AS(@"token");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchTypeRefresh    _INITIALIZE_AS(@"refresh");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchTypeAssertion  _INITIALIZE_AS(@"assertion");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2FetchTypeUserInfo   _INITIALIZE_AS(@"userInfo");
 | 
			
		||||
 | 
			
		||||
// Token-issuance errors
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorKey                  _INITIALIZE_AS(@"error");
 | 
			
		||||
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorInvalidRequest       _INITIALIZE_AS(@"invalid_request");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorInvalidClient        _INITIALIZE_AS(@"invalid_client");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorInvalidGrant         _INITIALIZE_AS(@"invalid_grant");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorUnauthorizedClient   _INITIALIZE_AS(@"unauthorized_client");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorUnsupportedGrantType _INITIALIZE_AS(@"unsupported_grant_type");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2ErrorInvalidScope         _INITIALIZE_AS(@"invalid_scope");
 | 
			
		||||
 | 
			
		||||
// Notification that sign-in has completed, and token fetches will begin (useful
 | 
			
		||||
// for displaying interstitial messages after the window has closed)
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2UserSignedIn              _INITIALIZE_AS(@"kGTMOAuth2UserSignedIn");
 | 
			
		||||
 | 
			
		||||
// Notification for token changes
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2AccessTokenRefreshed _INITIALIZE_AS(@"kGTMOAuth2AccessTokenRefreshed");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2RefreshTokenChanged  _INITIALIZE_AS(@"kGTMOAuth2RefreshTokenChanged");
 | 
			
		||||
 | 
			
		||||
// Notification for WebView loading
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewStartedLoading _INITIALIZE_AS(@"kGTMOAuth2WebViewStartedLoading");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewStoppedLoading _INITIALIZE_AS(@"kGTMOAuth2WebViewStoppedLoading");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewKey            _INITIALIZE_AS(@"kGTMOAuth2WebViewKey");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewStopKindKey    _INITIALIZE_AS(@"kGTMOAuth2WebViewStopKindKey");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewFinished       _INITIALIZE_AS(@"finished");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewFailed         _INITIALIZE_AS(@"failed");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2WebViewCancelled      _INITIALIZE_AS(@"cancelled");
 | 
			
		||||
 | 
			
		||||
// Notification for network loss during html sign-in display
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2NetworkLost         _INITIALIZE_AS(@"kGTMOAuthNetworkLost");
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2NetworkFound        _INITIALIZE_AS(@"kGTMOAuthNetworkFound");
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2Authentication : NSObject <GTMFetcherAuthorizationProtocol>  {
 | 
			
		||||
 @private
 | 
			
		||||
  NSString *clientID_;
 | 
			
		||||
  NSString *clientSecret_;
 | 
			
		||||
  NSString *redirectURI_;
 | 
			
		||||
  NSMutableDictionary *parameters_;
 | 
			
		||||
 | 
			
		||||
  // authorization parameters
 | 
			
		||||
  NSURL *tokenURL_;
 | 
			
		||||
  NSDate *expirationDate_;
 | 
			
		||||
 | 
			
		||||
  NSDictionary *additionalTokenRequestParameters_;
 | 
			
		||||
 | 
			
		||||
  // queue of requests for authorization waiting for a valid access token
 | 
			
		||||
  GTMHTTPFetcher *refreshFetcher_;
 | 
			
		||||
  NSMutableArray *authorizationQueue_;
 | 
			
		||||
 | 
			
		||||
  id <GTMHTTPFetcherServiceProtocol> fetcherService_; // WEAK
 | 
			
		||||
 | 
			
		||||
  Class parserClass_;
 | 
			
		||||
 | 
			
		||||
  BOOL shouldAuthorizeAllRequests_;
 | 
			
		||||
 | 
			
		||||
  // arbitrary data retained for the user
 | 
			
		||||
  id userData_;
 | 
			
		||||
  NSMutableDictionary *properties_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OAuth2 standard protocol parameters
 | 
			
		||||
//
 | 
			
		||||
// These should be the plain strings; any needed escaping will be provided by
 | 
			
		||||
// the library.
 | 
			
		||||
 | 
			
		||||
// Request properties
 | 
			
		||||
@property (copy) NSString *clientID;
 | 
			
		||||
@property (copy) NSString *clientSecret;
 | 
			
		||||
@property (copy) NSString *redirectURI;
 | 
			
		||||
@property (retain) NSString *scope;
 | 
			
		||||
@property (retain) NSString *tokenType;
 | 
			
		||||
@property (retain) NSString *assertion;
 | 
			
		||||
 | 
			
		||||
// Apps may optionally add parameters here to be provided to the token
 | 
			
		||||
// endpoint on token requests and refreshes
 | 
			
		||||
@property (retain) NSDictionary *additionalTokenRequestParameters;
 | 
			
		||||
 | 
			
		||||
// Response properties
 | 
			
		||||
@property (retain) NSMutableDictionary *parameters;
 | 
			
		||||
 | 
			
		||||
@property (retain) NSString *accessToken;
 | 
			
		||||
@property (retain) NSString *refreshToken;
 | 
			
		||||
@property (retain) NSNumber *expiresIn;
 | 
			
		||||
@property (retain) NSString *code;
 | 
			
		||||
@property (retain) NSString *errorString;
 | 
			
		||||
 | 
			
		||||
// URL for obtaining access tokens
 | 
			
		||||
@property (copy) NSURL *tokenURL;
 | 
			
		||||
 | 
			
		||||
// Calculated expiration date (expiresIn seconds added to the
 | 
			
		||||
// time the access token was received.)
 | 
			
		||||
@property (copy) NSDate *expirationDate;
 | 
			
		||||
 | 
			
		||||
// Service identifier, like "Google"; not used for authentication
 | 
			
		||||
//
 | 
			
		||||
// The provider name is just for allowing stored authorization to be associated
 | 
			
		||||
// with the authorizing service.
 | 
			
		||||
@property (copy) NSString *serviceProvider;
 | 
			
		||||
 | 
			
		||||
// User email and verified status; not used for authentication
 | 
			
		||||
//
 | 
			
		||||
// The verified string can be checked with -boolValue. If the result is false,
 | 
			
		||||
// then the email address is listed with the account on the server, but the
 | 
			
		||||
// address has not been confirmed as belonging to the owner of the account.
 | 
			
		||||
@property (retain) NSString *userEmail;
 | 
			
		||||
@property (retain) NSString *userEmailIsVerified;
 | 
			
		||||
 | 
			
		||||
// Property indicating if this auth has a refresh token so is suitable for
 | 
			
		||||
// authorizing a request. This does not guarantee that the token is valid.
 | 
			
		||||
@property (readonly) BOOL canAuthorize;
 | 
			
		||||
 | 
			
		||||
// Property indicating if this object will authorize plain http request
 | 
			
		||||
// (as well as any non-https requests.) Default is NO, only requests with the
 | 
			
		||||
// scheme https are authorized, since security may be compromised if tokens
 | 
			
		||||
// are sent over the wire using an unencrypted protocol like http.
 | 
			
		||||
@property (assign) BOOL shouldAuthorizeAllRequests;
 | 
			
		||||
 | 
			
		||||
// userData is retained for the convenience of the caller
 | 
			
		||||
@property (retain) id userData;
 | 
			
		||||
 | 
			
		||||
// Stored property values are retained for the convenience of the caller
 | 
			
		||||
@property (retain) NSDictionary *properties;
 | 
			
		||||
 | 
			
		||||
// Property for the optional fetcher service instance to be used to create
 | 
			
		||||
// fetchers
 | 
			
		||||
//
 | 
			
		||||
// Fetcher service objects retain authorizations, so this is weak to avoid
 | 
			
		||||
// circular retains.
 | 
			
		||||
@property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK
 | 
			
		||||
 | 
			
		||||
// Alternative JSON parsing class; this should implement the
 | 
			
		||||
// GTMOAuth2ParserClass informal protocol. If this property is
 | 
			
		||||
// not set, the class SBJSON must be available in the runtime.
 | 
			
		||||
@property (assign) Class parserClass;
 | 
			
		||||
 | 
			
		||||
// Convenience method for creating an authentication object
 | 
			
		||||
+ (id)authenticationWithServiceProvider:(NSString *)serviceProvider
 | 
			
		||||
                               tokenURL:(NSURL *)tokenURL
 | 
			
		||||
                            redirectURI:(NSString *)redirectURI
 | 
			
		||||
                               clientID:(NSString *)clientID
 | 
			
		||||
                           clientSecret:(NSString *)clientSecret;
 | 
			
		||||
 | 
			
		||||
// Clear out any authentication values, prepare for a new request fetch
 | 
			
		||||
- (void)reset;
 | 
			
		||||
 | 
			
		||||
// Main authorization entry points
 | 
			
		||||
//
 | 
			
		||||
// These will refresh the access token, if necessary, add the access token to
 | 
			
		||||
// the request, then invoke the callback.
 | 
			
		||||
//
 | 
			
		||||
// The request argument may be nil to just force a refresh of the access token,
 | 
			
		||||
// if needed.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: To avoid accidental leaks of bearer tokens, the request must
 | 
			
		||||
// be for a URL with the scheme https unless the shouldAuthorizeAllRequests
 | 
			
		||||
// property is set.
 | 
			
		||||
 | 
			
		||||
// The finish selector should have a signature matching
 | 
			
		||||
//   - (void)authentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
//                  request:(NSMutableURLRequest *)request
 | 
			
		||||
//        finishedWithError:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
- (void)authorizeRequest:(NSMutableURLRequest *)request
 | 
			
		||||
                delegate:(id)delegate
 | 
			
		||||
       didFinishSelector:(SEL)sel;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
- (void)authorizeRequest:(NSMutableURLRequest *)request
 | 
			
		||||
       completionHandler:(void (^)(NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Synchronous entry point; authorizing this way cannot refresh an expired
 | 
			
		||||
// access token
 | 
			
		||||
- (BOOL)authorizeRequest:(NSMutableURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
// If the authentication is waiting for a refresh to complete, spin the run
 | 
			
		||||
// loop, discarding events, until the fetch has completed
 | 
			
		||||
//
 | 
			
		||||
// This is only for use in testing or in tools without a user interface.
 | 
			
		||||
- (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Internal properties and methods for use by GTMOAuth2SignIn
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Pending fetcher to get a new access token, if any
 | 
			
		||||
@property (retain) GTMHTTPFetcher *refreshFetcher;
 | 
			
		||||
 | 
			
		||||
// Check if a request is queued up to be authorized
 | 
			
		||||
- (BOOL)isAuthorizingRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
// Check if a request appears to be authorized
 | 
			
		||||
- (BOOL)isAuthorizedRequest:(NSURLRequest *)request;
 | 
			
		||||
 | 
			
		||||
// Stop any pending refresh fetch
 | 
			
		||||
- (void)stopAuthorization;
 | 
			
		||||
 | 
			
		||||
// OAuth fetch user-agent header value
 | 
			
		||||
- (NSString *)userAgent;
 | 
			
		||||
 | 
			
		||||
// Parse and set token and token secret from response data
 | 
			
		||||
- (void)setKeysForResponseString:(NSString *)str;
 | 
			
		||||
- (void)setKeysForResponseDictionary:(NSDictionary *)dict;
 | 
			
		||||
 | 
			
		||||
// Persistent token string for keychain storage
 | 
			
		||||
//
 | 
			
		||||
// We'll use the format "refresh_token=foo&serviceProvider=bar" so we can
 | 
			
		||||
// easily alter what portions of the auth data are stored
 | 
			
		||||
//
 | 
			
		||||
// Use these methods for serialization
 | 
			
		||||
- (NSString *)persistenceResponseString;
 | 
			
		||||
- (void)setKeysForPersistenceResponseString:(NSString *)str;
 | 
			
		||||
 | 
			
		||||
// method to begin fetching an access token, used by the sign-in object
 | 
			
		||||
- (GTMHTTPFetcher *)beginTokenFetchWithDelegate:(id)delegate
 | 
			
		||||
                              didFinishSelector:(SEL)finishedSel;
 | 
			
		||||
 | 
			
		||||
// Entry point to post a notification about a fetcher currently used for
 | 
			
		||||
// obtaining or refreshing a token; the sign-in object will also use this
 | 
			
		||||
// to indicate when the user's email address is being fetched.
 | 
			
		||||
//
 | 
			
		||||
// Fetch type constants are above under "notifications for token fetches"
 | 
			
		||||
- (void)notifyFetchIsRunning:(BOOL)isStarting
 | 
			
		||||
                     fetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
                        type:(NSString *)fetchType;
 | 
			
		||||
 | 
			
		||||
// Arbitrary key-value properties retained for the user
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key;
 | 
			
		||||
- (id)propertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Utilities
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
+ (NSString *)encodedOAuthValueForString:(NSString *)str;
 | 
			
		||||
 | 
			
		||||
+ (NSString *)encodedQueryParametersForDictionary:(NSDictionary *)dict;
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)dictionaryWithResponseString:(NSString *)responseStr;
 | 
			
		||||
 | 
			
		||||
+ (NSString *)scopeWithStrings:(NSString *)firsStr, ... NS_REQUIRES_NIL_TERMINATION;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif // GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
							
								
								
									
										1167
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2Authentication.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										174
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,174 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// This sign-in object opens and closes the web view window as needed for
 | 
			
		||||
// users to sign in. For signing in to Google, it also obtains
 | 
			
		||||
// the authenticated user's email address.
 | 
			
		||||
//
 | 
			
		||||
// Typically, this will be managed for the application by
 | 
			
		||||
// GTMOAuth2ViewControllerTouch or GTMOAuth2WindowController, so this
 | 
			
		||||
// class's interface is interesting only if
 | 
			
		||||
// you are creating your own window controller for sign-in.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// Delegate methods implemented by the window controller
 | 
			
		||||
//
 | 
			
		||||
// The window controller implements two methods for use by the sign-in object,
 | 
			
		||||
// the webRequestSelector and the finishedSelector:
 | 
			
		||||
//
 | 
			
		||||
// webRequestSelector has a signature matching
 | 
			
		||||
//   - (void)signIn:(GTMOAuth2SignIn *)signIn displayRequest:(NSURLRequest *)request
 | 
			
		||||
//
 | 
			
		||||
// The web request selector will be invoked with a request to be displayed, or
 | 
			
		||||
// nil to close the window when the final callback request has been encountered.
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// finishedSelector has a signature matching
 | 
			
		||||
//  - (void)signin:(GTMOAuth2SignIn *)signin finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error
 | 
			
		||||
//
 | 
			
		||||
// The finished selector will be invoked when sign-in has completed, except
 | 
			
		||||
// when explicitly canceled by calling cancelSigningIn
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import <SystemConfiguration/SystemConfiguration.h>
 | 
			
		||||
 | 
			
		||||
// GTMHTTPFetcher brings in GTLDefines/GDataDefines
 | 
			
		||||
#import "GTMHTTPFetcher.h"
 | 
			
		||||
 | 
			
		||||
#import "GTMOAuth2Authentication.h"
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2SignIn : NSObject {
 | 
			
		||||
 @private
 | 
			
		||||
  GTMOAuth2Authentication *auth_;
 | 
			
		||||
 | 
			
		||||
  // the endpoint for displaying the sign-in page
 | 
			
		||||
  NSURL *authorizationURL_;
 | 
			
		||||
  NSDictionary *additionalAuthorizationParameters_;
 | 
			
		||||
 | 
			
		||||
  id delegate_;
 | 
			
		||||
  SEL webRequestSelector_;
 | 
			
		||||
  SEL finishedSelector_;
 | 
			
		||||
 | 
			
		||||
  BOOL hasHandledCallback_;
 | 
			
		||||
 | 
			
		||||
  GTMHTTPFetcher *pendingFetcher_;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
  BOOL shouldFetchGoogleUserEmail_;
 | 
			
		||||
  BOOL shouldFetchGoogleUserProfile_;
 | 
			
		||||
  NSDictionary *userProfile_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  SCNetworkReachabilityRef reachabilityRef_;
 | 
			
		||||
  NSTimer *networkLossTimer_;
 | 
			
		||||
  NSTimeInterval networkLossTimeoutInterval_;
 | 
			
		||||
  BOOL hasNotifiedNetworkLoss_;
 | 
			
		||||
 | 
			
		||||
  id userData_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) GTMOAuth2Authentication *authentication;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) NSURL *authorizationURL;
 | 
			
		||||
@property (nonatomic, retain) NSDictionary *additionalAuthorizationParameters;
 | 
			
		||||
 | 
			
		||||
// The delegate is released when signing in finishes or is cancelled
 | 
			
		||||
@property (nonatomic, retain) id delegate;
 | 
			
		||||
@property (nonatomic, assign) SEL webRequestSelector;
 | 
			
		||||
@property (nonatomic, assign) SEL finishedSelector;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) id userData;
 | 
			
		||||
 | 
			
		||||
// By default, signing in to Google will fetch the user's email, but will not
 | 
			
		||||
// fetch the user's profile.
 | 
			
		||||
//
 | 
			
		||||
// The email is saved in the auth object.
 | 
			
		||||
// The profile is available immediately after sign-in.
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
@property (nonatomic, assign) BOOL shouldFetchGoogleUserEmail;
 | 
			
		||||
@property (nonatomic, assign) BOOL shouldFetchGoogleUserProfile;
 | 
			
		||||
@property (nonatomic, retain, readonly) NSDictionary *userProfile;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// The default timeout for an unreachable network during display of the
 | 
			
		||||
// sign-in page is 30 seconds; set this to 0 to have no timeout
 | 
			
		||||
@property (nonatomic, assign) NSTimeInterval networkLossTimeoutInterval;
 | 
			
		||||
 | 
			
		||||
// The delegate is retained until sign-in has completed or been canceled
 | 
			
		||||
//
 | 
			
		||||
// designated initializer
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                    delegate:(id)delegate
 | 
			
		||||
          webRequestSelector:(SEL)webRequestSelector
 | 
			
		||||
            finishedSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
// A default authentication object for signing in to Google services
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (GTMOAuth2Authentication *)standardGoogleAuthenticationForScope:(NSString *)scope
 | 
			
		||||
                                                         clientID:(NSString *)clientID
 | 
			
		||||
                                                     clientSecret:(NSString *)clientSecret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma mark Methods used by the Window Controller
 | 
			
		||||
 | 
			
		||||
// Start the sequence of fetches and sign-in window display for sign-in
 | 
			
		||||
- (BOOL)startSigningIn;
 | 
			
		||||
 | 
			
		||||
// Stop any pending fetches, and close the window (but don't call the
 | 
			
		||||
// delegate's finishedSelector)
 | 
			
		||||
- (void)cancelSigningIn;
 | 
			
		||||
 | 
			
		||||
// Window controllers must tell the sign-in object about any redirect
 | 
			
		||||
// requested by the web view, and any changes in the webview window title
 | 
			
		||||
//
 | 
			
		||||
// If these return YES then the event was handled by the
 | 
			
		||||
// sign-in object (typically by closing the window) and should be ignored by
 | 
			
		||||
// the window controller's web view
 | 
			
		||||
 | 
			
		||||
- (BOOL)requestRedirectedToRequest:(NSURLRequest *)redirectedRequest;
 | 
			
		||||
- (BOOL)titleChanged:(NSString *)title;
 | 
			
		||||
- (BOOL)cookiesChanged:(NSHTTPCookieStorage *)cookieStorage;
 | 
			
		||||
- (BOOL)loadFailedWithError:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
// Window controllers must tell the sign-in object if the window was closed
 | 
			
		||||
// prematurely by the user (but not by the sign-in object); this calls the
 | 
			
		||||
// delegate's finishedSelector
 | 
			
		||||
- (void)windowWasClosed;
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
// Revocation of an authorized token from Google
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
// Standard authentication values
 | 
			
		||||
+ (NSString *)nativeClientRedirectURI;
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (NSURL *)googleAuthorizationURL;
 | 
			
		||||
+ (NSURL *)googleTokenURL;
 | 
			
		||||
+ (NSURL *)googleUserInfoURL;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
							
								
								
									
										814
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2SignIn.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,814 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
 | 
			
		||||
#define GTMOAUTH2SIGNIN_DEFINE_GLOBALS 1
 | 
			
		||||
#import "GTMOAuth2SignIn.h"
 | 
			
		||||
 | 
			
		||||
// we'll default to timing out if the network becomes unreachable for more
 | 
			
		||||
// than 30 seconds when the sign-in page is displayed
 | 
			
		||||
static const NSTimeInterval kDefaultNetworkLossTimeoutInterval = 30.0;
 | 
			
		||||
 | 
			
		||||
// URI indicating an installed app is signing in. This is described at
 | 
			
		||||
//
 | 
			
		||||
// http://code.google.com/apis/accounts/docs/OAuth2.html#IA
 | 
			
		||||
//
 | 
			
		||||
NSString *const kOOBString = @"urn:ietf:wg:oauth:2.0:oob";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2Authentication (InternalMethods)
 | 
			
		||||
- (NSDictionary *)dictionaryWithJSONData:(NSData *)data;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2SignIn ()
 | 
			
		||||
@property (assign) BOOL hasHandledCallback;
 | 
			
		||||
@property (retain) GTMHTTPFetcher *pendingFetcher;
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
@property (nonatomic, retain, readwrite) NSDictionary *userProfile;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
- (void)invokeFinalCallbackWithError:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
- (BOOL)startWebRequest;
 | 
			
		||||
+ (NSMutableURLRequest *)mutableURLRequestWithURL:(NSURL *)oldURL
 | 
			
		||||
                                      paramString:(NSString *)paramStr;
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
- (void)fetchGoogleUserInfo;
 | 
			
		||||
#endif
 | 
			
		||||
- (void)finishSignInWithError:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
- (void)handleCallbackReached;
 | 
			
		||||
 | 
			
		||||
- (void)auth:(GTMOAuth2Authentication *)auth
 | 
			
		||||
finishedWithFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
       error:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
- (void)infoFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
   finishedWithData:(NSData *)data
 | 
			
		||||
              error:(NSError *)error;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
- (void)closeTheWindow;
 | 
			
		||||
 | 
			
		||||
- (void)startReachabilityCheck;
 | 
			
		||||
- (void)stopReachabilityCheck;
 | 
			
		||||
- (void)reachabilityTarget:(SCNetworkReachabilityRef)reachabilityRef
 | 
			
		||||
              changedFlags:(SCNetworkConnectionFlags)flags;
 | 
			
		||||
- (void)reachabilityTimerFired:(NSTimer *)timer;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTMOAuth2SignIn
 | 
			
		||||
 | 
			
		||||
@synthesize authentication = auth_;
 | 
			
		||||
 | 
			
		||||
@synthesize authorizationURL = authorizationURL_;
 | 
			
		||||
@synthesize additionalAuthorizationParameters = additionalAuthorizationParameters_;
 | 
			
		||||
 | 
			
		||||
@synthesize delegate = delegate_;
 | 
			
		||||
@synthesize webRequestSelector = webRequestSelector_;
 | 
			
		||||
@synthesize finishedSelector = finishedSelector_;
 | 
			
		||||
@synthesize hasHandledCallback = hasHandledCallback_;
 | 
			
		||||
@synthesize pendingFetcher = pendingFetcher_;
 | 
			
		||||
@synthesize userData = userData_;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
@synthesize shouldFetchGoogleUserEmail = shouldFetchGoogleUserEmail_;
 | 
			
		||||
@synthesize shouldFetchGoogleUserProfile = shouldFetchGoogleUserProfile_;
 | 
			
		||||
@synthesize userProfile = userProfile_;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@synthesize networkLossTimeoutInterval = networkLossTimeoutInterval_;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (NSURL *)googleAuthorizationURL {
 | 
			
		||||
  NSString *str = @"https://accounts.google.com/o/oauth2/auth";
 | 
			
		||||
  return [NSURL URLWithString:str];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSURL *)googleTokenURL {
 | 
			
		||||
  NSString *str = @"https://accounts.google.com/o/oauth2/token";
 | 
			
		||||
  return [NSURL URLWithString:str];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSURL *)googleRevocationURL {
 | 
			
		||||
  NSString *urlStr = @"https://accounts.google.com/o/oauth2/revoke";
 | 
			
		||||
  return [NSURL URLWithString:urlStr];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSURL *)googleUserInfoURL {
 | 
			
		||||
  NSString *urlStr = @"https://www.googleapis.com/oauth2/v1/userinfo";
 | 
			
		||||
  return [NSURL URLWithString:urlStr];
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
+ (NSString *)nativeClientRedirectURI {
 | 
			
		||||
  return kOOBString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (GTMOAuth2Authentication *)standardGoogleAuthenticationForScope:(NSString *)scope
 | 
			
		||||
                                                         clientID:(NSString *)clientID
 | 
			
		||||
                                                     clientSecret:(NSString *)clientSecret {
 | 
			
		||||
  NSString *redirectURI = [self nativeClientRedirectURI];
 | 
			
		||||
  NSURL *tokenURL = [self googleTokenURL];
 | 
			
		||||
 | 
			
		||||
  GTMOAuth2Authentication *auth;
 | 
			
		||||
  auth = [GTMOAuth2Authentication authenticationWithServiceProvider:kGTMOAuth2ServiceProviderGoogle
 | 
			
		||||
                                                           tokenURL:tokenURL
 | 
			
		||||
                                                        redirectURI:redirectURI
 | 
			
		||||
                                                           clientID:clientID
 | 
			
		||||
                                                       clientSecret:clientSecret];
 | 
			
		||||
  auth.scope = scope;
 | 
			
		||||
 | 
			
		||||
  return auth;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                    delegate:(id)delegate
 | 
			
		||||
          webRequestSelector:(SEL)webRequestSelector
 | 
			
		||||
            finishedSelector:(SEL)finishedSelector {
 | 
			
		||||
  // check the selectors on debug builds
 | 
			
		||||
  GTMAssertSelectorNilOrImplementedWithArgs(delegate, webRequestSelector,
 | 
			
		||||
    @encode(GTMOAuth2SignIn *), @encode(NSURLRequest *), 0);
 | 
			
		||||
  GTMAssertSelectorNilOrImplementedWithArgs(delegate, finishedSelector,
 | 
			
		||||
    @encode(GTMOAuth2SignIn *), @encode(GTMOAuth2Authentication *),
 | 
			
		||||
    @encode(NSError *), 0);
 | 
			
		||||
 | 
			
		||||
  // designated initializer
 | 
			
		||||
  self = [super init];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    auth_ = [auth retain];
 | 
			
		||||
    authorizationURL_ = [authorizationURL retain];
 | 
			
		||||
    delegate_ = [delegate retain];
 | 
			
		||||
    webRequestSelector_ = webRequestSelector;
 | 
			
		||||
    finishedSelector_ = finishedSelector;
 | 
			
		||||
 | 
			
		||||
    // for Google authentication, we want to automatically fetch user info
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
    NSString *host = [authorizationURL host];
 | 
			
		||||
    if ([host hasSuffix:@".google.com"]) {
 | 
			
		||||
      shouldFetchGoogleUserEmail_ = YES;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // default timeout for a lost internet connection while the server
 | 
			
		||||
    // UI is displayed is 30 seconds
 | 
			
		||||
    networkLossTimeoutInterval_ = kDefaultNetworkLossTimeoutInterval;
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [self stopReachabilityCheck];
 | 
			
		||||
 | 
			
		||||
  [auth_ release];
 | 
			
		||||
  [authorizationURL_ release];
 | 
			
		||||
  [additionalAuthorizationParameters_ release];
 | 
			
		||||
  [delegate_ release];
 | 
			
		||||
  [pendingFetcher_ release];
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
  [userProfile_ release];
 | 
			
		||||
#endif
 | 
			
		||||
  [userData_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Sign-in Sequence Methods
 | 
			
		||||
 | 
			
		||||
// stop any pending fetches, and close the window (but don't call the
 | 
			
		||||
// delegate's finishedSelector)
 | 
			
		||||
- (void)cancelSigningIn {
 | 
			
		||||
  [self.pendingFetcher stopFetching];
 | 
			
		||||
  self.pendingFetcher = nil;
 | 
			
		||||
 | 
			
		||||
  [self.authentication stopAuthorization];
 | 
			
		||||
 | 
			
		||||
  [self closeTheWindow];
 | 
			
		||||
 | 
			
		||||
  [delegate_ autorelease];
 | 
			
		||||
  delegate_ = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// This is the entry point to begin the sequence
 | 
			
		||||
//  - display the authentication web page, and monitor redirects
 | 
			
		||||
//  - exchange the code for an access token and a refresh token
 | 
			
		||||
//  - for Google sign-in, fetch the user's email address
 | 
			
		||||
//  - tell the delegate we're finished
 | 
			
		||||
//
 | 
			
		||||
- (BOOL)startSigningIn {
 | 
			
		||||
  // For signing in to Google, append the scope for obtaining the authenticated
 | 
			
		||||
  // user email and profile, as appropriate
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
  GTMOAuth2Authentication *auth = self.authentication;
 | 
			
		||||
  if (self.shouldFetchGoogleUserEmail) {
 | 
			
		||||
    NSString *const emailScope = @"https://www.googleapis.com/auth/userinfo.email";
 | 
			
		||||
    NSString *scope = auth.scope;
 | 
			
		||||
    if ([scope rangeOfString:emailScope].location == NSNotFound) {
 | 
			
		||||
      scope = [GTMOAuth2Authentication scopeWithStrings:scope, emailScope, nil];
 | 
			
		||||
      auth.scope = scope;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (self.shouldFetchGoogleUserProfile) {
 | 
			
		||||
    NSString *const profileScope = @"https://www.googleapis.com/auth/userinfo.profile";
 | 
			
		||||
    NSString *scope = auth.scope;
 | 
			
		||||
    if ([scope rangeOfString:profileScope].location == NSNotFound) {
 | 
			
		||||
      scope = [GTMOAuth2Authentication scopeWithStrings:scope, profileScope, nil];
 | 
			
		||||
      auth.scope = scope;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // start the authorization
 | 
			
		||||
  return [self startWebRequest];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSMutableDictionary *)parametersForWebRequest {
 | 
			
		||||
  GTMOAuth2Authentication *auth = self.authentication;
 | 
			
		||||
  NSString *clientID = auth.clientID;
 | 
			
		||||
  NSString *redirectURI = auth.redirectURI;
 | 
			
		||||
 | 
			
		||||
  BOOL hasClientID = ([clientID length] > 0);
 | 
			
		||||
  BOOL hasRedirect = ([redirectURI length] > 0
 | 
			
		||||
                      || redirectURI == [[self class] nativeClientRedirectURI]);
 | 
			
		||||
  if (!hasClientID || !hasRedirect) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    NSAssert(hasClientID, @"GTMOAuth2SignIn: clientID needed");
 | 
			
		||||
    NSAssert(hasRedirect, @"GTMOAuth2SignIn: redirectURI needed");
 | 
			
		||||
#endif
 | 
			
		||||
    return NO;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // invoke the UI controller's web request selector to display
 | 
			
		||||
  // the authorization page
 | 
			
		||||
 | 
			
		||||
  // add params to the authorization URL
 | 
			
		||||
  NSString *scope = auth.scope;
 | 
			
		||||
  if ([scope length] == 0) scope = nil;
 | 
			
		||||
 | 
			
		||||
  NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                                     @"code", @"response_type",
 | 
			
		||||
                                     clientID, @"client_id",
 | 
			
		||||
                                     scope, @"scope", // scope may be nil
 | 
			
		||||
                                     nil];
 | 
			
		||||
  if (redirectURI) {
 | 
			
		||||
    [paramsDict setObject:redirectURI forKey:@"redirect_uri"];
 | 
			
		||||
  }
 | 
			
		||||
  return paramsDict;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)startWebRequest {
 | 
			
		||||
  NSMutableDictionary *paramsDict = [self parametersForWebRequest];
 | 
			
		||||
 | 
			
		||||
  NSDictionary *additionalParams = self.additionalAuthorizationParameters;
 | 
			
		||||
  if (additionalParams) {
 | 
			
		||||
    [paramsDict addEntriesFromDictionary:additionalParams];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *paramStr = [GTMOAuth2Authentication encodedQueryParametersForDictionary:paramsDict];
 | 
			
		||||
 | 
			
		||||
  NSURL *authorizationURL = self.authorizationURL;
 | 
			
		||||
  NSMutableURLRequest *request;
 | 
			
		||||
  request = [[self class] mutableURLRequestWithURL:authorizationURL
 | 
			
		||||
                                       paramString:paramStr];
 | 
			
		||||
 | 
			
		||||
  [delegate_ performSelector:self.webRequestSelector
 | 
			
		||||
                  withObject:self
 | 
			
		||||
                  withObject:request];
 | 
			
		||||
 | 
			
		||||
  // at this point, we're waiting on the server-driven html UI, so
 | 
			
		||||
  // we want notification if we lose connectivity to the web server
 | 
			
		||||
  [self startReachabilityCheck];
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// utility for making a request from an old URL with some additional parameters
 | 
			
		||||
+ (NSMutableURLRequest *)mutableURLRequestWithURL:(NSURL *)oldURL
 | 
			
		||||
                                      paramString:(NSString *)paramStr {
 | 
			
		||||
  NSString *query = [oldURL query];
 | 
			
		||||
  if ([query length] > 0) {
 | 
			
		||||
    query = [query stringByAppendingFormat:@"&%@", paramStr];
 | 
			
		||||
  } else {
 | 
			
		||||
    query = paramStr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *portStr = @"";
 | 
			
		||||
  NSString *oldPort = [[oldURL port] stringValue];
 | 
			
		||||
  if ([oldPort length] > 0) {
 | 
			
		||||
    portStr = [@":" stringByAppendingString:oldPort];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  NSString *qMark = [query length] > 0 ? @"?" : @"";
 | 
			
		||||
  NSString *newURLStr = [NSString stringWithFormat:@"%@://%@%@%@%@%@",
 | 
			
		||||
                         [oldURL scheme], [oldURL host], portStr,
 | 
			
		||||
                         [oldURL path], qMark, query];
 | 
			
		||||
  NSURL *newURL = [NSURL URLWithString:newURLStr];
 | 
			
		||||
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:newURL];
 | 
			
		||||
  return request;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// entry point for the window controller to tell us that the window
 | 
			
		||||
// prematurely closed
 | 
			
		||||
- (void)windowWasClosed {
 | 
			
		||||
  [self stopReachabilityCheck];
 | 
			
		||||
 | 
			
		||||
  NSError *error = [NSError errorWithDomain:kGTMOAuth2ErrorDomain
 | 
			
		||||
                                       code:kGTMOAuth2ErrorWindowClosed
 | 
			
		||||
                                   userInfo:nil];
 | 
			
		||||
  [self invokeFinalCallbackWithError:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// internal method to tell the window controller to close the window
 | 
			
		||||
- (void)closeTheWindow {
 | 
			
		||||
  [self stopReachabilityCheck];
 | 
			
		||||
 | 
			
		||||
  // a nil request means the window should be closed
 | 
			
		||||
  [delegate_ performSelector:self.webRequestSelector
 | 
			
		||||
                  withObject:self
 | 
			
		||||
                  withObject:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// entry point for the window controller to tell us what web page has been
 | 
			
		||||
// requested
 | 
			
		||||
//
 | 
			
		||||
// When the request is for the callback URL, this method invokes
 | 
			
		||||
// handleCallbackReached and returns YES
 | 
			
		||||
- (BOOL)requestRedirectedToRequest:(NSURLRequest *)redirectedRequest {
 | 
			
		||||
  // for Google's installed app sign-in protocol, we'll look for the
 | 
			
		||||
  // end-of-sign-in indicator in the titleChanged: method below
 | 
			
		||||
  NSString *redirectURI = self.authentication.redirectURI;
 | 
			
		||||
  if (redirectURI == nil) return NO;
 | 
			
		||||
 | 
			
		||||
  // when we're searching for the window title string, then we can ignore
 | 
			
		||||
  // redirects
 | 
			
		||||
  NSString *standardURI = [[self class] nativeClientRedirectURI];
 | 
			
		||||
  if (standardURI != nil && [redirectURI isEqual:standardURI]) return NO;
 | 
			
		||||
 | 
			
		||||
  // compare the redirectURI, which tells us when the web sign-in is done,
 | 
			
		||||
  // to the actual redirection
 | 
			
		||||
  NSURL *redirectURL = [NSURL URLWithString:redirectURI];
 | 
			
		||||
  NSURL *requestURL = [redirectedRequest URL];
 | 
			
		||||
 | 
			
		||||
  // avoid comparing to nil host and path values (such as when redirected to
 | 
			
		||||
  // "about:blank")
 | 
			
		||||
  NSString *requestHost = [requestURL host];
 | 
			
		||||
  NSString *requestPath = [requestURL path];
 | 
			
		||||
  BOOL isCallback;
 | 
			
		||||
  if (requestHost && requestPath) {
 | 
			
		||||
    isCallback = [[redirectURL host] isEqual:[requestURL host]]
 | 
			
		||||
                 && [[redirectURL path] isEqual:[requestURL path]];
 | 
			
		||||
  } else if (requestURL) {
 | 
			
		||||
    // handle "about:blank"
 | 
			
		||||
    isCallback = [redirectURL isEqual:requestURL];
 | 
			
		||||
  } else {
 | 
			
		||||
    isCallback = NO;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!isCallback) {
 | 
			
		||||
    // tell the caller that this request is nothing interesting
 | 
			
		||||
    return NO;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // we've reached the callback URL
 | 
			
		||||
 | 
			
		||||
  // try to get the access code
 | 
			
		||||
  if (!self.hasHandledCallback) {
 | 
			
		||||
    NSString *responseStr = [[redirectedRequest URL] query];
 | 
			
		||||
    [self.authentication setKeysForResponseString:responseStr];
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    NSAssert([self.authentication.code length] > 0
 | 
			
		||||
             || [self.authentication.errorString length] > 0,
 | 
			
		||||
             @"response lacks auth code or error");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    [self handleCallbackReached];
 | 
			
		||||
  }
 | 
			
		||||
  // tell the delegate that we did handle this request
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// entry point for the window controller to tell us when a new page title has
 | 
			
		||||
// been loadded
 | 
			
		||||
//
 | 
			
		||||
// When the title indicates sign-in has completed, this method invokes
 | 
			
		||||
// handleCallbackReached and returns YES
 | 
			
		||||
- (BOOL)titleChanged:(NSString *)title {
 | 
			
		||||
  // return YES if the OAuth flow ending title was detected
 | 
			
		||||
 | 
			
		||||
  // right now we're just looking for a parameter list following the last space
 | 
			
		||||
  // in the title string, but hopefully we'll eventually get something better
 | 
			
		||||
  // from the server to search for
 | 
			
		||||
  NSRange paramsRange = [title rangeOfString:@" "
 | 
			
		||||
                                     options:NSBackwardsSearch];
 | 
			
		||||
  NSUInteger spaceIndex = paramsRange.location;
 | 
			
		||||
  if (spaceIndex != NSNotFound) {
 | 
			
		||||
    NSString *responseStr = [title substringFromIndex:(spaceIndex + 1)];
 | 
			
		||||
 | 
			
		||||
    NSDictionary *dict = [GTMOAuth2Authentication dictionaryWithResponseString:responseStr];
 | 
			
		||||
 | 
			
		||||
    NSString *code = [dict objectForKey:@"code"];
 | 
			
		||||
    NSString *error = [dict objectForKey:@"error"];
 | 
			
		||||
    if ([code length] > 0 || [error length] > 0) {
 | 
			
		||||
 | 
			
		||||
      if (!self.hasHandledCallback) {
 | 
			
		||||
        [self.authentication setKeysForResponseDictionary:dict];
 | 
			
		||||
 | 
			
		||||
        [self handleCallbackReached];
 | 
			
		||||
      }
 | 
			
		||||
      return YES;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)cookiesChanged:(NSHTTPCookieStorage *)cookieStorage {
 | 
			
		||||
  // We're ignoring these.
 | 
			
		||||
  return NO;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// entry point for the window controller to tell us when a load has failed
 | 
			
		||||
// in the webview
 | 
			
		||||
//
 | 
			
		||||
// if the initial authorization URL fails, bail out so the user doesn't
 | 
			
		||||
// see an empty webview
 | 
			
		||||
- (BOOL)loadFailedWithError:(NSError *)error {
 | 
			
		||||
  NSURL *authorizationURL = self.authorizationURL;
 | 
			
		||||
  NSURL *failedURL = [[error userInfo] valueForKey:@"NSErrorFailingURLKey"]; // NSURLErrorFailingURLErrorKey defined in 10.6
 | 
			
		||||
 | 
			
		||||
  BOOL isAuthURL = [[failedURL host] isEqual:[authorizationURL host]]
 | 
			
		||||
    && [[failedURL path] isEqual:[authorizationURL path]];
 | 
			
		||||
 | 
			
		||||
  if (isAuthURL) {
 | 
			
		||||
    // We can assume that we have no pending fetchers, since we only
 | 
			
		||||
    // handle failure to load the initial authorization URL
 | 
			
		||||
    [self closeTheWindow];
 | 
			
		||||
    [self invokeFinalCallbackWithError:error];
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)handleCallbackReached {
 | 
			
		||||
  // the callback page was requested, or the authenticate code was loaded
 | 
			
		||||
  // into a page's title, so exchange the auth code for access & refresh tokens
 | 
			
		||||
  // and tell the window to close
 | 
			
		||||
 | 
			
		||||
  // avoid duplicate signals that the callback point has been reached
 | 
			
		||||
  self.hasHandledCallback = YES;
 | 
			
		||||
 | 
			
		||||
  [self closeTheWindow];
 | 
			
		||||
 | 
			
		||||
  NSError *error = nil;
 | 
			
		||||
 | 
			
		||||
  GTMOAuth2Authentication *auth = self.authentication;
 | 
			
		||||
  NSString *code = auth.code;
 | 
			
		||||
  if ([code length] > 0) {
 | 
			
		||||
    // exchange the code for a token
 | 
			
		||||
    SEL sel = @selector(auth:finishedWithFetcher:error:);
 | 
			
		||||
    GTMHTTPFetcher *fetcher = [auth beginTokenFetchWithDelegate:self
 | 
			
		||||
                                              didFinishSelector:sel];
 | 
			
		||||
    if (fetcher == nil) {
 | 
			
		||||
      error = [NSError errorWithDomain:kGTMHTTPFetcherStatusDomain
 | 
			
		||||
                                  code:-1
 | 
			
		||||
                              userInfo:nil];
 | 
			
		||||
    } else {
 | 
			
		||||
      self.pendingFetcher = fetcher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // notify the app so it can put up a post-sign in, pre-token exchange UI
 | 
			
		||||
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 | 
			
		||||
    [nc postNotificationName:kGTMOAuth2UserSignedIn
 | 
			
		||||
                      object:self
 | 
			
		||||
                    userInfo:nil];
 | 
			
		||||
  } else {
 | 
			
		||||
    // the callback lacked an auth code
 | 
			
		||||
    NSString *errStr = auth.errorString;
 | 
			
		||||
    NSDictionary *userInfo = nil;
 | 
			
		||||
    if ([errStr length] > 0) {
 | 
			
		||||
      userInfo = [NSDictionary dictionaryWithObject:errStr
 | 
			
		||||
                                             forKey:kGTMOAuth2ErrorMessageKey];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    error = [NSError errorWithDomain:kGTMOAuth2ErrorDomain
 | 
			
		||||
                                code:kGTMOAuth2ErrorAuthorizationFailed
 | 
			
		||||
                            userInfo:userInfo];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (error) {
 | 
			
		||||
    [self finishSignInWithError:error];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)auth:(GTMOAuth2Authentication *)auth
 | 
			
		||||
finishedWithFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
       error:(NSError *)error {
 | 
			
		||||
  self.pendingFetcher = nil;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
  if (error == nil
 | 
			
		||||
      && (self.shouldFetchGoogleUserEmail || self.shouldFetchGoogleUserProfile)
 | 
			
		||||
      && [self.authentication.serviceProvider isEqual:kGTMOAuth2ServiceProviderGoogle]) {
 | 
			
		||||
    // fetch the user's information from the Google server
 | 
			
		||||
    [self fetchGoogleUserInfo];
 | 
			
		||||
  } else {
 | 
			
		||||
    // we're not authorizing with Google, so we're done
 | 
			
		||||
    [self finishSignInWithError:error];
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  [self finishSignInWithError:error];
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
- (void)fetchGoogleUserInfo {
 | 
			
		||||
  // fetch the user's email address
 | 
			
		||||
  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) {
 | 
			
		||||
    fetcher = [fetcherService fetcherWithRequest:request];
 | 
			
		||||
  } else {
 | 
			
		||||
    fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
 | 
			
		||||
  }
 | 
			
		||||
  fetcher.retryEnabled = YES;
 | 
			
		||||
  fetcher.maxRetryInterval = 15.0;
 | 
			
		||||
  fetcher.comment = @"user info";
 | 
			
		||||
 | 
			
		||||
  [fetcher beginFetchWithDelegate:self
 | 
			
		||||
                didFinishSelector:@selector(infoFetcher:finishedWithData:error:)];
 | 
			
		||||
 | 
			
		||||
  self.pendingFetcher = fetcher;
 | 
			
		||||
 | 
			
		||||
  [auth notifyFetchIsRunning:YES
 | 
			
		||||
                     fetcher:fetcher
 | 
			
		||||
                        type:kGTMOAuth2FetchTypeUserInfo];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)infoFetcher:(GTMHTTPFetcher *)fetcher
 | 
			
		||||
   finishedWithData:(NSData *)data
 | 
			
		||||
              error:(NSError *)error {
 | 
			
		||||
  GTMOAuth2Authentication *auth = self.authentication;
 | 
			
		||||
  [auth notifyFetchIsRunning:NO
 | 
			
		||||
                     fetcher:fetcher
 | 
			
		||||
                        type:nil];
 | 
			
		||||
 | 
			
		||||
  self.pendingFetcher = nil;
 | 
			
		||||
 | 
			
		||||
  if (error) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    if (data) {
 | 
			
		||||
      NSString *dataStr = [[[NSString alloc] initWithData:data
 | 
			
		||||
                                                 encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
      NSLog(@"infoFetcher error: %@\n%@", error, dataStr);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  } else {
 | 
			
		||||
    // We have the authenticated user's info
 | 
			
		||||
    if (data) {
 | 
			
		||||
      NSDictionary *profileDict = [auth dictionaryWithJSONData:data];
 | 
			
		||||
      if (profileDict) {
 | 
			
		||||
        self.userProfile = profileDict;
 | 
			
		||||
 | 
			
		||||
        // Save the email into the auth object
 | 
			
		||||
        NSString *email = [profileDict objectForKey:@"email"];
 | 
			
		||||
        [auth setUserEmail:email];
 | 
			
		||||
 | 
			
		||||
        NSNumber *verified = [profileDict objectForKey:@"verified_email"];
 | 
			
		||||
        [auth setUserEmailIsVerified:[verified stringValue]];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  [self finishSignInWithError:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
 | 
			
		||||
- (void)finishSignInWithError:(NSError *)error {
 | 
			
		||||
  [self invokeFinalCallbackWithError:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// convenience method for making the final call to our delegate
 | 
			
		||||
- (void)invokeFinalCallbackWithError:(NSError *)error {
 | 
			
		||||
  if (delegate_ && finishedSelector_) {
 | 
			
		||||
    GTMOAuth2Authentication *auth = self.authentication;
 | 
			
		||||
 | 
			
		||||
    NSMethodSignature *sig = [delegate_ methodSignatureForSelector:finishedSelector_];
 | 
			
		||||
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
 | 
			
		||||
    [invocation setSelector:finishedSelector_];
 | 
			
		||||
    [invocation setTarget:delegate_];
 | 
			
		||||
    [invocation setArgument:&self atIndex:2];
 | 
			
		||||
    [invocation setArgument:&auth atIndex:3];
 | 
			
		||||
    [invocation setArgument:&error atIndex:4];
 | 
			
		||||
    [invocation invoke];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // we'll no longer send messages to the delegate
 | 
			
		||||
  //
 | 
			
		||||
  // we want to autorelease it rather than assign to the property in case
 | 
			
		||||
  // the delegate is below us in the call stack
 | 
			
		||||
  [delegate_ autorelease];
 | 
			
		||||
  delegate_ = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Reachability monitoring
 | 
			
		||||
 | 
			
		||||
static void ReachabilityCallBack(SCNetworkReachabilityRef target,
 | 
			
		||||
                                 SCNetworkConnectionFlags flags,
 | 
			
		||||
                                 void *info) {
 | 
			
		||||
  // pass the flags to the signIn object
 | 
			
		||||
  GTMOAuth2SignIn *signIn = (GTMOAuth2SignIn *)info;
 | 
			
		||||
 | 
			
		||||
  [signIn reachabilityTarget:target
 | 
			
		||||
                changedFlags:flags];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)startReachabilityCheck {
 | 
			
		||||
  // the user may set the timeout to 0 to skip the reachability checking
 | 
			
		||||
  // during display of the sign-in page
 | 
			
		||||
  if (networkLossTimeoutInterval_ <= 0.0 || reachabilityRef_ != NULL) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // create a reachability target from the authorization URL, add our callback,
 | 
			
		||||
  // and schedule it on the run loop so we'll be notified if the network drops
 | 
			
		||||
  NSURL *url = self.authorizationURL;
 | 
			
		||||
  const char* host = [[url host] UTF8String];
 | 
			
		||||
  reachabilityRef_ = SCNetworkReachabilityCreateWithName(kCFAllocatorSystemDefault,
 | 
			
		||||
                                                         host);
 | 
			
		||||
  if (reachabilityRef_) {
 | 
			
		||||
    BOOL isScheduled = NO;
 | 
			
		||||
    SCNetworkReachabilityContext ctx = { 0, self, NULL, NULL, NULL };
 | 
			
		||||
 | 
			
		||||
    if (SCNetworkReachabilitySetCallback(reachabilityRef_,
 | 
			
		||||
                                         ReachabilityCallBack, &ctx)) {
 | 
			
		||||
      if (SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef_,
 | 
			
		||||
                                                   CFRunLoopGetCurrent(),
 | 
			
		||||
                                                   kCFRunLoopDefaultMode)) {
 | 
			
		||||
        isScheduled = YES;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!isScheduled) {
 | 
			
		||||
      CFRelease(reachabilityRef_);
 | 
			
		||||
      reachabilityRef_ = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)destroyUnreachabilityTimer {
 | 
			
		||||
  [networkLossTimer_ invalidate];
 | 
			
		||||
  [networkLossTimer_ autorelease];
 | 
			
		||||
  networkLossTimer_ = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)reachabilityTarget:(SCNetworkReachabilityRef)reachabilityRef
 | 
			
		||||
              changedFlags:(SCNetworkConnectionFlags)flags {
 | 
			
		||||
  BOOL isConnected = (flags & kSCNetworkFlagsReachable) != 0
 | 
			
		||||
    && (flags & kSCNetworkFlagsConnectionRequired) == 0;
 | 
			
		||||
 | 
			
		||||
  if (isConnected) {
 | 
			
		||||
    // server is again reachable
 | 
			
		||||
    [self destroyUnreachabilityTimer];
 | 
			
		||||
 | 
			
		||||
    if (hasNotifiedNetworkLoss_) {
 | 
			
		||||
      // tell the user that the network has been found
 | 
			
		||||
      NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 | 
			
		||||
      [nc postNotificationName:kGTMOAuth2NetworkFound
 | 
			
		||||
                        object:self
 | 
			
		||||
                      userInfo:nil];
 | 
			
		||||
      hasNotifiedNetworkLoss_ = NO;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    // the server has become unreachable; start the timer, if necessary
 | 
			
		||||
    if (networkLossTimer_ == nil
 | 
			
		||||
        && networkLossTimeoutInterval_ > 0
 | 
			
		||||
        && !hasNotifiedNetworkLoss_) {
 | 
			
		||||
      SEL sel = @selector(reachabilityTimerFired:);
 | 
			
		||||
      networkLossTimer_ = [[NSTimer scheduledTimerWithTimeInterval:networkLossTimeoutInterval_
 | 
			
		||||
                                                            target:self
 | 
			
		||||
                                                          selector:sel
 | 
			
		||||
                                                          userInfo:nil
 | 
			
		||||
                                                           repeats:NO] retain];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)reachabilityTimerFired:(NSTimer *)timer {
 | 
			
		||||
  // the user may call [[notification object] cancelSigningIn] to
 | 
			
		||||
  // dismiss the sign-in
 | 
			
		||||
  if (!hasNotifiedNetworkLoss_) {
 | 
			
		||||
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 | 
			
		||||
    [nc postNotificationName:kGTMOAuth2NetworkLost
 | 
			
		||||
                      object:self
 | 
			
		||||
                    userInfo:nil];
 | 
			
		||||
    hasNotifiedNetworkLoss_ = YES;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [self destroyUnreachabilityTimer];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)stopReachabilityCheck {
 | 
			
		||||
  [self destroyUnreachabilityTimer];
 | 
			
		||||
 | 
			
		||||
  if (reachabilityRef_) {
 | 
			
		||||
    SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef_,
 | 
			
		||||
                                               CFRunLoopGetCurrent(),
 | 
			
		||||
                                               kCFRunLoopDefaultMode);
 | 
			
		||||
    SCNetworkReachabilitySetCallback(reachabilityRef_, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    CFRelease(reachabilityRef_);
 | 
			
		||||
    reachabilityRef_ = NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Token Revocation
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth {
 | 
			
		||||
  if (auth.canAuthorize
 | 
			
		||||
      && [auth.serviceProvider isEqual:kGTMOAuth2ServiceProviderGoogle]) {
 | 
			
		||||
 | 
			
		||||
    // create a signed revocation request for this authentication object
 | 
			
		||||
    NSURL *url = [self googleRevocationURL];
 | 
			
		||||
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 | 
			
		||||
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 | 
			
		||||
 | 
			
		||||
    NSString *token = auth.refreshToken;
 | 
			
		||||
    NSString *encoded = [GTMOAuth2Authentication encodedOAuthValueForString:token];
 | 
			
		||||
    NSString *body = [@"token=" stringByAppendingString:encoded];
 | 
			
		||||
 | 
			
		||||
    [request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
    [request setHTTPMethod:@"POST"];
 | 
			
		||||
 | 
			
		||||
    NSString *userAgent = [auth userAgent];
 | 
			
		||||
    [request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
 | 
			
		||||
 | 
			
		||||
    // there's nothing to be done if revocation succeeds or fails
 | 
			
		||||
    GTMHTTPFetcher *fetcher;
 | 
			
		||||
    id <GTMHTTPFetcherServiceProtocol> fetcherService = auth.fetcherService;
 | 
			
		||||
    if (fetcherService) {
 | 
			
		||||
      fetcher = [fetcherService fetcherWithRequest:request];
 | 
			
		||||
    } else {
 | 
			
		||||
      fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
 | 
			
		||||
    }
 | 
			
		||||
    fetcher.comment = @"revoke token";
 | 
			
		||||
 | 
			
		||||
    // Use a completion handler fetch for better debugging, but only if we're
 | 
			
		||||
    // guaranteed that blocks are available in the runtime
 | 
			
		||||
#if (!TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)) || \
 | 
			
		||||
    (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
 | 
			
		||||
    // Blocks are available
 | 
			
		||||
    [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
 | 
			
		||||
  #if DEBUG
 | 
			
		||||
      if (error) {
 | 
			
		||||
        NSString *errStr = [[[NSString alloc] initWithData:data
 | 
			
		||||
                                                  encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
        NSLog(@"revoke error: %@", errStr);
 | 
			
		||||
      }
 | 
			
		||||
  #endif // DEBUG
 | 
			
		||||
    }];
 | 
			
		||||
#else
 | 
			
		||||
    // Blocks may not be available
 | 
			
		||||
    [fetcher beginFetchWithDelegate:nil didFinishSelector:NULL];
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [auth reset];
 | 
			
		||||
}
 | 
			
		||||
#endif // !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
							
								
								
									
										344
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,344 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMOAuth2ViewControllerTouch.h
 | 
			
		||||
//
 | 
			
		||||
// This view controller for iPhone handles sign-in via OAuth to Google or
 | 
			
		||||
// other services.
 | 
			
		||||
//
 | 
			
		||||
// This controller is not reusable; create a new instance of this controller
 | 
			
		||||
// every time the user will sign in.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE
 | 
			
		||||
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
 | 
			
		||||
#import "GTMOAuth2Authentication.h"
 | 
			
		||||
 | 
			
		||||
#undef _EXTERN
 | 
			
		||||
#undef _INITIALIZE_AS
 | 
			
		||||
#ifdef GTMOAUTH2VIEWCONTROLLERTOUCH_DEFINE_GLOBALS
 | 
			
		||||
#define _EXTERN
 | 
			
		||||
#define _INITIALIZE_AS(x) =x
 | 
			
		||||
#else
 | 
			
		||||
#define _EXTERN extern
 | 
			
		||||
#define _INITIALIZE_AS(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
_EXTERN NSString* const kGTMOAuth2KeychainErrorDomain       _INITIALIZE_AS(@"com.google.GTMOAuthKeychain");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@class GTMOAuth2SignIn;
 | 
			
		||||
@class GTMOAuth2ViewControllerTouch;
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2ViewControllerTouch : UIViewController<UINavigationControllerDelegate, UIWebViewDelegate> {
 | 
			
		||||
 @private
 | 
			
		||||
  UIButton *backButton_;
 | 
			
		||||
  UIButton *forwardButton_;
 | 
			
		||||
  UIView *navButtonsView_;
 | 
			
		||||
  UIBarButtonItem *rightBarButtonItem_;
 | 
			
		||||
  UIWebView *webView_;
 | 
			
		||||
 | 
			
		||||
  // The object responsible for the sign-in networking sequence; it holds
 | 
			
		||||
  // onto the authentication object as well.
 | 
			
		||||
  GTMOAuth2SignIn *signIn_;
 | 
			
		||||
 | 
			
		||||
  // the page request to load when awakeFromNib occurs
 | 
			
		||||
  NSURLRequest *request_;
 | 
			
		||||
 | 
			
		||||
  // The user we're calling back
 | 
			
		||||
  //
 | 
			
		||||
  // The delegate is retained only until the callback is invoked
 | 
			
		||||
  // or the sign-in is canceled
 | 
			
		||||
  id delegate_;
 | 
			
		||||
  SEL finishedSelector_;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  void (^completionBlock_)(GTMOAuth2ViewControllerTouch *, GTMOAuth2Authentication *, NSError *);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  NSString *keychainItemName_;
 | 
			
		||||
  CFTypeRef keychainItemAccessibility_;
 | 
			
		||||
 | 
			
		||||
  // if non-nil, the html string to be displayed immediately upon opening
 | 
			
		||||
  // of the web view
 | 
			
		||||
  NSString *initialHTMLString_;
 | 
			
		||||
 | 
			
		||||
  // if non-nil, the URL for which cookies will be deleted when the
 | 
			
		||||
  // browser view is dismissed
 | 
			
		||||
  NSURL *browserCookiesURL_;
 | 
			
		||||
 | 
			
		||||
  id userData_;
 | 
			
		||||
  NSMutableDictionary *properties_;
 | 
			
		||||
 | 
			
		||||
  // 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_;
 | 
			
		||||
 | 
			
		||||
  // YES, when view first shown in this signIn session.
 | 
			
		||||
  BOOL isViewShown_;
 | 
			
		||||
 | 
			
		||||
  // YES, after the view has fully transitioned in.
 | 
			
		||||
  BOOL didViewAppear_;
 | 
			
		||||
 | 
			
		||||
  // YES between sends of start and stop notifications
 | 
			
		||||
  BOOL hasNotifiedWebViewStartedLoading_;
 | 
			
		||||
 | 
			
		||||
  // To prevent us from calling our delegate's selector more than once.
 | 
			
		||||
  BOOL hasCalledFinished_;
 | 
			
		||||
 | 
			
		||||
  // Set in a webView callback.
 | 
			
		||||
  BOOL hasDoneFinalRedirect_;
 | 
			
		||||
 | 
			
		||||
  // Set during the pop initiated by the sign-in object; otherwise,
 | 
			
		||||
  // viewWillDisappear indicates that some external change of the view
 | 
			
		||||
  // has stopped the sign-in.
 | 
			
		||||
  BOOL didDismissSelf_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// the application and service name to use for saving the auth tokens
 | 
			
		||||
// to the keychain
 | 
			
		||||
@property (nonatomic, copy) NSString *keychainItemName;
 | 
			
		||||
 | 
			
		||||
// the keychain item accessibility is a system constant for use
 | 
			
		||||
// with kSecAttrAccessible.
 | 
			
		||||
//
 | 
			
		||||
// Since it's a system constant, we do not need to retain it.
 | 
			
		||||
@property (nonatomic, assign) CFTypeRef keychainItemAccessibility;
 | 
			
		||||
 | 
			
		||||
// optional html string displayed immediately upon opening the web view
 | 
			
		||||
//
 | 
			
		||||
// This string is visible just until the sign-in web page loads, and
 | 
			
		||||
// may be used for a "Loading..." type of message or to set the
 | 
			
		||||
// initial view color
 | 
			
		||||
@property (nonatomic, copy) NSString *initialHTMLString;
 | 
			
		||||
 | 
			
		||||
// the underlying object to hold authentication tokens and authorize http
 | 
			
		||||
// requests
 | 
			
		||||
@property (nonatomic, retain, readonly) GTMOAuth2Authentication *authentication;
 | 
			
		||||
 | 
			
		||||
// the underlying object which performs the sign-in networking sequence
 | 
			
		||||
@property (nonatomic, retain, readonly) GTMOAuth2SignIn *signIn;
 | 
			
		||||
 | 
			
		||||
// user interface elements
 | 
			
		||||
@property (nonatomic, retain) IBOutlet UIButton *backButton;
 | 
			
		||||
@property (nonatomic, retain) IBOutlet UIButton *forwardButton;
 | 
			
		||||
@property (nonatomic, retain) IBOutlet UIView *navButtonsView;
 | 
			
		||||
@property (nonatomic, retain) IBOutlet UIBarButtonItem *rightBarButtonItem;
 | 
			
		||||
@property (nonatomic, retain) IBOutlet UIWebView *webView;
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
// if set, cookies are deleted for this URL when the view is hidden
 | 
			
		||||
//
 | 
			
		||||
// For Google sign-ins, this is set by default to https://google.com/accounts
 | 
			
		||||
// but it may be explicitly set to nil to disable clearing of browser cookies
 | 
			
		||||
@property (nonatomic, retain) NSURL *browserCookiesURL;
 | 
			
		||||
 | 
			
		||||
// userData is retained for the convenience of the caller
 | 
			
		||||
@property (nonatomic, retain) id userData;
 | 
			
		||||
 | 
			
		||||
// Stored property values are retained for the convenience of the caller
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key;
 | 
			
		||||
- (id)propertyForKey:(NSString *)key;
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, retain) NSDictionary *properties;
 | 
			
		||||
 | 
			
		||||
// Method for creating a controller to authenticate to Google services
 | 
			
		||||
//
 | 
			
		||||
// scope is the requested scope of authorization
 | 
			
		||||
//   (like "http://www.google.com/m8/feeds")
 | 
			
		||||
//
 | 
			
		||||
// keychain item name is used for storing the token on the keychain,
 | 
			
		||||
//   keychainItemName should be like "My Application: Google Latitude"
 | 
			
		||||
//   (or set to nil if no persistent keychain storage is desired)
 | 
			
		||||
//
 | 
			
		||||
// the delegate is retained only until the finished selector is invoked
 | 
			
		||||
//   or the sign-in is canceled
 | 
			
		||||
//
 | 
			
		||||
// If you don't like the default nibName and bundle, you can change them
 | 
			
		||||
// using the UIViewController properties once you've made one of these.
 | 
			
		||||
//
 | 
			
		||||
// finishedSelector is called after authentication completes. It should follow
 | 
			
		||||
// this signature.
 | 
			
		||||
//
 | 
			
		||||
// - (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
 | 
			
		||||
//       finishedWithAuth:(GTMOAuth2Authentication *)auth
 | 
			
		||||
//                  error:(NSError *)error;
 | 
			
		||||
//
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (id)controllerWithScope:(NSString *)scope
 | 
			
		||||
                 clientID:(NSString *)clientID
 | 
			
		||||
             clientSecret:(NSString *)clientSecret
 | 
			
		||||
         keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                 delegate:(id)delegate
 | 
			
		||||
         finishedSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
- (id)initWithScope:(NSString *)scope
 | 
			
		||||
           clientID:(NSString *)clientID
 | 
			
		||||
       clientSecret:(NSString *)clientSecret
 | 
			
		||||
   keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
           delegate:(id)delegate
 | 
			
		||||
   finishedSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
+ (id)controllerWithScope:(NSString *)scope
 | 
			
		||||
                 clientID:(NSString *)clientID
 | 
			
		||||
             clientSecret:(NSString *)clientSecret
 | 
			
		||||
         keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
        completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (id)initWithScope:(NSString *)scope
 | 
			
		||||
           clientID:(NSString *)clientID
 | 
			
		||||
       clientSecret:(NSString *)clientSecret
 | 
			
		||||
   keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
  completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler;
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Create a controller for authenticating to non-Google services, taking
 | 
			
		||||
//   explicit endpoint URLs and an authentication object
 | 
			
		||||
+ (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
                  authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                  keychainItemName:(NSString *)keychainItemName  // may be nil
 | 
			
		||||
                          delegate:(id)delegate
 | 
			
		||||
                  finishedSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
// This is the designated initializer
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
            keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                    delegate:(id)delegate
 | 
			
		||||
            finishedSelector:(SEL)finishedSelector;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
+ (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
                  authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                  keychainItemName:(NSString *)keychainItemName  // may be nil
 | 
			
		||||
                 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler;
 | 
			
		||||
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
            keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
           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;
 | 
			
		||||
 | 
			
		||||
// subclasses may override authNibBundle to specify a custom bundle
 | 
			
		||||
+ (NSBundle *)authNibBundle;
 | 
			
		||||
 | 
			
		||||
// apps may replace the sign-in class with their own subclass of it
 | 
			
		||||
+ (Class)signInClass;
 | 
			
		||||
+ (void)setSignInClass:(Class)theClass;
 | 
			
		||||
 | 
			
		||||
- (void)cancelSigningIn;
 | 
			
		||||
 | 
			
		||||
// revocation of an authorized token from Google
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Keychain
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// create an authentication object for Google services from the access
 | 
			
		||||
// token and secret stored in the keychain; if no token is available, return
 | 
			
		||||
// an unauthorized auth object
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (GTMOAuth2Authentication *)authForGoogleFromKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                                                     clientID:(NSString *)clientID
 | 
			
		||||
                                                 clientSecret:(NSString *)clientSecret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// add tokens from the keychain, if available, to the authentication object
 | 
			
		||||
//
 | 
			
		||||
// returns YES if the authentication object was authorized from the keychain
 | 
			
		||||
+ (BOOL)authorizeFromKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                      authentication:(GTMOAuth2Authentication *)auth;
 | 
			
		||||
 | 
			
		||||
// method for deleting the stored access token and secret, useful for "signing
 | 
			
		||||
// out"
 | 
			
		||||
+ (BOOL)removeAuthFromKeychainForName:(NSString *)keychainItemName;
 | 
			
		||||
 | 
			
		||||
// method for saving the stored access token and secret
 | 
			
		||||
+ (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                      accessibility:(CFTypeRef)accessibility
 | 
			
		||||
                     authentication:(GTMOAuth2Authentication *)auth;
 | 
			
		||||
 | 
			
		||||
// older version, defaults to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
 | 
			
		||||
+ (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                     authentication:(GTMOAuth2Authentication *)auth;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// To function, GTMOAuth2ViewControllerTouch needs a certain amount of access
 | 
			
		||||
// to the iPhone's keychain. To keep things simple, its keychain access is
 | 
			
		||||
// broken out into a helper class. We declare it here in case you'd like to use
 | 
			
		||||
// it too, to store passwords.
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  kGTMOAuth2KeychainErrorBadArguments = -1301,
 | 
			
		||||
  kGTMOAuth2KeychainErrorNoPassword = -1302
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2Keychain : NSObject
 | 
			
		||||
 | 
			
		||||
+ (GTMOAuth2Keychain *)defaultKeychain;
 | 
			
		||||
 | 
			
		||||
// OK to pass nil for the error parameter.
 | 
			
		||||
- (NSString *)passwordForService:(NSString *)service
 | 
			
		||||
                         account:(NSString *)account
 | 
			
		||||
                           error:(NSError **)error;
 | 
			
		||||
 | 
			
		||||
// OK to pass nil for the error parameter.
 | 
			
		||||
- (BOOL)removePasswordForService:(NSString *)service
 | 
			
		||||
                         account:(NSString *)account
 | 
			
		||||
                           error:(NSError **)error;
 | 
			
		||||
 | 
			
		||||
// OK to pass nil for the error parameter.
 | 
			
		||||
//
 | 
			
		||||
// accessibility should be one of the constants for kSecAttrAccessible
 | 
			
		||||
// such as kSecAttrAccessibleWhenUnlocked
 | 
			
		||||
- (BOOL)setPassword:(NSString *)password
 | 
			
		||||
         forService:(NSString *)service
 | 
			
		||||
      accessibility:(CFTypeRef)accessibility
 | 
			
		||||
            account:(NSString *)account
 | 
			
		||||
              error:(NSError **)error;
 | 
			
		||||
 | 
			
		||||
// For unit tests: allow setting a mock object
 | 
			
		||||
+ (void)setDefaultKeychain:(GTMOAuth2Keychain *)keychain;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif // TARGET_OS_IPHONE
 | 
			
		||||
 | 
			
		||||
#endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
							
								
								
									
										970
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewControllerTouch.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,970 @@
 | 
			
		||||
/* Copyright (c) 2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GTMOAuth2ViewControllerTouch.m
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import <Security/Security.h>
 | 
			
		||||
 | 
			
		||||
#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE
 | 
			
		||||
 | 
			
		||||
#define GTMOAUTH2VIEWCONTROLLERTOUCH_DEFINE_GLOBALS 1
 | 
			
		||||
#import "GTMOAuth2ViewControllerTouch.h"
 | 
			
		||||
 | 
			
		||||
#import "GTMOAuth2SignIn.h"
 | 
			
		||||
#import "GTMOAuth2Authentication.h"
 | 
			
		||||
 | 
			
		||||
static NSString * const kGTMOAuth2AccountName = @"OAuth";
 | 
			
		||||
static GTMOAuth2Keychain* sDefaultKeychain = nil;
 | 
			
		||||
 | 
			
		||||
@interface GTMOAuth2ViewControllerTouch()
 | 
			
		||||
 | 
			
		||||
@property (nonatomic, copy) NSURLRequest *request;
 | 
			
		||||
 | 
			
		||||
- (void)signIn:(GTMOAuth2SignIn *)signIn displayRequest:(NSURLRequest *)request;
 | 
			
		||||
- (void)signIn:(GTMOAuth2SignIn *)signIn
 | 
			
		||||
finishedWithAuth:(GTMOAuth2Authentication *)auth
 | 
			
		||||
         error:(NSError *)error;
 | 
			
		||||
- (BOOL)isNavigationBarTranslucent;
 | 
			
		||||
- (void)moveWebViewFromUnderNavigationBar;
 | 
			
		||||
- (void)popView;
 | 
			
		||||
- (void)clearBrowserCookies;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GTMOAuth2ViewControllerTouch
 | 
			
		||||
 | 
			
		||||
// IBOutlets
 | 
			
		||||
@synthesize request = request_,
 | 
			
		||||
            backButton = backButton_,
 | 
			
		||||
            forwardButton = forwardButton_,
 | 
			
		||||
            navButtonsView = navButtonsView_,
 | 
			
		||||
            rightBarButtonItem = rightBarButtonItem_,
 | 
			
		||||
            webView = webView_;
 | 
			
		||||
 | 
			
		||||
@synthesize keychainItemName = keychainItemName_,
 | 
			
		||||
            keychainItemAccessibility = keychainItemAccessibility_,
 | 
			
		||||
            initialHTMLString = initialHTMLString_,
 | 
			
		||||
            browserCookiesURL = browserCookiesURL_,
 | 
			
		||||
            signIn = signIn_,
 | 
			
		||||
            userData = userData_,
 | 
			
		||||
            properties = properties_;
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (id)controllerWithScope:(NSString *)scope
 | 
			
		||||
                 clientID:(NSString *)clientID
 | 
			
		||||
             clientSecret:(NSString *)clientSecret
 | 
			
		||||
         keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                 delegate:(id)delegate
 | 
			
		||||
         finishedSelector:(SEL)finishedSelector {
 | 
			
		||||
  return [[[self alloc] initWithScope:scope
 | 
			
		||||
                             clientID:clientID
 | 
			
		||||
                         clientSecret:clientSecret
 | 
			
		||||
                     keychainItemName:keychainItemName
 | 
			
		||||
                             delegate:delegate
 | 
			
		||||
                     finishedSelector:finishedSelector] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithScope:(NSString *)scope
 | 
			
		||||
           clientID:(NSString *)clientID
 | 
			
		||||
       clientSecret:(NSString *)clientSecret
 | 
			
		||||
   keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
           delegate:(id)delegate
 | 
			
		||||
   finishedSelector:(SEL)finishedSelector {
 | 
			
		||||
  // convenient entry point for Google authentication
 | 
			
		||||
 | 
			
		||||
  Class signInClass = [[self class] signInClass];
 | 
			
		||||
 | 
			
		||||
  GTMOAuth2Authentication *auth;
 | 
			
		||||
  auth = [signInClass standardGoogleAuthenticationForScope:scope
 | 
			
		||||
                                                  clientID:clientID
 | 
			
		||||
                                              clientSecret:clientSecret];
 | 
			
		||||
  NSURL *authorizationURL = [signInClass googleAuthorizationURL];
 | 
			
		||||
  return [self initWithAuthentication:auth
 | 
			
		||||
                     authorizationURL:authorizationURL
 | 
			
		||||
                     keychainItemName:keychainItemName
 | 
			
		||||
                             delegate:delegate
 | 
			
		||||
                     finishedSelector:finishedSelector];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
 | 
			
		||||
+ (id)controllerWithScope:(NSString *)scope
 | 
			
		||||
                 clientID:(NSString *)clientID
 | 
			
		||||
             clientSecret:(NSString *)clientSecret
 | 
			
		||||
         keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
        completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler {
 | 
			
		||||
  return [[[self alloc] initWithScope:scope
 | 
			
		||||
                             clientID:clientID
 | 
			
		||||
                         clientSecret:clientSecret
 | 
			
		||||
                     keychainItemName:keychainItemName
 | 
			
		||||
                    completionHandler:handler] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithScope:(NSString *)scope
 | 
			
		||||
           clientID:(NSString *)clientID
 | 
			
		||||
       clientSecret:(NSString *)clientSecret
 | 
			
		||||
   keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
  completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler {
 | 
			
		||||
  // convenient entry point for Google authentication
 | 
			
		||||
 | 
			
		||||
  Class signInClass = [[self class] signInClass];
 | 
			
		||||
 | 
			
		||||
  GTMOAuth2Authentication *auth;
 | 
			
		||||
  auth = [signInClass standardGoogleAuthenticationForScope:scope
 | 
			
		||||
                                                  clientID:clientID
 | 
			
		||||
                                              clientSecret:clientSecret];
 | 
			
		||||
  NSURL *authorizationURL = [signInClass googleAuthorizationURL];
 | 
			
		||||
  self = [self initWithAuthentication:auth
 | 
			
		||||
                     authorizationURL:authorizationURL
 | 
			
		||||
                     keychainItemName:keychainItemName
 | 
			
		||||
                             delegate:nil
 | 
			
		||||
                     finishedSelector:NULL];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    completionBlock_ = [handler copy];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NS_BLOCKS_AVAILABLE
 | 
			
		||||
#endif // !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
 | 
			
		||||
+ (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
                  authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                  keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                          delegate:(id)delegate
 | 
			
		||||
                  finishedSelector:(SEL)finishedSelector {
 | 
			
		||||
  return [[[self alloc] initWithAuthentication:auth
 | 
			
		||||
                              authorizationURL:authorizationURL
 | 
			
		||||
                              keychainItemName:keychainItemName
 | 
			
		||||
                                      delegate:delegate
 | 
			
		||||
                              finishedSelector:finishedSelector] autorelease];  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
            keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                    delegate:(id)delegate
 | 
			
		||||
            finishedSelector:(SEL)finishedSelector {
 | 
			
		||||
 | 
			
		||||
  NSString *nibName = [[self class] authNibName];
 | 
			
		||||
  NSBundle *nibBundle = [[self class] authNibBundle];
 | 
			
		||||
 | 
			
		||||
  self = [super initWithNibName:nibName bundle:nibBundle];
 | 
			
		||||
  if (self != nil) {
 | 
			
		||||
    delegate_ = [delegate retain];
 | 
			
		||||
    finishedSelector_ = finishedSelector;
 | 
			
		||||
 | 
			
		||||
    Class signInClass = [[self class] signInClass];
 | 
			
		||||
 | 
			
		||||
    // use the supplied auth and OAuth endpoint URLs
 | 
			
		||||
    signIn_ = [[signInClass alloc] initWithAuthentication:auth
 | 
			
		||||
                                         authorizationURL:authorizationURL
 | 
			
		||||
                                                 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
 | 
			
		||||
    //
 | 
			
		||||
    // for other service domains, or to disable clearing of the cookies,
 | 
			
		||||
    // set the browserCookiesURL property explicitly
 | 
			
		||||
    NSString *authorizationHost = [signIn_.authorizationURL host];
 | 
			
		||||
    if ([authorizationHost hasSuffix:@".google.com"]) {
 | 
			
		||||
      NSString *urlStr = [NSString stringWithFormat:@"https://%@/",
 | 
			
		||||
                          authorizationHost];
 | 
			
		||||
      NSURL *cookiesURL = [NSURL URLWithString:urlStr];
 | 
			
		||||
      [self setBrowserCookiesURL:cookiesURL];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [self setKeychainItemName:keychainItemName];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
+ (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
                  authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
                  keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
                 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler {
 | 
			
		||||
  return [[[self alloc] initWithAuthentication:auth
 | 
			
		||||
                              authorizationURL:authorizationURL
 | 
			
		||||
                              keychainItemName:keychainItemName
 | 
			
		||||
                             completionHandler:handler] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
 | 
			
		||||
            authorizationURL:(NSURL *)authorizationURL
 | 
			
		||||
            keychainItemName:(NSString *)keychainItemName
 | 
			
		||||
           completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler {
 | 
			
		||||
  // fall back to the non-blocks init
 | 
			
		||||
  self = [self initWithAuthentication:auth
 | 
			
		||||
                     authorizationURL:authorizationURL
 | 
			
		||||
                     keychainItemName:keychainItemName
 | 
			
		||||
                             delegate:nil
 | 
			
		||||
                     finishedSelector:NULL];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    completionBlock_ = [handler copy];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [webView_ setDelegate:nil];
 | 
			
		||||
 | 
			
		||||
  [backButton_ release];
 | 
			
		||||
  [forwardButton_ release];
 | 
			
		||||
  [navButtonsView_ release];
 | 
			
		||||
  [rightBarButtonItem_ release];
 | 
			
		||||
  [webView_ release];
 | 
			
		||||
  [signIn_ release];
 | 
			
		||||
  [request_ release];
 | 
			
		||||
  [delegate_ release];
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  [completionBlock_ release];
 | 
			
		||||
#endif
 | 
			
		||||
  [keychainItemName_ release];
 | 
			
		||||
  [initialHTMLString_ release];
 | 
			
		||||
  [browserCookiesURL_ release];
 | 
			
		||||
  [userData_ release];
 | 
			
		||||
  [properties_ release];
 | 
			
		||||
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)authNibName {
 | 
			
		||||
  // subclasses may override this to specify a custom nib name
 | 
			
		||||
  return @"GTMOAuth2ViewTouch";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSBundle *)authNibBundle {
 | 
			
		||||
  // subclasses may override this to specify a custom nib bundle
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (GTMOAuth2Authentication *)authForGoogleFromKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                                                     clientID:(NSString *)clientID
 | 
			
		||||
                                                 clientSecret:(NSString *)clientSecret {
 | 
			
		||||
  Class signInClass = [self signInClass];
 | 
			
		||||
  NSURL *tokenURL = [signInClass googleTokenURL];
 | 
			
		||||
  NSString *redirectURI = [signInClass nativeClientRedirectURI];
 | 
			
		||||
  
 | 
			
		||||
  GTMOAuth2Authentication *auth;
 | 
			
		||||
  auth = [GTMOAuth2Authentication authenticationWithServiceProvider:kGTMOAuth2ServiceProviderGoogle
 | 
			
		||||
                                                           tokenURL:tokenURL
 | 
			
		||||
                                                        redirectURI:redirectURI
 | 
			
		||||
                                                           clientID:clientID
 | 
			
		||||
                                                       clientSecret:clientSecret];
 | 
			
		||||
  [[self class] authorizeFromKeychainForName:keychainItemName
 | 
			
		||||
                              authentication:auth];
 | 
			
		||||
  return auth;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
+ (BOOL)authorizeFromKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                      authentication:(GTMOAuth2Authentication *)newAuth {
 | 
			
		||||
  newAuth.accessToken = nil;
 | 
			
		||||
 | 
			
		||||
  BOOL didGetTokens = NO;
 | 
			
		||||
  GTMOAuth2Keychain *keychain = [GTMOAuth2Keychain defaultKeychain];
 | 
			
		||||
  NSString *password = [keychain passwordForService:keychainItemName
 | 
			
		||||
                                            account:kGTMOAuth2AccountName
 | 
			
		||||
                                              error:nil];
 | 
			
		||||
  if (password != nil) {
 | 
			
		||||
    [newAuth setKeysForResponseString:password];
 | 
			
		||||
    didGetTokens = YES;
 | 
			
		||||
  }
 | 
			
		||||
  return didGetTokens;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (BOOL)removeAuthFromKeychainForName:(NSString *)keychainItemName {
 | 
			
		||||
  GTMOAuth2Keychain *keychain = [GTMOAuth2Keychain defaultKeychain];
 | 
			
		||||
  return [keychain removePasswordForService:keychainItemName
 | 
			
		||||
                                    account:kGTMOAuth2AccountName
 | 
			
		||||
                                      error:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                     authentication:(GTMOAuth2Authentication *)auth {
 | 
			
		||||
  return [self saveParamsToKeychainForName:keychainItemName
 | 
			
		||||
                             accessibility:NULL
 | 
			
		||||
                            authentication:auth];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName
 | 
			
		||||
                      accessibility:(CFTypeRef)accessibility
 | 
			
		||||
                     authentication:(GTMOAuth2Authentication *)auth {
 | 
			
		||||
  [self removeAuthFromKeychainForName:keychainItemName];
 | 
			
		||||
  // don't save unless we have a token that can really authorize requests
 | 
			
		||||
  if (![auth canAuthorize]) return NO;
 | 
			
		||||
 | 
			
		||||
  if (accessibility == NULL
 | 
			
		||||
      && &kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly != NULL) {
 | 
			
		||||
    accessibility = kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // make a response string containing the values we want to save
 | 
			
		||||
  NSString *password = [auth persistenceResponseString];
 | 
			
		||||
  GTMOAuth2Keychain *keychain = [GTMOAuth2Keychain defaultKeychain];
 | 
			
		||||
  return [keychain setPassword:password
 | 
			
		||||
                    forService:keychainItemName
 | 
			
		||||
                 accessibility:accessibility
 | 
			
		||||
                       account:kGTMOAuth2AccountName
 | 
			
		||||
                         error:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)loadView {
 | 
			
		||||
  NSString *nibPath = nil;
 | 
			
		||||
  NSBundle *nibBundle = [self nibBundle];
 | 
			
		||||
  if (nibBundle == nil) {
 | 
			
		||||
    nibBundle = [NSBundle mainBundle];
 | 
			
		||||
  }
 | 
			
		||||
  NSString *nibName = self.nibName;
 | 
			
		||||
  if (nibName != nil) {
 | 
			
		||||
    nibPath = [nibBundle pathForResource:nibName ofType:@"nib"];
 | 
			
		||||
  }
 | 
			
		||||
  if (nibPath != nil && [[NSFileManager defaultManager] fileExistsAtPath:nibPath]) {
 | 
			
		||||
    [super loadView];
 | 
			
		||||
  } else {
 | 
			
		||||
    // One of the requirements of loadView is that a valid view object is set to
 | 
			
		||||
    // self.view upon completion. Otherwise, subclasses that attempt to
 | 
			
		||||
    // access self.view after calling [super loadView] will enter an infinite
 | 
			
		||||
    // loop due to the fact that UIViewController's -view accessor calls
 | 
			
		||||
    // loadView when self.view is nil.
 | 
			
		||||
    self.view = [[[UIView alloc] init] autorelease];
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    NSLog(@"missing %@.nib", nibName);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (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) {
 | 
			
		||||
      // 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];
 | 
			
		||||
      self.view.hidden = YES;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)notifyWithName:(NSString *)name
 | 
			
		||||
               webView:(UIWebView *)webView
 | 
			
		||||
                  kind:(NSString *)kind {
 | 
			
		||||
  BOOL isStarting = [name isEqual:kGTMOAuth2WebViewStartedLoading];
 | 
			
		||||
  if (hasNotifiedWebViewStartedLoading_ == isStarting) {
 | 
			
		||||
    // Duplicate notification
 | 
			
		||||
    //
 | 
			
		||||
    // UIWebView's delegate methods are so unbalanced that there's little
 | 
			
		||||
    // point trying to keep a count, as it could easily end up stuck greater
 | 
			
		||||
    // than zero.
 | 
			
		||||
    //
 | 
			
		||||
    // We don't really have a way to track the starts and stops of
 | 
			
		||||
    // subframe loads, too, as the webView in the notification is always
 | 
			
		||||
    // for the topmost request.
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  hasNotifiedWebViewStartedLoading_ = isStarting;
 | 
			
		||||
 | 
			
		||||
  // Notification for webview load starting and stopping
 | 
			
		||||
  NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                        webView, kGTMOAuth2WebViewKey,
 | 
			
		||||
                        kind, kGTMOAuth2WebViewStopKindKey, // kind may be nil
 | 
			
		||||
                        nil];
 | 
			
		||||
  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 | 
			
		||||
  [nc postNotificationName:name
 | 
			
		||||
                    object:self
 | 
			
		||||
                  userInfo:dict];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)cancelSigningIn {
 | 
			
		||||
  // The application has explicitly asked us to cancel signing in
 | 
			
		||||
  // (so no further callback is required)
 | 
			
		||||
  hasCalledFinished_ = YES;
 | 
			
		||||
 | 
			
		||||
  [delegate_ autorelease];
 | 
			
		||||
  delegate_ = nil;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
  [completionBlock_ autorelease];
 | 
			
		||||
  completionBlock_ = nil;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // The sign-in object's cancel method will close the window
 | 
			
		||||
  [signIn_ cancelSigningIn];
 | 
			
		||||
  hasDoneFinalRedirect_ = YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Class gSignInClass = Nil;
 | 
			
		||||
 | 
			
		||||
+ (Class)signInClass {
 | 
			
		||||
  if (gSignInClass == Nil) {
 | 
			
		||||
    gSignInClass = [GTMOAuth2SignIn class];
 | 
			
		||||
  }
 | 
			
		||||
  return gSignInClass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (void)setSignInClass:(Class)theClass {
 | 
			
		||||
  gSignInClass = theClass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Token Revocation
 | 
			
		||||
 | 
			
		||||
#if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
 | 
			
		||||
+ (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth {
 | 
			
		||||
  [[self signInClass] revokeTokenForGoogleAuthentication:auth];
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma mark Browser Cookies
 | 
			
		||||
 | 
			
		||||
- (GTMOAuth2Authentication *)authentication {
 | 
			
		||||
  return self.signIn.authentication;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearBrowserCookies {
 | 
			
		||||
  // if browserCookiesURL is non-nil, then get cookies for that URL
 | 
			
		||||
  // and delete them from the common application cookie storage
 | 
			
		||||
  NSURL *cookiesURL = [self browserCookiesURL];
 | 
			
		||||
  if (cookiesURL) {
 | 
			
		||||
    NSHTTPCookieStorage *cookieStorage;
 | 
			
		||||
 | 
			
		||||
    cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
 | 
			
		||||
    NSArray *cookies =  [cookieStorage cookiesForURL:cookiesURL];
 | 
			
		||||
 | 
			
		||||
    for (NSHTTPCookie *cookie in cookies) {
 | 
			
		||||
      [cookieStorage deleteCookie:cookie];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Accessors
 | 
			
		||||
 | 
			
		||||
- (void)setNetworkLossTimeoutInterval:(NSTimeInterval)val {
 | 
			
		||||
  signIn_.networkLossTimeoutInterval = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSTimeInterval)networkLossTimeoutInterval {
 | 
			
		||||
  return signIn_.networkLossTimeoutInterval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldUseKeychain {
 | 
			
		||||
  NSString *name = self.keychainItemName;
 | 
			
		||||
  return ([name length] > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark User Properties
 | 
			
		||||
 | 
			
		||||
- (void)setProperty:(id)obj forKey:(NSString *)key {
 | 
			
		||||
  if (obj == nil) {
 | 
			
		||||
    // User passed in nil, so delete the property
 | 
			
		||||
    [properties_ removeObjectForKey:key];
 | 
			
		||||
  } else {
 | 
			
		||||
    // Be sure the property dictionary exists
 | 
			
		||||
    if (properties_ == nil) {
 | 
			
		||||
      [self setProperties:[NSMutableDictionary dictionary]];
 | 
			
		||||
    }
 | 
			
		||||
    [properties_ setObject:obj forKey:key];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)propertyForKey:(NSString *)key {
 | 
			
		||||
  id obj = [properties_ objectForKey:key];
 | 
			
		||||
 | 
			
		||||
  // Be sure the returned pointer has the life of the autorelease pool,
 | 
			
		||||
  // in case self is released immediately
 | 
			
		||||
  return [[obj retain] autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
  //
 | 
			
		||||
  // All web requests and all window closing goes through this routine
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  if (self.navigationController) {
 | 
			
		||||
    if (self.navigationController.topViewController != self && request != nil) {
 | 
			
		||||
      NSLog(@"Unexpected: Request to show, when already on top. request %@", [request URL]);
 | 
			
		||||
    } else if(self.navigationController.topViewController != self && request == nil) {
 | 
			
		||||
      NSLog(@"Unexpected: Request to pop, when not on top. request nil");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (request != nil) {
 | 
			
		||||
    const NSTimeInterval kJanuary2011 = 1293840000;
 | 
			
		||||
    BOOL isDateValid = ([[NSDate date] timeIntervalSince1970] > kJanuary2011);
 | 
			
		||||
    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];
 | 
			
		||||
      } else {
 | 
			
		||||
        [self.webView loadRequest:request];
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // clock date is invalid, so signing in would fail with an unhelpful error
 | 
			
		||||
      // from the server. Warn the user in an html string showing a watch icon,
 | 
			
		||||
      // question mark, and the system date and time. Hopefully this will clue
 | 
			
		||||
      // in brighter users, or at least give them a clue when they report the
 | 
			
		||||
      // problem to developers.
 | 
			
		||||
      //
 | 
			
		||||
      // Even better is for apps to check the system clock and show some more
 | 
			
		||||
      // helpful, localized instructions for users; this is really a fallback.
 | 
			
		||||
      NSString *html = @"<html><body><div align=center><font size='7'>"
 | 
			
		||||
        @"⌚ ?<br><i>System Clock Incorrect</i><br>%@"
 | 
			
		||||
        @"</font></div></body></html>";
 | 
			
		||||
      NSString *errHTML = [NSString stringWithFormat:html, [NSDate date]];
 | 
			
		||||
 | 
			
		||||
      [[self webView] loadHTMLString:errHTML baseURL:nil];
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    // request was nil.
 | 
			
		||||
    [self popView];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)signIn:(GTMOAuth2SignIn *)signIn
 | 
			
		||||
  finishedWithAuth:(GTMOAuth2Authentication *)auth
 | 
			
		||||
             error:(NSError *)error {
 | 
			
		||||
  if (!hasCalledFinished_) {
 | 
			
		||||
    hasCalledFinished_ = YES;
 | 
			
		||||
 | 
			
		||||
    if (error == nil) {
 | 
			
		||||
      if (self.shouldUseKeychain) {
 | 
			
		||||
        NSString *keychainItemName = self.keychainItemName;
 | 
			
		||||
        if (auth.canAuthorize) {
 | 
			
		||||
          // save the auth params in the keychain
 | 
			
		||||
          CFTypeRef accessibility = self.keychainItemAccessibility;
 | 
			
		||||
          [[self class] saveParamsToKeychainForName:keychainItemName
 | 
			
		||||
                                      accessibility:accessibility
 | 
			
		||||
                                     authentication:auth];
 | 
			
		||||
        } else {
 | 
			
		||||
          // remove the auth params from the keychain
 | 
			
		||||
          [[self class] removeAuthFromKeychainForName:keychainItemName];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (delegate_ && finishedSelector_) {
 | 
			
		||||
      SEL sel = finishedSelector_;
 | 
			
		||||
      NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel];
 | 
			
		||||
      NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
 | 
			
		||||
      [invocation setSelector:sel];
 | 
			
		||||
      [invocation setTarget:delegate_];
 | 
			
		||||
      [invocation setArgument:&self atIndex:2];
 | 
			
		||||
      [invocation setArgument:&auth atIndex:3];
 | 
			
		||||
      [invocation setArgument:&error atIndex:4];
 | 
			
		||||
      [invocation invoke];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [delegate_ autorelease];
 | 
			
		||||
    delegate_ = nil;
 | 
			
		||||
 | 
			
		||||
#if NS_BLOCKS_AVAILABLE
 | 
			
		||||
    if (completionBlock_) {
 | 
			
		||||
      completionBlock_(self, auth, error);
 | 
			
		||||
 | 
			
		||||
      // release the block here to avoid a retain loop on the controller
 | 
			
		||||
      [completionBlock_ autorelease];
 | 
			
		||||
      completionBlock_ = nil;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)moveWebViewFromUnderNavigationBar {
 | 
			
		||||
  CGRect dontCare;
 | 
			
		||||
  CGRect webFrame = self.view.bounds;
 | 
			
		||||
  UINavigationBar *navigationBar = self.navigationController.navigationBar;
 | 
			
		||||
  CGRectDivide(webFrame, &dontCare, &webFrame,
 | 
			
		||||
    navigationBar.frame.size.height, CGRectMinYEdge);
 | 
			
		||||
  [self.webView setFrame:webFrame];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isTranslucent is defined in iPhoneOS 3.0 on.
 | 
			
		||||
- (BOOL)isNavigationBarTranslucent {
 | 
			
		||||
  UINavigationBar *navigationBar = [[self navigationController] navigationBar];
 | 
			
		||||
  BOOL isTranslucent =
 | 
			
		||||
    ([navigationBar respondsToSelector:@selector(isTranslucent)] &&
 | 
			
		||||
     [navigationBar isTranslucent]);
 | 
			
		||||
  return isTranslucent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
#pragma mark Protocol implementations
 | 
			
		||||
 | 
			
		||||
- (void)viewWillAppear:(BOOL)animated {
 | 
			
		||||
  if (!isViewShown_) {
 | 
			
		||||
    isViewShown_ = YES;
 | 
			
		||||
    if ([self isNavigationBarTranslucent]) {
 | 
			
		||||
      [self moveWebViewFromUnderNavigationBar];
 | 
			
		||||
    }
 | 
			
		||||
    if (![signIn_ startSigningIn]) {
 | 
			
		||||
      // Can't start signing in. We must pop our view.
 | 
			
		||||
      // UIWebview needs time to stabilize. Animations need time to complete.
 | 
			
		||||
      // We remove ourself from the view stack after that.
 | 
			
		||||
      [self performSelector:@selector(popView)
 | 
			
		||||
                 withObject:nil
 | 
			
		||||
                 afterDelay:0.5
 | 
			
		||||
                    inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  [super viewWillAppear:animated];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)viewDidAppear:(BOOL)animated {
 | 
			
		||||
  didViewAppear_ = YES;
 | 
			
		||||
  [super viewDidAppear:animated];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)viewWillDisappear:(BOOL)animated {
 | 
			
		||||
  if (!didDismissSelf_) {
 | 
			
		||||
    // We won't receive further webview delegate messages, so be sure the
 | 
			
		||||
    // started loading notification is balanced, if necessary
 | 
			
		||||
    [self notifyWithName:kGTMOAuth2WebViewStoppedLoading
 | 
			
		||||
                 webView:self.webView
 | 
			
		||||
                    kind:kGTMOAuth2WebViewCancelled];
 | 
			
		||||
 | 
			
		||||
    // We are not popping ourselves, so presumably we are being popped by the
 | 
			
		||||
    // navigation controller; tell the sign-in object to close up shop
 | 
			
		||||
    //
 | 
			
		||||
    // this will indirectly call our signIn:finishedWithAuth:error: method
 | 
			
		||||
    // for us
 | 
			
		||||
    [signIn_ windowWasClosed];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // prevent the next sign-in from showing in the WebView that the user is
 | 
			
		||||
  // already signed in
 | 
			
		||||
  [self clearBrowserCookies];
 | 
			
		||||
 | 
			
		||||
  [super viewWillDisappear:animated];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)webView:(UIWebView *)webView
 | 
			
		||||
  shouldStartLoadWithRequest:(NSURLRequest *)request
 | 
			
		||||
              navigationType:(UIWebViewNavigationType)navigationType {
 | 
			
		||||
 | 
			
		||||
  if (!hasDoneFinalRedirect_) {
 | 
			
		||||
    hasDoneFinalRedirect_ = [signIn_ requestRedirectedToRequest:request];
 | 
			
		||||
    if (hasDoneFinalRedirect_) {
 | 
			
		||||
      // signIn has told the view to close
 | 
			
		||||
      return NO;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)updateUI {
 | 
			
		||||
  [backButton_ setEnabled:[[self webView] canGoBack]];
 | 
			
		||||
  [forwardButton_ setEnabled:[[self webView] canGoForward]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)webViewDidStartLoad:(UIWebView *)webView {
 | 
			
		||||
  [self notifyWithName:kGTMOAuth2WebViewStartedLoading
 | 
			
		||||
               webView:webView
 | 
			
		||||
                  kind:nil];
 | 
			
		||||
  [self updateUI];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)webViewDidFinishLoad:(UIWebView *)webView {
 | 
			
		||||
  [self notifyWithName:kGTMOAuth2WebViewStoppedLoading
 | 
			
		||||
               webView:webView
 | 
			
		||||
                  kind:kGTMOAuth2WebViewFinished];
 | 
			
		||||
 | 
			
		||||
  NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
 | 
			
		||||
  if ([title length] > 0) {
 | 
			
		||||
    [signIn_ titleChanged:title];
 | 
			
		||||
  } else {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    // Verify that Javascript is enabled
 | 
			
		||||
    NSString *result = [webView stringByEvaluatingJavaScriptFromString:@"1+1"];
 | 
			
		||||
    NSAssert([result integerValue] == 2, @"GTMOAuth2: Javascript is required");
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  [signIn_ cookiesChanged:[NSHTTPCookieStorage sharedHTTPCookieStorage]];
 | 
			
		||||
 | 
			
		||||
  [self updateUI];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
 | 
			
		||||
  [self notifyWithName:kGTMOAuth2WebViewStoppedLoading
 | 
			
		||||
               webView:webView
 | 
			
		||||
                  kind:kGTMOAuth2WebViewFailed];
 | 
			
		||||
 | 
			
		||||
  // Tell the sign-in object that a load failed; if it was the authorization
 | 
			
		||||
  // URL, it will pop the view and return an error to the delegate.
 | 
			
		||||
  if (didViewAppear_) {
 | 
			
		||||
    BOOL isUserInterruption = ([error code] == NSURLErrorCancelled
 | 
			
		||||
                               && [[error domain] isEqual:NSURLErrorDomain]);
 | 
			
		||||
    if (isUserInterruption) {
 | 
			
		||||
      // Ignore this error:
 | 
			
		||||
      // Users report that this error occurs when clicking too quickly on the
 | 
			
		||||
      // accept button, before the page has completely loaded.  Ignoring
 | 
			
		||||
      // this error seems to provide a better experience than does immediately
 | 
			
		||||
      // cancelling sign-in.
 | 
			
		||||
      //
 | 
			
		||||
      // This error also occurs whenever UIWebView is sent the stopLoading
 | 
			
		||||
      // message, so if we ever send that message intentionally, we need to
 | 
			
		||||
      // revisit this bypass.
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [signIn_ loadFailedWithError:error];
 | 
			
		||||
  } else {
 | 
			
		||||
    // UIWebview needs time to stabilize. Animations need time to complete.
 | 
			
		||||
    [signIn_ performSelector:@selector(loadFailedWithError:)
 | 
			
		||||
                  withObject:error
 | 
			
		||||
                  afterDelay:0.5
 | 
			
		||||
                     inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 | 
			
		||||
  BOOL value = YES;
 | 
			
		||||
  if (!isInsideShouldAutorotateToInterfaceOrientation_) {
 | 
			
		||||
    isInsideShouldAutorotateToInterfaceOrientation_ = YES;
 | 
			
		||||
    UIViewController *navigationController = [self navigationController];
 | 
			
		||||
    if (navigationController != nil) {
 | 
			
		||||
      value = [navigationController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
 | 
			
		||||
    } else {
 | 
			
		||||
      value = [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
 | 
			
		||||
    }
 | 
			
		||||
    isInsideShouldAutorotateToInterfaceOrientation_ = NO;
 | 
			
		||||
  }
 | 
			
		||||
  return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma mark Common Code
 | 
			
		||||
 | 
			
		||||
@implementation GTMOAuth2Keychain
 | 
			
		||||
 | 
			
		||||
+ (GTMOAuth2Keychain *)defaultKeychain {
 | 
			
		||||
  if (sDefaultKeychain == nil) {
 | 
			
		||||
    sDefaultKeychain = [[self alloc] init];
 | 
			
		||||
  }
 | 
			
		||||
  return sDefaultKeychain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// For unit tests: allow setting a mock object
 | 
			
		||||
+ (void)setDefaultKeychain:(GTMOAuth2Keychain *)keychain {
 | 
			
		||||
  if (sDefaultKeychain != keychain) {
 | 
			
		||||
    [sDefaultKeychain release];
 | 
			
		||||
    sDefaultKeychain = [keychain retain];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)keyForService:(NSString *)service account:(NSString *)account {
 | 
			
		||||
  return [NSString stringWithFormat:@"com.google.GTMOAuth.%@%@", service, account];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The Keychain API isn't available on the iPhone simulator in SDKs before 3.0,
 | 
			
		||||
// so, on early simulators we use a fake API, that just writes, unencrypted, to
 | 
			
		||||
// NSUserDefaults.
 | 
			
		||||
#if TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MAX_ALLOWED < 30000
 | 
			
		||||
#pragma mark Simulator
 | 
			
		||||
 | 
			
		||||
// Simulator - just simulated, not secure.
 | 
			
		||||
- (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
 | 
			
		||||
  NSString *result = nil;
 | 
			
		||||
  if (0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
    NSString *key = [self keyForService:service account:account];
 | 
			
		||||
    result = [defaults stringForKey:key];
 | 
			
		||||
    if (result == nil && error != NULL) {
 | 
			
		||||
      *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                   code:kGTMOAuth2KeychainErrorNoPassword
 | 
			
		||||
                               userInfo:nil];
 | 
			
		||||
    }
 | 
			
		||||
  } else if (error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:kGTMOAuth2KeychainErrorBadArguments
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Simulator - just simulated, not secure.
 | 
			
		||||
- (BOOL)removePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
 | 
			
		||||
  BOOL didSucceed = NO;
 | 
			
		||||
  if (0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
    NSString *key = [self keyForService:service account:account];
 | 
			
		||||
    [defaults removeObjectForKey:key];
 | 
			
		||||
    [defaults synchronize];
 | 
			
		||||
  } else if (error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:kGTMOAuth2KeychainErrorBadArguments
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return didSucceed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Simulator - just simulated, not secure.
 | 
			
		||||
- (BOOL)setPassword:(NSString *)password
 | 
			
		||||
         forService:(NSString *)service
 | 
			
		||||
      accessibility:(CFTypeRef)accessibility
 | 
			
		||||
            account:(NSString *)account
 | 
			
		||||
              error:(NSError **)error {
 | 
			
		||||
  BOOL didSucceed = NO;
 | 
			
		||||
  if (0 < [password length] && 0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
    NSString *key = [self keyForService:service account:account];
 | 
			
		||||
    [defaults setObject:password forKey:key];
 | 
			
		||||
    [defaults synchronize];
 | 
			
		||||
    didSucceed = YES;
 | 
			
		||||
  } else if (error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:kGTMOAuth2KeychainErrorBadArguments
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return didSucceed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // ! TARGET_IPHONE_SIMULATOR
 | 
			
		||||
#pragma mark Device
 | 
			
		||||
 | 
			
		||||
+ (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account {
 | 
			
		||||
  NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                         (id)kSecClassGenericPassword, (id)kSecClass,
 | 
			
		||||
                         @"OAuth", (id)kSecAttrGeneric,
 | 
			
		||||
                         account, (id)kSecAttrAccount,
 | 
			
		||||
                         service, (id)kSecAttrService,
 | 
			
		||||
                         nil];
 | 
			
		||||
  return query;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account {
 | 
			
		||||
  return [[self class] keychainQueryForService:service account:account];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// iPhone
 | 
			
		||||
- (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
 | 
			
		||||
  OSStatus status = kGTMOAuth2KeychainErrorBadArguments;
 | 
			
		||||
  NSString *result = nil;
 | 
			
		||||
  if (0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    CFDataRef passwordData = NULL;
 | 
			
		||||
    NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account];
 | 
			
		||||
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
 | 
			
		||||
    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
 | 
			
		||||
 | 
			
		||||
    status = SecItemCopyMatching((CFDictionaryRef)keychainQuery,
 | 
			
		||||
                                       (CFTypeRef *)&passwordData);
 | 
			
		||||
    if (status == noErr && 0 < [(NSData *)passwordData length]) {
 | 
			
		||||
      result = [[[NSString alloc] initWithData:(NSData *)passwordData
 | 
			
		||||
                                      encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
    }
 | 
			
		||||
    if (passwordData != NULL) {
 | 
			
		||||
      CFRelease(passwordData);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (status != noErr && error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:status
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// iPhone
 | 
			
		||||
- (BOOL)removePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
 | 
			
		||||
  OSStatus status = kGTMOAuth2KeychainErrorBadArguments;
 | 
			
		||||
  if (0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account];
 | 
			
		||||
    status = SecItemDelete((CFDictionaryRef)keychainQuery);
 | 
			
		||||
  }
 | 
			
		||||
  if (status != noErr && error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:status
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return status == noErr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// iPhone
 | 
			
		||||
- (BOOL)setPassword:(NSString *)password
 | 
			
		||||
         forService:(NSString *)service
 | 
			
		||||
      accessibility:(CFTypeRef)accessibility
 | 
			
		||||
            account:(NSString *)account
 | 
			
		||||
              error:(NSError **)error {
 | 
			
		||||
  OSStatus status = kGTMOAuth2KeychainErrorBadArguments;
 | 
			
		||||
  if (0 < [service length] && 0 < [account length]) {
 | 
			
		||||
    [self removePasswordForService:service account:account error:nil];
 | 
			
		||||
    if (0 < [password length]) {
 | 
			
		||||
      NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account];
 | 
			
		||||
      NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
      [keychainQuery setObject:passwordData forKey:(id)kSecValueData];
 | 
			
		||||
 | 
			
		||||
      if (accessibility != NULL && &kSecAttrAccessible != NULL) {
 | 
			
		||||
        [keychainQuery setObject:(id)accessibility
 | 
			
		||||
                          forKey:(id)kSecAttrAccessible];
 | 
			
		||||
      }
 | 
			
		||||
      status = SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (status != noErr && error != NULL) {
 | 
			
		||||
    *error = [NSError errorWithDomain:kGTMOAuth2KeychainErrorDomain
 | 
			
		||||
                                 code:status
 | 
			
		||||
                             userInfo:nil];
 | 
			
		||||
  }
 | 
			
		||||
  return status == noErr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ! TARGET_IPHONE_SIMULATOR
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif // TARGET_OS_IPHONE
 | 
			
		||||
 | 
			
		||||
#endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
 | 
			
		||||
							
								
								
									
										456
									
								
								External/google-plus-ios-sdk/OpenSource/GTMOAuth2ViewTouch.xib
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,456 @@
 | 
			
		||||
<?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>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			<string key="NS.object.0">141</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<integer value="4"/>
 | 
			
		||||
			<integer value="15"/>
 | 
			
		||||
		</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>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<object class="IBProxyObject" id="372490531">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBProxyObject" id="975951072">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUINavigationItem" id="1047805472">
 | 
			
		||||
				<string key="IBUITitle">OAuth</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUIBarButtonItem" id="961671599">
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
				<int key="IBUIStyle">1</int>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUIView" id="808907889">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">292</int>
 | 
			
		||||
				<object class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<object class="IBUIButton" id="453250804">
 | 
			
		||||
						<reference key="NSNextResponder" ref="808907889"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrameSize">{30, 30}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="808907889"/>
 | 
			
		||||
						<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">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSColor" key="IBUIDisabledTitleColor">
 | 
			
		||||
							<int key="NSColorSpace">2</int>
 | 
			
		||||
							<bytes key="NSRGB">MC41OTYwNzg0NiAwLjY4NjI3NDUzIDAuOTUyOTQxMjQgMC42MDAwMDAwMgA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="IBUINormalTitleColor" ref="193465259"/>
 | 
			
		||||
						<object class="NSColor" key="IBUINormalTitleShadowColor" id="999379443">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MC41AA</bytes>
 | 
			
		||||
						</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"/>
 | 
			
		||||
						<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"/>
 | 
			
		||||
						<object class="NSColor" key="IBUIDisabledTitleColor">
 | 
			
		||||
							<int key="NSColorSpace">2</int>
 | 
			
		||||
							<bytes key="NSRGB">MC41ODQzMTM3NSAwLjY3NDUwOTgyIDAuOTUyOTQxMjQgMC42MDAwMDAwMgA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="IBUINormalTitleColor" ref="193465259"/>
 | 
			
		||||
						<reference key="IBUINormalTitleShadowColor" ref="999379443"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="NSFrameSize">{60, 30}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<object class="NSColor" key="IBUIBackgroundColor">
 | 
			
		||||
					<int key="NSColorSpace">3</int>
 | 
			
		||||
					<bytes key="NSWhite">MSAwAA</bytes>
 | 
			
		||||
				</object>
 | 
			
		||||
				<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
 | 
			
		||||
				<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
 | 
			
		||||
					<int key="interfaceOrientation">3</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUIView" id="426018584">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">274</int>
 | 
			
		||||
				<object class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<object class="IBUIWebView" id="663477729">
 | 
			
		||||
						<reference key="NSNextResponder" ref="426018584"/>
 | 
			
		||||
						<int key="NSvFlags">274</int>
 | 
			
		||||
						<string key="NSFrameSize">{320, 460}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="426018584"/>
 | 
			
		||||
						<object class="NSColor" key="IBUIBackgroundColor">
 | 
			
		||||
							<int key="NSColorSpace">1</int>
 | 
			
		||||
							<bytes key="NSRGB">MSAxIDEAA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<bool key="IBUIMultipleTouchEnabled">YES</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<int key="IBUIDataDetectorTypes">1</int>
 | 
			
		||||
						<bool key="IBUIDetectsPhoneNumbers">YES</bool>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="NSFrameSize">{320, 460}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<object class="NSColor" key="IBUIBackgroundColor">
 | 
			
		||||
					<int key="NSColorSpace">3</int>
 | 
			
		||||
					<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
					<object class="NSColorSpace" key="NSCustomColorSpace">
 | 
			
		||||
						<int key="NSID">2</int>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
		</object>
 | 
			
		||||
		<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>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="961671599"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">20</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">navButtonsView</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="808907889"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">22</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">backButton</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="453250804"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">25</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">forwardButton</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="981703116"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">26</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">view</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="426018584"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">28</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">webView</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="663477729"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">29</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"/>
 | 
			
		||||
						<reference key="children" ref="1000"/>
 | 
			
		||||
						<nil key="parent"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-1</int>
 | 
			
		||||
						<reference key="object" ref="372490531"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">File's Owner</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-2</int>
 | 
			
		||||
						<reference key="object" ref="975951072"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">6</int>
 | 
			
		||||
						<reference key="object" ref="1047805472"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">10</int>
 | 
			
		||||
						<reference key="object" ref="961671599"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">15</int>
 | 
			
		||||
						<reference key="object" ref="808907889"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="453250804"/>
 | 
			
		||||
							<reference ref="981703116"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">16</int>
 | 
			
		||||
						<reference key="object" ref="453250804"/>
 | 
			
		||||
						<reference key="parent" ref="808907889"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">17</int>
 | 
			
		||||
						<reference key="object" ref="981703116"/>
 | 
			
		||||
						<reference key="parent" ref="808907889"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">27</int>
 | 
			
		||||
						<reference key="object" ref="426018584"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="663477729"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">4</int>
 | 
			
		||||
						<reference key="object" ref="663477729"/>
 | 
			
		||||
						<reference key="parent" ref="426018584"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSMutableDictionary" key="flattenedProperties">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<string>-1.CustomClassName</string>
 | 
			
		||||
					<string>-2.CustomClassName</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>4.IBPluginDependency</string>
 | 
			
		||||
					<string>6.IBPluginDependency</string>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<string>GTMOAuth2ViewControllerTouch</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>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
			<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>
 | 
			
		||||
			</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>
 | 
			
		||||
			</object>
 | 
			
		||||
			<nil key="sourceID"/>
 | 
			
		||||
			<int key="maxID">29</int>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBClassDescriber" key="IBDocument.Classes">
 | 
			
		||||
			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<object class="IBPartialClassDescription">
 | 
			
		||||
					<string key="className">GTMOAuth2ViewControllerTouch</string>
 | 
			
		||||
					<string key="superclassName">UIViewController</string>
 | 
			
		||||
					<object class="NSMutableDictionary" key="outlets">
 | 
			
		||||
						<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
						<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>backButton</string>
 | 
			
		||||
							<string>delegate_</string>
 | 
			
		||||
							<string>forwardButton</string>
 | 
			
		||||
							<string>navButtonsView</string>
 | 
			
		||||
							<string>rightBarButtonItem</string>
 | 
			
		||||
							<string>userData_</string>
 | 
			
		||||
							<string>webView</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>UIButton</string>
 | 
			
		||||
							<string>id</string>
 | 
			
		||||
							<string>UIButton</string>
 | 
			
		||||
							<string>UIView</string>
 | 
			
		||||
							<string>UIBarButtonItem</string>
 | 
			
		||||
							<string>id</string>
 | 
			
		||||
							<string>UIWebView</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
 | 
			
		||||
						<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
						<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>backButton</string>
 | 
			
		||||
							<string>delegate_</string>
 | 
			
		||||
							<string>forwardButton</string>
 | 
			
		||||
							<string>navButtonsView</string>
 | 
			
		||||
							<string>rightBarButtonItem</string>
 | 
			
		||||
							<string>userData_</string>
 | 
			
		||||
							<string>webView</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSMutableArray" 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">navButtonsView</string>
 | 
			
		||||
								<string key="candidateClassName">UIView</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<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>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 | 
			
		||||
						<string key="majorKey">IBProjectSource</string>
 | 
			
		||||
						<string key="minorKey">Touch/GTMOAuth2ViewControllerTouch.h</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
		</object>
 | 
			
		||||
		<int key="IBDocument.localizationMode">0</int>
 | 
			
		||||
		<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"/>
 | 
			
		||||
		</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"/>
 | 
			
		||||
		</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>
 | 
			
		||||
	</data>
 | 
			
		||||
</archive>
 | 
			
		||||
							
								
								
									
										113
									
								
								External/google-plus-ios-sdk/OpenSource/GTMObjC2Runtime.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,113 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMObjC2Runtime.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <objc/objc-api.h>
 | 
			
		||||
#import <objc/objc-auto.h>
 | 
			
		||||
#import "GTMDefines.h"
 | 
			
		||||
 | 
			
		||||
// These functions exist for code that we want to compile on both the < 10.5
 | 
			
		||||
// sdks and on the >= 10.5 sdks without warnings. It basically reimplements
 | 
			
		||||
// certain parts of the objc2 runtime in terms of the objc1 runtime. It is not
 | 
			
		||||
// a complete implementation as I've only implemented the routines I know we
 | 
			
		||||
// use. Feel free to add more as necessary.
 | 
			
		||||
// These functions are not documented because they conform to the documentation
 | 
			
		||||
// for the ObjC2 Runtime.
 | 
			
		||||
 | 
			
		||||
#if OBJC_API_VERSION >= 2  // Only have optional and req'd keywords in ObjC2.
 | 
			
		||||
#define AT_OPTIONAL @optional
 | 
			
		||||
#define AT_REQUIRED @required
 | 
			
		||||
#else
 | 
			
		||||
#define AT_OPTIONAL
 | 
			
		||||
#define AT_REQUIRED
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// The file objc-runtime.h was moved to runtime.h and in Leopard, objc-runtime.h
 | 
			
		||||
// was just a wrapper around runtime.h. For the iPhone SDK, this objc-runtime.h
 | 
			
		||||
// is removed in the iPhoneOS2.0 SDK.
 | 
			
		||||
//
 | 
			
		||||
// The |Object| class was removed in the iPhone2.0 SDK too.
 | 
			
		||||
#if GTM_IPHONE_SDK
 | 
			
		||||
#import <objc/message.h>
 | 
			
		||||
#import <objc/runtime.h>
 | 
			
		||||
#else
 | 
			
		||||
#import <objc/objc-runtime.h>
 | 
			
		||||
#import <objc/Object.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#import <libkern/OSAtomic.h>
 | 
			
		||||
 | 
			
		||||
#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
#import "objc/Protocol.h"
 | 
			
		||||
 | 
			
		||||
OBJC_EXPORT Class object_getClass(id obj);
 | 
			
		||||
OBJC_EXPORT const char *class_getName(Class cls);
 | 
			
		||||
OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol);
 | 
			
		||||
OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel);
 | 
			
		||||
OBJC_EXPORT Class class_getSuperclass(Class cls);
 | 
			
		||||
OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount);
 | 
			
		||||
OBJC_EXPORT SEL method_getName(Method m);
 | 
			
		||||
OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2);
 | 
			
		||||
OBJC_EXPORT IMP method_getImplementation(Method method);
 | 
			
		||||
OBJC_EXPORT IMP method_setImplementation(Method method, IMP imp);
 | 
			
		||||
OBJC_EXPORT struct objc_method_description protocol_getMethodDescription(Protocol *p,
 | 
			
		||||
                                                                         SEL aSel,
 | 
			
		||||
                                                                         BOOL isRequiredMethod,
 | 
			
		||||
                                                                         BOOL isInstanceMethod);
 | 
			
		||||
OBJC_EXPORT BOOL sel_isEqual(SEL lhs, SEL rhs);
 | 
			
		||||
 | 
			
		||||
// If building for 10.4 but using the 10.5 SDK, don't include these.
 | 
			
		||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
 | 
			
		||||
// atomics
 | 
			
		||||
// On Leopard these are GC aware
 | 
			
		||||
// Intentionally did not include the non-barrier versions, because I couldn't
 | 
			
		||||
// come up with a case personally where you wouldn't want to use the
 | 
			
		||||
// barrier versions.
 | 
			
		||||
GTM_INLINE bool OSAtomicCompareAndSwapPtrBarrier(void *predicate,
 | 
			
		||||
                                                 void *replacement,
 | 
			
		||||
                                                 void * volatile *theValue) {
 | 
			
		||||
#if defined(__LP64__) && __LP64__
 | 
			
		||||
  return OSAtomicCompareAndSwap64Barrier((int64_t)predicate,
 | 
			
		||||
                                         (int64_t)replacement,
 | 
			
		||||
                                         (int64_t *)theValue);
 | 
			
		||||
#else  // defined(__LP64__) && __LP64__
 | 
			
		||||
  return OSAtomicCompareAndSwap32Barrier((int32_t)predicate,
 | 
			
		||||
                                         (int32_t)replacement,
 | 
			
		||||
                                         (int32_t *)theValue);
 | 
			
		||||
#endif  // defined(__LP64__) && __LP64__
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
 | 
			
		||||
#endif  // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
 | 
			
		||||
#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
 | 
			
		||||
GTM_INLINE BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate,
 | 
			
		||||
                                                       id replacement,
 | 
			
		||||
                                                       volatile id *objectLocation) {
 | 
			
		||||
  return OSAtomicCompareAndSwapPtrBarrier(predicate,
 | 
			
		||||
                                          replacement,
 | 
			
		||||
                                          (void * volatile *)objectLocation);
 | 
			
		||||
}
 | 
			
		||||
GTM_INLINE BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate,
 | 
			
		||||
                                                                 id replacement,
 | 
			
		||||
                                                                 volatile id *objectLocation) {
 | 
			
		||||
  return OSAtomicCompareAndSwapPtrBarrier(predicate,
 | 
			
		||||
                                          replacement,
 | 
			
		||||
                                          (void * volatile *)objectLocation);
 | 
			
		||||
}
 | 
			
		||||
#endif  // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
							
								
								
									
										163
									
								
								External/google-plus-ios-sdk/OpenSource/GTMObjC2Runtime.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,163 @@
 | 
			
		||||
//
 | 
			
		||||
//  GTMObjC2Runtime.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2008 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GTMObjC2Runtime.h"
 | 
			
		||||
 | 
			
		||||
#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
#import <stdlib.h>
 | 
			
		||||
#import <string.h>
 | 
			
		||||
 | 
			
		||||
Class object_getClass(id obj) {
 | 
			
		||||
  if (!obj) return NULL;
 | 
			
		||||
  return obj->isa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *class_getName(Class cls) {
 | 
			
		||||
  if (!cls) return "nil";
 | 
			
		||||
  return cls->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL class_conformsToProtocol(Class cls, Protocol *protocol) {
 | 
			
		||||
  // We intentionally don't check cls as it crashes on Leopard so we want
 | 
			
		||||
  // to crash on Tiger as well.
 | 
			
		||||
  // I logged
 | 
			
		||||
  // Radar 5572978 class_conformsToProtocol crashes when arg1 is passed as nil
 | 
			
		||||
  // because it seems odd that this API won't accept nil for cls considering
 | 
			
		||||
  // all the other apis will accept nil args.
 | 
			
		||||
  // If this does get fixed, remember to enable the unit tests.
 | 
			
		||||
  if (!protocol) return NO;
 | 
			
		||||
 | 
			
		||||
  struct objc_protocol_list *protos;
 | 
			
		||||
  for (protos = cls->protocols; protos != NULL; protos = protos->next) {
 | 
			
		||||
    for (long i = 0; i < protos->count; i++) {
 | 
			
		||||
      if ([protos->list[i] conformsTo:protocol]) {
 | 
			
		||||
        return YES;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Class class_getSuperclass(Class cls) {
 | 
			
		||||
  if (!cls) return NULL;
 | 
			
		||||
  return cls->super_class;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL class_respondsToSelector(Class cls, SEL sel) {
 | 
			
		||||
  return class_getInstanceMethod(cls, sel) != nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Method *class_copyMethodList(Class cls, unsigned int *outCount) {
 | 
			
		||||
  if (!cls) return NULL;
 | 
			
		||||
 | 
			
		||||
  unsigned int count = 0;
 | 
			
		||||
  void *iterator = NULL;
 | 
			
		||||
  struct objc_method_list *mlist;
 | 
			
		||||
  Method *methods = NULL;
 | 
			
		||||
  if (outCount) *outCount = 0;
 | 
			
		||||
 | 
			
		||||
  while ( (mlist = class_nextMethodList(cls, &iterator)) ) {
 | 
			
		||||
    if (mlist->method_count == 0) continue;
 | 
			
		||||
    methods = (Method *)realloc(methods,
 | 
			
		||||
                                sizeof(Method) * (count + mlist->method_count + 1));
 | 
			
		||||
    if (!methods) {
 | 
			
		||||
      //Memory alloc failed, so what can we do?
 | 
			
		||||
      return NULL;  // COV_NF_LINE
 | 
			
		||||
    }
 | 
			
		||||
    for (int i = 0; i < mlist->method_count; i++) {
 | 
			
		||||
      methods[i + count] = &mlist->method_list[i];
 | 
			
		||||
    }
 | 
			
		||||
    count += mlist->method_count;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // List must be NULL terminated
 | 
			
		||||
  if (methods) {
 | 
			
		||||
    methods[count] = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (outCount) *outCount = count;
 | 
			
		||||
  return methods;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SEL method_getName(Method method) {
 | 
			
		||||
  if (!method) return NULL;
 | 
			
		||||
  return method->method_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IMP method_getImplementation(Method method) {
 | 
			
		||||
  if (!method) return NULL;
 | 
			
		||||
  return method->method_imp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IMP method_setImplementation(Method method, IMP imp) {
 | 
			
		||||
  // We intentionally don't test method for nil.
 | 
			
		||||
  // Leopard fails here, so should we.
 | 
			
		||||
  // I logged this as Radar:
 | 
			
		||||
  // 5572981 method_setImplementation crashes if you pass nil for the
 | 
			
		||||
  // method arg (arg 1)
 | 
			
		||||
  // because it seems odd that this API won't accept nil for method considering
 | 
			
		||||
  // all the other apis will accept nil args.
 | 
			
		||||
  // If this does get fixed, remember to enable the unit tests.
 | 
			
		||||
  // This method works differently on SnowLeopard than
 | 
			
		||||
  // on Leopard. If you pass in a nil for IMP on SnowLeopard
 | 
			
		||||
  // it doesn't change anything. On Leopard it will. Since
 | 
			
		||||
  // attempting to change a sel to nil is probably an error
 | 
			
		||||
  // we follow the SnowLeopard way of doing things.
 | 
			
		||||
  IMP oldImp = NULL;
 | 
			
		||||
  if (imp) {
 | 
			
		||||
    oldImp = method->method_imp;
 | 
			
		||||
    method->method_imp = imp;
 | 
			
		||||
  }
 | 
			
		||||
  return oldImp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void method_exchangeImplementations(Method m1, Method m2) {
 | 
			
		||||
  if (m1 == m2) return;
 | 
			
		||||
  if (!m1 || !m2) return;
 | 
			
		||||
  IMP imp2 = method_getImplementation(m2);
 | 
			
		||||
  IMP imp1 = method_setImplementation(m1, imp2);
 | 
			
		||||
  method_setImplementation(m2, imp1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct objc_method_description protocol_getMethodDescription(Protocol *p,
 | 
			
		||||
                                                             SEL aSel,
 | 
			
		||||
                                                             BOOL isRequiredMethod,
 | 
			
		||||
                                                             BOOL isInstanceMethod) {
 | 
			
		||||
  struct objc_method_description *descPtr = NULL;
 | 
			
		||||
  // No such thing as required in ObjC1.
 | 
			
		||||
  if (isInstanceMethod) {
 | 
			
		||||
    descPtr = [p descriptionForInstanceMethod:aSel];
 | 
			
		||||
  } else {
 | 
			
		||||
    descPtr = [p descriptionForClassMethod:aSel];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct objc_method_description desc;
 | 
			
		||||
  if (descPtr) {
 | 
			
		||||
    desc = *descPtr;
 | 
			
		||||
  } else {
 | 
			
		||||
    bzero(&desc, sizeof(desc));
 | 
			
		||||
  }
 | 
			
		||||
  return desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL sel_isEqual(SEL lhs, SEL rhs) {
 | 
			
		||||
  // Apple (informally) promises this will work in the future:
 | 
			
		||||
  // http://twitter.com/#!/gparker/status/2400099786
 | 
			
		||||
  return (lhs == rhs) ? YES : NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
 | 
			
		||||
							
								
								
									
										39
									
								
								External/google-plus-ios-sdk/README
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,39 @@
 | 
			
		||||
This Google+ iOS SDK allows users to sign in with Google+, share with Google+,
 | 
			
		||||
and write moments to Google+ history from third-party apps. The SDK contains the
 | 
			
		||||
following files:
 | 
			
		||||
 | 
			
		||||
README  -- This file.
 | 
			
		||||
 | 
			
		||||
Changelog  -- The versions and changes of the SDK.
 | 
			
		||||
 | 
			
		||||
lib/  -- Header files and libraries.
 | 
			
		||||
  GooglePlusShare.h -- Header file to include for sharing with Google+.
 | 
			
		||||
  GooglePlusSignIn.h -- Header file to include for signing into Google+.
 | 
			
		||||
  GooglePlusSignInButton.h -- Header file to include for showing a button to
 | 
			
		||||
                              sign in with Google+.
 | 
			
		||||
  libGooglePlus.a -- Static library built for iOS device to link into your app.
 | 
			
		||||
  libGooglePlusUniversal.a -- Static library built for both iOS device and
 | 
			
		||||
                              simulator to link into your app.
 | 
			
		||||
 | 
			
		||||
OpenSource/  -- Google open source files used by the SDK. Add all files in this
 | 
			
		||||
                directory into your project if you're not already using them.
 | 
			
		||||
                Also see comments for the subdirectory below.
 | 
			
		||||
  GTL/ -- Google open source files only used by the sample app. Include them
 | 
			
		||||
          into your project if you're going to use the same functionality,
 | 
			
		||||
          e.g. Add Moments.
 | 
			
		||||
 | 
			
		||||
Resources/  -- Resources that can be used in your app.
 | 
			
		||||
               For |GooglePlusSignInButton|, the google_plus_sign_in*.png images
 | 
			
		||||
               are required.
 | 
			
		||||
  google_plus_share.png -- 82x24 Google+ share button image.
 | 
			
		||||
  google_plus_share_large.png -- 112x32 Google+ share button image.
 | 
			
		||||
  google_plus_share@2x.png -- 164x48 Google+ share button image.
 | 
			
		||||
  google_plus_share_large@2x.png -- 224x64 Google+ share button image.
 | 
			
		||||
  google_plus_sign_in.png -- 120x32 Google+ sign-in button image.
 | 
			
		||||
  google_plus_sign_in_wide.png --220x32 Wide Google+ sign-in button image.
 | 
			
		||||
  google_plus_sign_in@2x.png -- 240x64 Google+ sign-in button image.
 | 
			
		||||
  google_plus_sign_in_wide@2x.png -- 440x64 Wide Google+ sign-in button image.
 | 
			
		||||
 | 
			
		||||
SampleCode/  -- Sample code for your reference only.
 | 
			
		||||
                Do not include this in your project.
 | 
			
		||||
   GooglePlusSample.xcodeproj/  -- The Xcode project.
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_share.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_share@2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_share_large.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_share_large@2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_sign_in.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_sign_in@2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_sign_in_wide.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								External/google-plus-ios-sdk/Resources/google_plus_sign_in_wide@2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										74
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSample-Info.plist
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,74 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
	<key>CFBundleDevelopmentRegion</key>
 | 
			
		||||
	<string>en</string>
 | 
			
		||||
	<key>CFBundleDisplayName</key>
 | 
			
		||||
	<string>${PRODUCT_NAME}</string>
 | 
			
		||||
	<key>CFBundleExecutable</key>
 | 
			
		||||
	<string>${EXECUTABLE_NAME}</string>
 | 
			
		||||
	<key>CFBundleIconFiles</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<string>Icon.png</string>
 | 
			
		||||
		<string>Icon@2x.png</string>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>CFBundleIcons</key>
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>CFBundlePrimaryIcon</key>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>CFBundleIconFiles</key>
 | 
			
		||||
			<array>
 | 
			
		||||
				<string>Icon.png</string>
 | 
			
		||||
				<string>Icon@2x.png</string>
 | 
			
		||||
			</array>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</dict>
 | 
			
		||||
	<key>CFBundleIdentifier</key>
 | 
			
		||||
	<string>com.google.${PRODUCT_NAME:rfc1034identifier}</string>
 | 
			
		||||
	<key>CFBundleInfoDictionaryVersion</key>
 | 
			
		||||
	<string>6.0</string>
 | 
			
		||||
	<key>CFBundleName</key>
 | 
			
		||||
	<string>${PRODUCT_NAME}</string>
 | 
			
		||||
	<key>CFBundlePackageType</key>
 | 
			
		||||
	<string>APPL</string>
 | 
			
		||||
	<key>CFBundleShortVersionString</key>
 | 
			
		||||
	<string>1.0</string>
 | 
			
		||||
	<key>CFBundleSignature</key>
 | 
			
		||||
	<string>????</string>
 | 
			
		||||
	<key>CFBundleURLTypes</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>CFBundleTypeRole</key>
 | 
			
		||||
			<string>Editor</string>
 | 
			
		||||
			<key>CFBundleURLName</key>
 | 
			
		||||
			<string>com.google.GooglePlusSample</string>
 | 
			
		||||
			<key>CFBundleURLSchemes</key>
 | 
			
		||||
			<array>
 | 
			
		||||
				<string>com.google.GooglePlusSample</string>
 | 
			
		||||
			</array>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>CFBundleVersion</key>
 | 
			
		||||
	<string>1.0</string>
 | 
			
		||||
	<key>LSRequiresIPhoneOS</key>
 | 
			
		||||
	<true/>
 | 
			
		||||
	<key>UIRequiredDeviceCapabilities</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<string>armv7</string>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>UISupportedInterfaceOrientations</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<string>UIInterfaceOrientationPortrait</string>
 | 
			
		||||
		<string>UIInterfaceOrientationLandscapeLeft</string>
 | 
			
		||||
		<string>UIInterfaceOrientationLandscapeRight</string>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>UISupportedInterfaceOrientations~ipad</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<string>UIInterfaceOrientationPortrait</string>
 | 
			
		||||
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
 | 
			
		||||
		<string>UIInterfaceOrientationLandscapeLeft</string>
 | 
			
		||||
		<string>UIInterfaceOrientationLandscapeRight</string>
 | 
			
		||||
	</array>
 | 
			
		||||
</dict>
 | 
			
		||||
</plist>
 | 
			
		||||
							
								
								
									
										14
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSample-Prefix.pch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,14 @@
 | 
			
		||||
//
 | 
			
		||||
// Prefix header for all source files of the 'GooglePlusSample' target in the 'GooglePlusSample' project
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Availability.h>
 | 
			
		||||
 | 
			
		||||
#ifndef __IPHONE_4_0
 | 
			
		||||
#warning "This project uses features only available in iOS SDK 4.0 and later."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __OBJC__
 | 
			
		||||
  #import <UIKit/UIKit.h>
 | 
			
		||||
  #import <Foundation/Foundation.h>
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										648
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.pbxproj
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,648 @@
 | 
			
		||||
// !$*UTF8*$!
 | 
			
		||||
{
 | 
			
		||||
	archiveVersion = 1;
 | 
			
		||||
	classes = {
 | 
			
		||||
	};
 | 
			
		||||
	objectVersion = 46;
 | 
			
		||||
	objects = {
 | 
			
		||||
 | 
			
		||||
/* Begin PBXBuildFile section */
 | 
			
		||||
		0043C79F1580045B000DF02E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0043C79E1580045B000DF02E /* UIKit.framework */; };
 | 
			
		||||
		0043C7A11580045B000DF02E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0043C7A01580045B000DF02E /* Foundation.framework */; };
 | 
			
		||||
		0043C7A31580045B000DF02E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0043C7A21580045B000DF02E /* CoreGraphics.framework */; };
 | 
			
		||||
		00F70E83158006DC0077799E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 00F70E82158006DC0077799E /* main.m */; };
 | 
			
		||||
		00F70E99158007D90077799E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00F70E98158007D90077799E /* Security.framework */; };
 | 
			
		||||
		00F70E9B158008040077799E /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00F70E9A158008040077799E /* SystemConfiguration.framework */; };
 | 
			
		||||
		0C52D6F8158BAB1F001510E6 /* button_background.png in Resources */ = {isa = PBXBuildFile; fileRef = 0C52D6F7158BAB1F001510E6 /* button_background.png */; };
 | 
			
		||||
		D973B402158ABC1F0083A4B5 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D973B401158ABC1F0083A4B5 /* MessageUI.framework */; };
 | 
			
		||||
		D98254A815990D8D0060CA47 /* Icon_2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D98254A615990D8D0060CA47 /* Icon_2x.png */; };
 | 
			
		||||
		D98254A915990D8D0060CA47 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = D98254A715990D8D0060CA47 /* Icon.png */; };
 | 
			
		||||
		D98254F2159937730060CA47 /* GTLPlusPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = D98254F1159937730060CA47 /* GTLPlusPerson.m */; };
 | 
			
		||||
		D9EE743D158A8BD400EC1D05 /* google_plus_share_large.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7435158A8BD400EC1D05 /* google_plus_share_large.png */; };
 | 
			
		||||
		D9EE743E158A8BD400EC1D05 /* google_plus_share_large@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7436158A8BD400EC1D05 /* google_plus_share_large@2x.png */; };
 | 
			
		||||
		D9EE743F158A8BD400EC1D05 /* google_plus_share.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7437158A8BD400EC1D05 /* google_plus_share.png */; };
 | 
			
		||||
		D9EE7440158A8BD400EC1D05 /* google_plus_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE7438158A8BD400EC1D05 /* google_plus_share@2x.png */; };
 | 
			
		||||
		D9EE748D158A8C0E00EC1D05 /* GTLBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7449158A8C0E00EC1D05 /* GTLBase64.m */; };
 | 
			
		||||
		D9EE748E158A8C0E00EC1D05 /* GTLBatchQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE744B158A8C0E00EC1D05 /* GTLBatchQuery.m */; };
 | 
			
		||||
		D9EE748F158A8C0E00EC1D05 /* GTLBatchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE744D158A8C0E00EC1D05 /* GTLBatchResult.m */; };
 | 
			
		||||
		D9EE7490158A8C0E00EC1D05 /* GTLDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE744F158A8C0E00EC1D05 /* GTLDateTime.m */; };
 | 
			
		||||
		D9EE7491158A8C0E00EC1D05 /* GTLErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7452158A8C0E00EC1D05 /* GTLErrorObject.m */; };
 | 
			
		||||
		D9EE7492158A8C0E00EC1D05 /* GTLFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7454158A8C0E00EC1D05 /* GTLFramework.m */; };
 | 
			
		||||
		D9EE7493158A8C0E00EC1D05 /* GTLJSONParser.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7456158A8C0E00EC1D05 /* GTLJSONParser.m */; };
 | 
			
		||||
		D9EE7494158A8C0E00EC1D05 /* GTLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7458158A8C0E00EC1D05 /* GTLObject.m */; };
 | 
			
		||||
		D9EE7495158A8C0E00EC1D05 /* GTLPlusConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE745C158A8C0E00EC1D05 /* GTLPlusConstants.m */; };
 | 
			
		||||
		D9EE7496158A8C0E00EC1D05 /* GTLPlusItemScope.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE745E158A8C0E00EC1D05 /* GTLPlusItemScope.m */; };
 | 
			
		||||
		D9EE7497158A8C0E00EC1D05 /* GTLPlusMoment.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7460158A8C0E00EC1D05 /* GTLPlusMoment.m */; };
 | 
			
		||||
		D9EE7499158A8C0E00EC1D05 /* GTLQueryPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7464158A8C0E00EC1D05 /* GTLQueryPlus.m */; };
 | 
			
		||||
		D9EE749A158A8C0E00EC1D05 /* GTLServicePlus.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7466158A8C0E00EC1D05 /* GTLServicePlus.m */; };
 | 
			
		||||
		D9EE749B158A8C0E00EC1D05 /* GTLQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7468158A8C0E00EC1D05 /* GTLQuery.m */; };
 | 
			
		||||
		D9EE749C158A8C0E00EC1D05 /* GTLRuntimeCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE746A158A8C0E00EC1D05 /* GTLRuntimeCommon.m */; };
 | 
			
		||||
		D9EE749D158A8C0E00EC1D05 /* GTLService.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE746C158A8C0E00EC1D05 /* GTLService.m */; };
 | 
			
		||||
		D9EE749E158A8C0E00EC1D05 /* GTLUploadParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE746F158A8C0E00EC1D05 /* GTLUploadParameters.m */; };
 | 
			
		||||
		D9EE749F158A8C0E00EC1D05 /* GTLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7471158A8C0E00EC1D05 /* GTLUtilities.m */; };
 | 
			
		||||
		D9EE74A0158A8C0E00EC1D05 /* GTMHTTPFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7475158A8C0E00EC1D05 /* GTMHTTPFetcher.m */; };
 | 
			
		||||
		D9EE74A1158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7477158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.m */; };
 | 
			
		||||
		D9EE74A2158A8C0E00EC1D05 /* GTMHTTPFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7479158A8C0E00EC1D05 /* GTMHTTPFetcherService.m */; };
 | 
			
		||||
		D9EE74A3158A8C0E00EC1D05 /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE747B158A8C0E00EC1D05 /* GTMHTTPFetchHistory.m */; };
 | 
			
		||||
		D9EE74A4158A8C0E00EC1D05 /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE747D158A8C0E00EC1D05 /* GTMLogger.m */; };
 | 
			
		||||
		D9EE74A5158A8C0E00EC1D05 /* GTMMethodCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE747F158A8C0E00EC1D05 /* GTMMethodCheck.m */; };
 | 
			
		||||
		D9EE74A6158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7481158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.m */; };
 | 
			
		||||
		D9EE74A7158A8C0E00EC1D05 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7483158A8C0E00EC1D05 /* GTMNSString+URLArguments.m */; };
 | 
			
		||||
		D9EE74A8158A8C0E00EC1D05 /* GTMOAuth2Authentication.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7485158A8C0E00EC1D05 /* GTMOAuth2Authentication.m */; };
 | 
			
		||||
		D9EE74A9158A8C0E00EC1D05 /* GTMOAuth2SignIn.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7487158A8C0E00EC1D05 /* GTMOAuth2SignIn.m */; };
 | 
			
		||||
		D9EE74AA158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE7489158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.m */; };
 | 
			
		||||
		D9EE74AB158A8C0E00EC1D05 /* GTMOAuth2ViewTouch.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9EE748A158A8C0E00EC1D05 /* GTMOAuth2ViewTouch.xib */; };
 | 
			
		||||
		D9EE74AC158A8C0E00EC1D05 /* GTMObjC2Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE748C158A8C0E00EC1D05 /* GTMObjC2Runtime.m */; };
 | 
			
		||||
		D9EE74B0158A8D1E00EC1D05 /* libGooglePlusUniversal.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9EE74AE158A8D1E00EC1D05 /* libGooglePlusUniversal.a */; };
 | 
			
		||||
		D9EE74C2158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE74B4158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.m */; };
 | 
			
		||||
		D9EE74C3158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE74B6158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.m */; };
 | 
			
		||||
		D9EE74C4158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74B7158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.xib */; };
 | 
			
		||||
		D9EE74C5158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE74B9158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m */; };
 | 
			
		||||
		D9EE74C6158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74BA158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.xib */; };
 | 
			
		||||
		D9EE74C7158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE74BC158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m */; };
 | 
			
		||||
		D9EE74C8158A8E0500EC1D05 /* GooglePlusSampleShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74BD158A8E0500EC1D05 /* GooglePlusSampleShareViewController.xib */; };
 | 
			
		||||
		D9EE74C9158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9EE74BF158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m */; };
 | 
			
		||||
		D9EE74CA158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74C0158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.xib */; };
 | 
			
		||||
		D9EE74CD158A8E2900EC1D05 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74CB158A8E2900EC1D05 /* InfoPlist.strings */; };
 | 
			
		||||
		D9EE74E4158A9A7D00EC1D05 /* google_plus_sign_in_wide.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74E0158A9A7D00EC1D05 /* google_plus_sign_in_wide.png */; };
 | 
			
		||||
		D9EE74E5158A9A7D00EC1D05 /* google_plus_sign_in_wide@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74E1158A9A7D00EC1D05 /* google_plus_sign_in_wide@2x.png */; };
 | 
			
		||||
		D9EE74E6158A9A7D00EC1D05 /* google_plus_sign_in.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74E2158A9A7D00EC1D05 /* google_plus_sign_in.png */; };
 | 
			
		||||
		D9EE74E7158A9A7D00EC1D05 /* google_plus_sign_in@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9EE74E3158A9A7D00EC1D05 /* google_plus_sign_in@2x.png */; };
 | 
			
		||||
/* End PBXBuildFile section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXFileReference section */
 | 
			
		||||
		0043C79A1580045B000DF02E /* GooglePlusSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GooglePlusSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
			
		||||
		0043C79E1580045B000DF02E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		0043C7A01580045B000DF02E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		0043C7A21580045B000DF02E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		00F70E82158006DC0077799E /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		00F70E98158007D90077799E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		00F70E9A158008040077799E /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		0C52D6F7158BAB1F001510E6 /* button_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background.png; path = Resources/button_background.png; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D973B401158ABC1F0083A4B5 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
 | 
			
		||||
		D98254A615990D8D0060CA47 /* Icon_2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_2x.png; path = Resources/Icon_2x.png; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D98254A715990D8D0060CA47 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icon.png; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D98254F0159937730060CA47 /* GTLPlusPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusPerson.h; sourceTree = "<group>"; };
 | 
			
		||||
		D98254F1159937730060CA47 /* GTLPlusPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusPerson.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7431158A8BAE00EC1D05 /* GooglePlusShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusShare.h; path = ../lib/GooglePlusShare.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7432158A8BAE00EC1D05 /* GooglePlusSignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusSignIn.h; path = ../lib/GooglePlusSignIn.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7433158A8BAE00EC1D05 /* GooglePlusSignInButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GooglePlusSignInButton.h; path = ../lib/GooglePlusSignInButton.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7435158A8BD400EC1D05 /* google_plus_share_large.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_share_large.png; path = ../Resources/google_plus_share_large.png; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7436158A8BD400EC1D05 /* google_plus_share_large@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "google_plus_share_large@2x.png"; path = "../Resources/google_plus_share_large@2x.png"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7437158A8BD400EC1D05 /* google_plus_share.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_share.png; path = ../Resources/google_plus_share.png; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7438158A8BD400EC1D05 /* google_plus_share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "google_plus_share@2x.png"; path = "../Resources/google_plus_share@2x.png"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7448158A8C0E00EC1D05 /* GTLBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBase64.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7449158A8C0E00EC1D05 /* GTLBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBase64.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744A158A8C0E00EC1D05 /* GTLBatchQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchQuery.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744B158A8C0E00EC1D05 /* GTLBatchQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchQuery.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744C158A8C0E00EC1D05 /* GTLBatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLBatchResult.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744D158A8C0E00EC1D05 /* GTLBatchResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLBatchResult.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744E158A8C0E00EC1D05 /* GTLDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDateTime.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE744F158A8C0E00EC1D05 /* GTLDateTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLDateTime.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7450158A8C0E00EC1D05 /* GTLDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLDefines.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7451158A8C0E00EC1D05 /* GTLErrorObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLErrorObject.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7452158A8C0E00EC1D05 /* GTLErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLErrorObject.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7453158A8C0E00EC1D05 /* GTLFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLFramework.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7454158A8C0E00EC1D05 /* GTLFramework.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLFramework.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7455158A8C0E00EC1D05 /* GTLJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLJSONParser.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7456158A8C0E00EC1D05 /* GTLJSONParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLJSONParser.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7457158A8C0E00EC1D05 /* GTLObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLObject.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7458158A8C0E00EC1D05 /* GTLObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLObject.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745A158A8C0E00EC1D05 /* GTLPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlus.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745B158A8C0E00EC1D05 /* GTLPlusConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusConstants.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745C158A8C0E00EC1D05 /* GTLPlusConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusConstants.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745D158A8C0E00EC1D05 /* GTLPlusItemScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusItemScope.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745E158A8C0E00EC1D05 /* GTLPlusItemScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusItemScope.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE745F158A8C0E00EC1D05 /* GTLPlusMoment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLPlusMoment.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7460158A8C0E00EC1D05 /* GTLPlusMoment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLPlusMoment.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7463158A8C0E00EC1D05 /* GTLQueryPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQueryPlus.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7464158A8C0E00EC1D05 /* GTLQueryPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQueryPlus.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7465158A8C0E00EC1D05 /* GTLServicePlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLServicePlus.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7466158A8C0E00EC1D05 /* GTLServicePlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLServicePlus.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7467158A8C0E00EC1D05 /* GTLQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLQuery.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7468158A8C0E00EC1D05 /* GTLQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLQuery.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7469158A8C0E00EC1D05 /* GTLRuntimeCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLRuntimeCommon.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746A158A8C0E00EC1D05 /* GTLRuntimeCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLRuntimeCommon.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746B158A8C0E00EC1D05 /* GTLService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLService.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746C158A8C0E00EC1D05 /* GTLService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLService.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746D158A8C0E00EC1D05 /* GTLTargetNamespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLTargetNamespace.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746E158A8C0E00EC1D05 /* GTLUploadParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUploadParameters.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE746F158A8C0E00EC1D05 /* GTLUploadParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUploadParameters.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7470158A8C0E00EC1D05 /* GTLUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTLUtilities.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7471158A8C0E00EC1D05 /* GTLUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTLUtilities.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7472158A8C0E00EC1D05 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7473158A8C0E00EC1D05 /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7474158A8C0E00EC1D05 /* GTMHTTPFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcher.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7475158A8C0E00EC1D05 /* GTMHTTPFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcher.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7476158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherLogging.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7477158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherLogging.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7478158A8C0E00EC1D05 /* GTMHTTPFetcherService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcherService.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7479158A8C0E00EC1D05 /* GTMHTTPFetcherService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcherService.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747A158A8C0E00EC1D05 /* GTMHTTPFetchHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetchHistory.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747B158A8C0E00EC1D05 /* GTMHTTPFetchHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetchHistory.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747C158A8C0E00EC1D05 /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747D158A8C0E00EC1D05 /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747E158A8C0E00EC1D05 /* GTMMethodCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMMethodCheck.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE747F158A8C0E00EC1D05 /* GTMMethodCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMMethodCheck.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7480158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSDictionary+URLArguments.h"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7481158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSDictionary+URLArguments.m"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7482158A8C0E00EC1D05 /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSString+URLArguments.h"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7483158A8C0E00EC1D05 /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+URLArguments.m"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7484158A8C0E00EC1D05 /* GTMOAuth2Authentication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2Authentication.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7485158A8C0E00EC1D05 /* GTMOAuth2Authentication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2Authentication.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7486158A8C0E00EC1D05 /* GTMOAuth2SignIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2SignIn.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7487158A8C0E00EC1D05 /* GTMOAuth2SignIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2SignIn.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7488158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2ViewControllerTouch.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE7489158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2ViewControllerTouch.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE748A158A8C0E00EC1D05 /* GTMOAuth2ViewTouch.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GTMOAuth2ViewTouch.xib; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE748B158A8C0E00EC1D05 /* GTMObjC2Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMObjC2Runtime.h; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE748C158A8C0E00EC1D05 /* GTMObjC2Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMObjC2Runtime.m; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74AD158A8D1E00EC1D05 /* libGooglePlus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libGooglePlus.a; path = ../lib/libGooglePlus.a; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74AE158A8D1E00EC1D05 /* libGooglePlusUniversal.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libGooglePlusUniversal.a; path = ../lib/libGooglePlusUniversal.a; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74B1158A8E0500EC1D05 /* GooglePlusSample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GooglePlusSample-Info.plist"; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B2158A8E0500EC1D05 /* GooglePlusSample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GooglePlusSample-Prefix.pch"; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B3158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSampleAppDelegate.h; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B4158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GooglePlusSampleAppDelegate.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B5158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSampleMasterViewController.h; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B6158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GooglePlusSampleMasterViewController.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B7158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GooglePlusSampleMasterViewController.xib; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B8158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSampleMomentsViewController.h; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74B9158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GooglePlusSampleMomentsViewController.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BA158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GooglePlusSampleMomentsViewController.xib; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BB158A8E0500EC1D05 /* GooglePlusSampleShareViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSampleShareViewController.h; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BC158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GooglePlusSampleShareViewController.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BD158A8E0500EC1D05 /* GooglePlusSampleShareViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GooglePlusSampleShareViewController.xib; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BE158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GooglePlusSampleSignInViewController.h; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74BF158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GooglePlusSampleSignInViewController.m; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74C0158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GooglePlusSampleSignInViewController.xib; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74CC158A8E2900EC1D05 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; };
 | 
			
		||||
		D9EE74E0158A9A7D00EC1D05 /* google_plus_sign_in_wide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_sign_in_wide.png; path = ../Resources/google_plus_sign_in_wide.png; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74E1158A9A7D00EC1D05 /* google_plus_sign_in_wide@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "google_plus_sign_in_wide@2x.png"; path = "../Resources/google_plus_sign_in_wide@2x.png"; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74E2158A9A7D00EC1D05 /* google_plus_sign_in.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = google_plus_sign_in.png; path = ../Resources/google_plus_sign_in.png; sourceTree = "<group>"; };
 | 
			
		||||
		D9EE74E3158A9A7D00EC1D05 /* google_plus_sign_in@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "google_plus_sign_in@2x.png"; path = "../Resources/google_plus_sign_in@2x.png"; sourceTree = "<group>"; };
 | 
			
		||||
/* End PBXFileReference section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXFrameworksBuildPhase section */
 | 
			
		||||
		0043C7971580045B000DF02E /* Frameworks */ = {
 | 
			
		||||
			isa = PBXFrameworksBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				D973B402158ABC1F0083A4B5 /* MessageUI.framework in Frameworks */,
 | 
			
		||||
				00F70E9B158008040077799E /* SystemConfiguration.framework in Frameworks */,
 | 
			
		||||
				00F70E99158007D90077799E /* Security.framework in Frameworks */,
 | 
			
		||||
				0043C79F1580045B000DF02E /* UIKit.framework in Frameworks */,
 | 
			
		||||
				0043C7A11580045B000DF02E /* Foundation.framework in Frameworks */,
 | 
			
		||||
				0043C7A31580045B000DF02E /* CoreGraphics.framework in Frameworks */,
 | 
			
		||||
				D9EE74B0158A8D1E00EC1D05 /* libGooglePlusUniversal.a in Frameworks */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXFrameworksBuildPhase section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXGroup section */
 | 
			
		||||
		0043C78F1580045B000DF02E = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE7434158A8BB500EC1D05 /* GooglePlusSDK */,
 | 
			
		||||
				D9EE7446158A8C0E00EC1D05 /* GoogleOpenSource */,
 | 
			
		||||
				0043C7A41580045B000DF02E /* GooglePlusSample */,
 | 
			
		||||
				0043C79D1580045B000DF02E /* Frameworks */,
 | 
			
		||||
				0043C79B1580045B000DF02E /* Products */,
 | 
			
		||||
			);
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		0043C79B1580045B000DF02E /* Products */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				0043C79A1580045B000DF02E /* GooglePlusSample.app */,
 | 
			
		||||
			);
 | 
			
		||||
			name = Products;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		0043C79D1580045B000DF02E /* Frameworks */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D973B401158ABC1F0083A4B5 /* MessageUI.framework */,
 | 
			
		||||
				00F70E9A158008040077799E /* SystemConfiguration.framework */,
 | 
			
		||||
				00F70E98158007D90077799E /* Security.framework */,
 | 
			
		||||
				0043C79E1580045B000DF02E /* UIKit.framework */,
 | 
			
		||||
				0043C7A01580045B000DF02E /* Foundation.framework */,
 | 
			
		||||
				0043C7A21580045B000DF02E /* CoreGraphics.framework */,
 | 
			
		||||
			);
 | 
			
		||||
			name = Frameworks;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		0043C7A41580045B000DF02E /* GooglePlusSample */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE74B3158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.h */,
 | 
			
		||||
				D9EE74B4158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.m */,
 | 
			
		||||
				D9EE74B5158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.h */,
 | 
			
		||||
				D9EE74B6158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.m */,
 | 
			
		||||
				D9EE74B7158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.xib */,
 | 
			
		||||
				D9EE74B8158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.h */,
 | 
			
		||||
				D9EE74B9158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m */,
 | 
			
		||||
				D9EE74BA158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.xib */,
 | 
			
		||||
				D9EE74BB158A8E0500EC1D05 /* GooglePlusSampleShareViewController.h */,
 | 
			
		||||
				D9EE74BC158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m */,
 | 
			
		||||
				D9EE74BD158A8E0500EC1D05 /* GooglePlusSampleShareViewController.xib */,
 | 
			
		||||
				D9EE74BE158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.h */,
 | 
			
		||||
				D9EE74BF158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m */,
 | 
			
		||||
				D9EE74C0158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.xib */,
 | 
			
		||||
				D98254AB15990DBC0060CA47 /* Resources */,
 | 
			
		||||
				0043C7A51580045B000DF02E /* Supporting Files */,
 | 
			
		||||
			);
 | 
			
		||||
			path = GooglePlusSample;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		0043C7A51580045B000DF02E /* Supporting Files */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				00F70E82158006DC0077799E /* main.m */,
 | 
			
		||||
				D9EE74CB158A8E2900EC1D05 /* InfoPlist.strings */,
 | 
			
		||||
				D9EE74B1158A8E0500EC1D05 /* GooglePlusSample-Info.plist */,
 | 
			
		||||
				D9EE74B2158A8E0500EC1D05 /* GooglePlusSample-Prefix.pch */,
 | 
			
		||||
			);
 | 
			
		||||
			name = "Supporting Files";
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D98254AB15990DBC0060CA47 /* Resources */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D98254A615990D8D0060CA47 /* Icon_2x.png */,
 | 
			
		||||
				D98254A715990D8D0060CA47 /* Icon.png */,
 | 
			
		||||
				0C52D6F7158BAB1F001510E6 /* button_background.png */,
 | 
			
		||||
			);
 | 
			
		||||
			name = Resources;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D9EE7434158A8BB500EC1D05 /* GooglePlusSDK */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE7431158A8BAE00EC1D05 /* GooglePlusShare.h */,
 | 
			
		||||
				D9EE7432158A8BAE00EC1D05 /* GooglePlusSignIn.h */,
 | 
			
		||||
				D9EE7433158A8BAE00EC1D05 /* GooglePlusSignInButton.h */,
 | 
			
		||||
				D9EE74AD158A8D1E00EC1D05 /* libGooglePlus.a */,
 | 
			
		||||
				D9EE74AE158A8D1E00EC1D05 /* libGooglePlusUniversal.a */,
 | 
			
		||||
				D9EE7445158A8BDB00EC1D05 /* Resources */,
 | 
			
		||||
			);
 | 
			
		||||
			name = GooglePlusSDK;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D9EE7445158A8BDB00EC1D05 /* Resources */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE74E0158A9A7D00EC1D05 /* google_plus_sign_in_wide.png */,
 | 
			
		||||
				D9EE74E1158A9A7D00EC1D05 /* google_plus_sign_in_wide@2x.png */,
 | 
			
		||||
				D9EE74E2158A9A7D00EC1D05 /* google_plus_sign_in.png */,
 | 
			
		||||
				D9EE74E3158A9A7D00EC1D05 /* google_plus_sign_in@2x.png */,
 | 
			
		||||
				D9EE7435158A8BD400EC1D05 /* google_plus_share_large.png */,
 | 
			
		||||
				D9EE7436158A8BD400EC1D05 /* google_plus_share_large@2x.png */,
 | 
			
		||||
				D9EE7437158A8BD400EC1D05 /* google_plus_share.png */,
 | 
			
		||||
				D9EE7438158A8BD400EC1D05 /* google_plus_share@2x.png */,
 | 
			
		||||
			);
 | 
			
		||||
			name = Resources;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D9EE7446158A8C0E00EC1D05 /* GoogleOpenSource */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE7447158A8C0E00EC1D05 /* GTL */,
 | 
			
		||||
				D9EE7472158A8C0E00EC1D05 /* GTMDefines.h */,
 | 
			
		||||
				D9EE7473158A8C0E00EC1D05 /* GTMGarbageCollection.h */,
 | 
			
		||||
				D9EE7474158A8C0E00EC1D05 /* GTMHTTPFetcher.h */,
 | 
			
		||||
				D9EE7475158A8C0E00EC1D05 /* GTMHTTPFetcher.m */,
 | 
			
		||||
				D9EE7476158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.h */,
 | 
			
		||||
				D9EE7477158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.m */,
 | 
			
		||||
				D9EE7478158A8C0E00EC1D05 /* GTMHTTPFetcherService.h */,
 | 
			
		||||
				D9EE7479158A8C0E00EC1D05 /* GTMHTTPFetcherService.m */,
 | 
			
		||||
				D9EE747A158A8C0E00EC1D05 /* GTMHTTPFetchHistory.h */,
 | 
			
		||||
				D9EE747B158A8C0E00EC1D05 /* GTMHTTPFetchHistory.m */,
 | 
			
		||||
				D9EE747C158A8C0E00EC1D05 /* GTMLogger.h */,
 | 
			
		||||
				D9EE747D158A8C0E00EC1D05 /* GTMLogger.m */,
 | 
			
		||||
				D9EE747E158A8C0E00EC1D05 /* GTMMethodCheck.h */,
 | 
			
		||||
				D9EE747F158A8C0E00EC1D05 /* GTMMethodCheck.m */,
 | 
			
		||||
				D9EE7480158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.h */,
 | 
			
		||||
				D9EE7481158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.m */,
 | 
			
		||||
				D9EE7482158A8C0E00EC1D05 /* GTMNSString+URLArguments.h */,
 | 
			
		||||
				D9EE7483158A8C0E00EC1D05 /* GTMNSString+URLArguments.m */,
 | 
			
		||||
				D9EE7484158A8C0E00EC1D05 /* GTMOAuth2Authentication.h */,
 | 
			
		||||
				D9EE7485158A8C0E00EC1D05 /* GTMOAuth2Authentication.m */,
 | 
			
		||||
				D9EE7486158A8C0E00EC1D05 /* GTMOAuth2SignIn.h */,
 | 
			
		||||
				D9EE7487158A8C0E00EC1D05 /* GTMOAuth2SignIn.m */,
 | 
			
		||||
				D9EE7488158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.h */,
 | 
			
		||||
				D9EE7489158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.m */,
 | 
			
		||||
				D9EE748A158A8C0E00EC1D05 /* GTMOAuth2ViewTouch.xib */,
 | 
			
		||||
				D9EE748B158A8C0E00EC1D05 /* GTMObjC2Runtime.h */,
 | 
			
		||||
				D9EE748C158A8C0E00EC1D05 /* GTMObjC2Runtime.m */,
 | 
			
		||||
			);
 | 
			
		||||
			name = GoogleOpenSource;
 | 
			
		||||
			path = ../OpenSource;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D9EE7447158A8C0E00EC1D05 /* GTL */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE7459158A8C0E00EC1D05 /* GTLPlus */,
 | 
			
		||||
				D9EE7448158A8C0E00EC1D05 /* GTLBase64.h */,
 | 
			
		||||
				D9EE7449158A8C0E00EC1D05 /* GTLBase64.m */,
 | 
			
		||||
				D9EE744A158A8C0E00EC1D05 /* GTLBatchQuery.h */,
 | 
			
		||||
				D9EE744B158A8C0E00EC1D05 /* GTLBatchQuery.m */,
 | 
			
		||||
				D9EE744C158A8C0E00EC1D05 /* GTLBatchResult.h */,
 | 
			
		||||
				D9EE744D158A8C0E00EC1D05 /* GTLBatchResult.m */,
 | 
			
		||||
				D9EE744E158A8C0E00EC1D05 /* GTLDateTime.h */,
 | 
			
		||||
				D9EE744F158A8C0E00EC1D05 /* GTLDateTime.m */,
 | 
			
		||||
				D9EE7450158A8C0E00EC1D05 /* GTLDefines.h */,
 | 
			
		||||
				D9EE7451158A8C0E00EC1D05 /* GTLErrorObject.h */,
 | 
			
		||||
				D9EE7452158A8C0E00EC1D05 /* GTLErrorObject.m */,
 | 
			
		||||
				D9EE7453158A8C0E00EC1D05 /* GTLFramework.h */,
 | 
			
		||||
				D9EE7454158A8C0E00EC1D05 /* GTLFramework.m */,
 | 
			
		||||
				D9EE7455158A8C0E00EC1D05 /* GTLJSONParser.h */,
 | 
			
		||||
				D9EE7456158A8C0E00EC1D05 /* GTLJSONParser.m */,
 | 
			
		||||
				D9EE7457158A8C0E00EC1D05 /* GTLObject.h */,
 | 
			
		||||
				D9EE7458158A8C0E00EC1D05 /* GTLObject.m */,
 | 
			
		||||
				D9EE7467158A8C0E00EC1D05 /* GTLQuery.h */,
 | 
			
		||||
				D9EE7468158A8C0E00EC1D05 /* GTLQuery.m */,
 | 
			
		||||
				D9EE7469158A8C0E00EC1D05 /* GTLRuntimeCommon.h */,
 | 
			
		||||
				D9EE746A158A8C0E00EC1D05 /* GTLRuntimeCommon.m */,
 | 
			
		||||
				D9EE746B158A8C0E00EC1D05 /* GTLService.h */,
 | 
			
		||||
				D9EE746C158A8C0E00EC1D05 /* GTLService.m */,
 | 
			
		||||
				D9EE746D158A8C0E00EC1D05 /* GTLTargetNamespace.h */,
 | 
			
		||||
				D9EE746E158A8C0E00EC1D05 /* GTLUploadParameters.h */,
 | 
			
		||||
				D9EE746F158A8C0E00EC1D05 /* GTLUploadParameters.m */,
 | 
			
		||||
				D9EE7470158A8C0E00EC1D05 /* GTLUtilities.h */,
 | 
			
		||||
				D9EE7471158A8C0E00EC1D05 /* GTLUtilities.m */,
 | 
			
		||||
			);
 | 
			
		||||
			path = GTL;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		D9EE7459158A8C0E00EC1D05 /* GTLPlus */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE745A158A8C0E00EC1D05 /* GTLPlus.h */,
 | 
			
		||||
				D9EE745B158A8C0E00EC1D05 /* GTLPlusConstants.h */,
 | 
			
		||||
				D9EE745C158A8C0E00EC1D05 /* GTLPlusConstants.m */,
 | 
			
		||||
				D9EE745D158A8C0E00EC1D05 /* GTLPlusItemScope.h */,
 | 
			
		||||
				D9EE745E158A8C0E00EC1D05 /* GTLPlusItemScope.m */,
 | 
			
		||||
				D9EE745F158A8C0E00EC1D05 /* GTLPlusMoment.h */,
 | 
			
		||||
				D9EE7460158A8C0E00EC1D05 /* GTLPlusMoment.m */,
 | 
			
		||||
				D98254F0159937730060CA47 /* GTLPlusPerson.h */,
 | 
			
		||||
				D98254F1159937730060CA47 /* GTLPlusPerson.m */,
 | 
			
		||||
				D9EE7463158A8C0E00EC1D05 /* GTLQueryPlus.h */,
 | 
			
		||||
				D9EE7464158A8C0E00EC1D05 /* GTLQueryPlus.m */,
 | 
			
		||||
				D9EE7465158A8C0E00EC1D05 /* GTLServicePlus.h */,
 | 
			
		||||
				D9EE7466158A8C0E00EC1D05 /* GTLServicePlus.m */,
 | 
			
		||||
			);
 | 
			
		||||
			path = GTLPlus;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXGroup section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXNativeTarget section */
 | 
			
		||||
		0043C7991580045B000DF02E /* GooglePlusSample */ = {
 | 
			
		||||
			isa = PBXNativeTarget;
 | 
			
		||||
			buildConfigurationList = 0043C7B21580045B000DF02E /* Build configuration list for PBXNativeTarget "GooglePlusSample" */;
 | 
			
		||||
			buildPhases = (
 | 
			
		||||
				0043C7961580045B000DF02E /* Sources */,
 | 
			
		||||
				0043C7971580045B000DF02E /* Frameworks */,
 | 
			
		||||
				0043C7981580045B000DF02E /* Resources */,
 | 
			
		||||
			);
 | 
			
		||||
			buildRules = (
 | 
			
		||||
			);
 | 
			
		||||
			dependencies = (
 | 
			
		||||
			);
 | 
			
		||||
			name = GooglePlusSample;
 | 
			
		||||
			productName = GooglePlusSample;
 | 
			
		||||
			productReference = 0043C79A1580045B000DF02E /* GooglePlusSample.app */;
 | 
			
		||||
			productType = "com.apple.product-type.application";
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXNativeTarget section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXProject section */
 | 
			
		||||
		0043C7911580045B000DF02E /* Project object */ = {
 | 
			
		||||
			isa = PBXProject;
 | 
			
		||||
			attributes = {
 | 
			
		||||
				LastUpgradeCheck = 0420;
 | 
			
		||||
				ORGANIZATIONNAME = "Google Inc";
 | 
			
		||||
			};
 | 
			
		||||
			buildConfigurationList = 0043C7941580045B000DF02E /* Build configuration list for PBXProject "GooglePlusSample" */;
 | 
			
		||||
			compatibilityVersion = "Xcode 3.2";
 | 
			
		||||
			developmentRegion = English;
 | 
			
		||||
			hasScannedForEncodings = 0;
 | 
			
		||||
			knownRegions = (
 | 
			
		||||
				en,
 | 
			
		||||
			);
 | 
			
		||||
			mainGroup = 0043C78F1580045B000DF02E;
 | 
			
		||||
			productRefGroup = 0043C79B1580045B000DF02E /* Products */;
 | 
			
		||||
			projectDirPath = "";
 | 
			
		||||
			projectRoot = "";
 | 
			
		||||
			targets = (
 | 
			
		||||
				0043C7991580045B000DF02E /* GooglePlusSample */,
 | 
			
		||||
			);
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXProject section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXResourcesBuildPhase section */
 | 
			
		||||
		0043C7981580045B000DF02E /* Resources */ = {
 | 
			
		||||
			isa = PBXResourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				D9EE743D158A8BD400EC1D05 /* google_plus_share_large.png in Resources */,
 | 
			
		||||
				D9EE743E158A8BD400EC1D05 /* google_plus_share_large@2x.png in Resources */,
 | 
			
		||||
				D9EE743F158A8BD400EC1D05 /* google_plus_share.png in Resources */,
 | 
			
		||||
				D9EE7440158A8BD400EC1D05 /* google_plus_share@2x.png in Resources */,
 | 
			
		||||
				D9EE74E4158A9A7D00EC1D05 /* google_plus_sign_in_wide.png in Resources */,
 | 
			
		||||
				D9EE74E5158A9A7D00EC1D05 /* google_plus_sign_in_wide@2x.png in Resources */,
 | 
			
		||||
				D9EE74E6158A9A7D00EC1D05 /* google_plus_sign_in.png in Resources */,
 | 
			
		||||
				D9EE74E7158A9A7D00EC1D05 /* google_plus_sign_in@2x.png in Resources */,
 | 
			
		||||
				D9EE74AB158A8C0E00EC1D05 /* GTMOAuth2ViewTouch.xib in Resources */,
 | 
			
		||||
				D9EE74C4158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.xib in Resources */,
 | 
			
		||||
				D9EE74C6158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.xib in Resources */,
 | 
			
		||||
				D9EE74C8158A8E0500EC1D05 /* GooglePlusSampleShareViewController.xib in Resources */,
 | 
			
		||||
				D9EE74CA158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.xib in Resources */,
 | 
			
		||||
				D9EE74CD158A8E2900EC1D05 /* InfoPlist.strings in Resources */,
 | 
			
		||||
				0C52D6F8158BAB1F001510E6 /* button_background.png in Resources */,
 | 
			
		||||
				D98254A815990D8D0060CA47 /* Icon_2x.png in Resources */,
 | 
			
		||||
				D98254A915990D8D0060CA47 /* Icon.png in Resources */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXResourcesBuildPhase section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXSourcesBuildPhase section */
 | 
			
		||||
		0043C7961580045B000DF02E /* Sources */ = {
 | 
			
		||||
			isa = PBXSourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				00F70E83158006DC0077799E /* main.m in Sources */,
 | 
			
		||||
				D9EE748D158A8C0E00EC1D05 /* GTLBase64.m in Sources */,
 | 
			
		||||
				D9EE748E158A8C0E00EC1D05 /* GTLBatchQuery.m in Sources */,
 | 
			
		||||
				D9EE748F158A8C0E00EC1D05 /* GTLBatchResult.m in Sources */,
 | 
			
		||||
				D9EE7490158A8C0E00EC1D05 /* GTLDateTime.m in Sources */,
 | 
			
		||||
				D9EE7491158A8C0E00EC1D05 /* GTLErrorObject.m in Sources */,
 | 
			
		||||
				D9EE7492158A8C0E00EC1D05 /* GTLFramework.m in Sources */,
 | 
			
		||||
				D9EE7493158A8C0E00EC1D05 /* GTLJSONParser.m in Sources */,
 | 
			
		||||
				D9EE7494158A8C0E00EC1D05 /* GTLObject.m in Sources */,
 | 
			
		||||
				D9EE7495158A8C0E00EC1D05 /* GTLPlusConstants.m in Sources */,
 | 
			
		||||
				D9EE7496158A8C0E00EC1D05 /* GTLPlusItemScope.m in Sources */,
 | 
			
		||||
				D9EE7497158A8C0E00EC1D05 /* GTLPlusMoment.m in Sources */,
 | 
			
		||||
				D9EE7499158A8C0E00EC1D05 /* GTLQueryPlus.m in Sources */,
 | 
			
		||||
				D9EE749A158A8C0E00EC1D05 /* GTLServicePlus.m in Sources */,
 | 
			
		||||
				D9EE749B158A8C0E00EC1D05 /* GTLQuery.m in Sources */,
 | 
			
		||||
				D9EE749C158A8C0E00EC1D05 /* GTLRuntimeCommon.m in Sources */,
 | 
			
		||||
				D9EE749D158A8C0E00EC1D05 /* GTLService.m in Sources */,
 | 
			
		||||
				D9EE749E158A8C0E00EC1D05 /* GTLUploadParameters.m in Sources */,
 | 
			
		||||
				D9EE749F158A8C0E00EC1D05 /* GTLUtilities.m in Sources */,
 | 
			
		||||
				D9EE74A0158A8C0E00EC1D05 /* GTMHTTPFetcher.m in Sources */,
 | 
			
		||||
				D9EE74A1158A8C0E00EC1D05 /* GTMHTTPFetcherLogging.m in Sources */,
 | 
			
		||||
				D9EE74A2158A8C0E00EC1D05 /* GTMHTTPFetcherService.m in Sources */,
 | 
			
		||||
				D9EE74A3158A8C0E00EC1D05 /* GTMHTTPFetchHistory.m in Sources */,
 | 
			
		||||
				D9EE74A4158A8C0E00EC1D05 /* GTMLogger.m in Sources */,
 | 
			
		||||
				D9EE74A5158A8C0E00EC1D05 /* GTMMethodCheck.m in Sources */,
 | 
			
		||||
				D9EE74A6158A8C0E00EC1D05 /* GTMNSDictionary+URLArguments.m in Sources */,
 | 
			
		||||
				D9EE74A7158A8C0E00EC1D05 /* GTMNSString+URLArguments.m in Sources */,
 | 
			
		||||
				D9EE74A8158A8C0E00EC1D05 /* GTMOAuth2Authentication.m in Sources */,
 | 
			
		||||
				D9EE74A9158A8C0E00EC1D05 /* GTMOAuth2SignIn.m in Sources */,
 | 
			
		||||
				D9EE74AA158A8C0E00EC1D05 /* GTMOAuth2ViewControllerTouch.m in Sources */,
 | 
			
		||||
				D9EE74AC158A8C0E00EC1D05 /* GTMObjC2Runtime.m in Sources */,
 | 
			
		||||
				D9EE74C2158A8E0500EC1D05 /* GooglePlusSampleAppDelegate.m in Sources */,
 | 
			
		||||
				D9EE74C3158A8E0500EC1D05 /* GooglePlusSampleMasterViewController.m in Sources */,
 | 
			
		||||
				D9EE74C5158A8E0500EC1D05 /* GooglePlusSampleMomentsViewController.m in Sources */,
 | 
			
		||||
				D9EE74C7158A8E0500EC1D05 /* GooglePlusSampleShareViewController.m in Sources */,
 | 
			
		||||
				D9EE74C9158A8E0500EC1D05 /* GooglePlusSampleSignInViewController.m in Sources */,
 | 
			
		||||
				D98254F2159937730060CA47 /* GTLPlusPerson.m in Sources */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXSourcesBuildPhase section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXVariantGroup section */
 | 
			
		||||
		D9EE74CB158A8E2900EC1D05 /* InfoPlist.strings */ = {
 | 
			
		||||
			isa = PBXVariantGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				D9EE74CC158A8E2900EC1D05 /* en */,
 | 
			
		||||
			);
 | 
			
		||||
			name = InfoPlist.strings;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
/* End PBXVariantGroup section */
 | 
			
		||||
 | 
			
		||||
/* Begin XCBuildConfiguration section */
 | 
			
		||||
		0043C7B01580045B000DF02E /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ALWAYS_SEARCH_USER_PATHS = NO;
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 | 
			
		||||
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 | 
			
		||||
				COPY_PHASE_STRIP = NO;
 | 
			
		||||
				GCC_C_LANGUAGE_STANDARD = gnu99;
 | 
			
		||||
				GCC_DYNAMIC_NO_PIC = NO;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = 0;
 | 
			
		||||
				GCC_PREPROCESSOR_DEFINITIONS = (
 | 
			
		||||
					"DEBUG=1",
 | 
			
		||||
					"$(inherited)",
 | 
			
		||||
				);
 | 
			
		||||
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-all_load",
 | 
			
		||||
					"-ObjC",
 | 
			
		||||
				);
 | 
			
		||||
				SDKROOT = iphoneos;
 | 
			
		||||
				TARGETED_DEVICE_FAMILY = "1,2";
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
		};
 | 
			
		||||
		0043C7B11580045B000DF02E /* Release */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ALWAYS_SEARCH_USER_PATHS = NO;
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 | 
			
		||||
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 | 
			
		||||
				COPY_PHASE_STRIP = YES;
 | 
			
		||||
				GCC_C_LANGUAGE_STANDARD = gnu99;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
 | 
			
		||||
				OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-all_load",
 | 
			
		||||
					"-ObjC",
 | 
			
		||||
				);
 | 
			
		||||
				SDKROOT = iphoneos;
 | 
			
		||||
				TARGETED_DEVICE_FAMILY = "1,2";
 | 
			
		||||
				VALIDATE_PRODUCT = YES;
 | 
			
		||||
			};
 | 
			
		||||
			name = Release;
 | 
			
		||||
		};
 | 
			
		||||
		0043C7B31580045B000DF02E /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 | 
			
		||||
				GCC_PREFIX_HEADER = "GooglePlusSample-Prefix.pch";
 | 
			
		||||
				INFOPLIST_FILE = "GooglePlusSample-Info.plist";
 | 
			
		||||
				LIBRARY_SEARCH_PATHS = (
 | 
			
		||||
					"$(inherited)",
 | 
			
		||||
					"\"$(SRCROOT)\"",
 | 
			
		||||
					"\"$(SRCROOT)/../lib\"",
 | 
			
		||||
				);
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-all_load",
 | 
			
		||||
					"-ObjC",
 | 
			
		||||
				);
 | 
			
		||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
			
		||||
				WRAPPER_EXTENSION = app;
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
		};
 | 
			
		||||
		0043C7B41580045B000DF02E /* Release */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 | 
			
		||||
				GCC_PREFIX_HEADER = "GooglePlusSample-Prefix.pch";
 | 
			
		||||
				INFOPLIST_FILE = "GooglePlusSample-Info.plist";
 | 
			
		||||
				LIBRARY_SEARCH_PATHS = (
 | 
			
		||||
					"$(inherited)",
 | 
			
		||||
					"\"$(SRCROOT)\"",
 | 
			
		||||
					"\"$(SRCROOT)/../lib\"",
 | 
			
		||||
				);
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-all_load",
 | 
			
		||||
					"-ObjC",
 | 
			
		||||
				);
 | 
			
		||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
			
		||||
				WRAPPER_EXTENSION = app;
 | 
			
		||||
			};
 | 
			
		||||
			name = Release;
 | 
			
		||||
		};
 | 
			
		||||
/* End XCBuildConfiguration section */
 | 
			
		||||
 | 
			
		||||
/* Begin XCConfigurationList section */
 | 
			
		||||
		0043C7941580045B000DF02E /* Build configuration list for PBXProject "GooglePlusSample" */ = {
 | 
			
		||||
			isa = XCConfigurationList;
 | 
			
		||||
			buildConfigurations = (
 | 
			
		||||
				0043C7B01580045B000DF02E /* Debug */,
 | 
			
		||||
				0043C7B11580045B000DF02E /* Release */,
 | 
			
		||||
			);
 | 
			
		||||
			defaultConfigurationIsVisible = 0;
 | 
			
		||||
			defaultConfigurationName = Release;
 | 
			
		||||
		};
 | 
			
		||||
		0043C7B21580045B000DF02E /* Build configuration list for PBXNativeTarget "GooglePlusSample" */ = {
 | 
			
		||||
			isa = XCConfigurationList;
 | 
			
		||||
			buildConfigurations = (
 | 
			
		||||
				0043C7B31580045B000DF02E /* Debug */,
 | 
			
		||||
				0043C7B41580045B000DF02E /* Release */,
 | 
			
		||||
			);
 | 
			
		||||
			defaultConfigurationIsVisible = 0;
 | 
			
		||||
			defaultConfigurationName = Release;
 | 
			
		||||
		};
 | 
			
		||||
/* End XCConfigurationList section */
 | 
			
		||||
	};
 | 
			
		||||
	rootObject = 0043C7911580045B000DF02E /* Project object */;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Workspace
 | 
			
		||||
   version = "1.0">
 | 
			
		||||
   <FileRef
 | 
			
		||||
      location = "self:GooglePlusSample.xcodeproj">
 | 
			
		||||
   </FileRef>
 | 
			
		||||
</Workspace>
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "0043C7991580045B000DF02E"
 | 
			
		||||
               BuildableName = "GooglePlusSample.app"
 | 
			
		||||
               BlueprintName = "GooglePlusSample"
 | 
			
		||||
               ReferencedContainer = "container:GooglePlusSample.xcodeproj">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
      <Testables>
 | 
			
		||||
      </Testables>
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "0043C7991580045B000DF02E"
 | 
			
		||||
            BuildableName = "GooglePlusSample.app"
 | 
			
		||||
            BlueprintName = "GooglePlusSample"
 | 
			
		||||
            ReferencedContainer = "container:GooglePlusSample.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "0043C7991580045B000DF02E"
 | 
			
		||||
            BuildableName = "GooglePlusSample.app"
 | 
			
		||||
            BlueprintName = "GooglePlusSample"
 | 
			
		||||
            ReferencedContainer = "container:GooglePlusSample.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
      <AdditionalOptions>
 | 
			
		||||
      </AdditionalOptions>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "0043C7991580045B000DF02E"
 | 
			
		||||
            BuildableName = "GooglePlusSample.app"
 | 
			
		||||
            BlueprintName = "GooglePlusSample"
 | 
			
		||||
            ReferencedContainer = "container:GooglePlusSample.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
	<key>SchemeUserState</key>
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>GooglePlusSample.xcscheme</key>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>orderHint</key>
 | 
			
		||||
			<integer>0</integer>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</dict>
 | 
			
		||||
	<key>SuppressBuildableAutocreation</key>
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>0043C7991580045B000DF02E</key>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>primary</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</dict>
 | 
			
		||||
</dict>
 | 
			
		||||
</plist>
 | 
			
		||||
							
								
								
									
										41
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,41 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleAppDelegate.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
 | 
			
		||||
@class GooglePlusShare;
 | 
			
		||||
@class GooglePlusSignInButton;
 | 
			
		||||
@class GTMOAuth2Authentication;
 | 
			
		||||
 | 
			
		||||
@interface GooglePlusSampleAppDelegate : UIResponder<UIApplicationDelegate>
 | 
			
		||||
 | 
			
		||||
// The sample app's |UIWindow|.
 | 
			
		||||
@property (retain, nonatomic) UIWindow *window;
 | 
			
		||||
// The navigation controller.
 | 
			
		||||
@property (retain, nonatomic) UINavigationController *navigationController;
 | 
			
		||||
// The Google+ sign-in button to handle the URL redirect.
 | 
			
		||||
@property (retain, nonatomic) GooglePlusSignInButton *signInButton;
 | 
			
		||||
// The OAuth 2.0 authentication used in the application.
 | 
			
		||||
@property (retain, nonatomic) GTMOAuth2Authentication *auth;
 | 
			
		||||
// The Google+ share object to handle the URL redirect.
 | 
			
		||||
@property (retain, nonatomic) GooglePlusShare *share;
 | 
			
		||||
 | 
			
		||||
// The OAuth 2.0 client ID to be used for Google+ sign-in, share, and moments.
 | 
			
		||||
+ (NSString *)clientID;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										89
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleAppDelegate.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,89 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleAppDelegate.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleAppDelegate.h"
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleMasterViewController.h"
 | 
			
		||||
#import "GooglePlusSignIn.h"
 | 
			
		||||
#import "GooglePlusSignInButton.h"
 | 
			
		||||
 | 
			
		||||
@implementation GooglePlusSampleAppDelegate
 | 
			
		||||
 | 
			
		||||
@synthesize window = window_;
 | 
			
		||||
@synthesize navigationController = navigationController_;
 | 
			
		||||
@synthesize signInButton = signInButton_;
 | 
			
		||||
@synthesize auth = auth_;
 | 
			
		||||
@synthesize share = share_;
 | 
			
		||||
 | 
			
		||||
// DO NOT USE THIS CLIENT ID. IT WILL NOT WORK FOR YOUR APP.
 | 
			
		||||
// Please use the client ID created for you by Google.
 | 
			
		||||
static NSString * const kClientID = @"571459971810-"
 | 
			
		||||
    @"2bpoda566pap5kkc0aqljqfjki8tgeb6.apps.googleusercontent.com";
 | 
			
		||||
 | 
			
		||||
+ (NSString *)clientID {
 | 
			
		||||
  return kClientID;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Object life-cycle.
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [window_ release];
 | 
			
		||||
  [navigationController_ release];
 | 
			
		||||
  [signInButton_ release];
 | 
			
		||||
  [auth_ release];
 | 
			
		||||
  [share_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)application:(UIApplication *)application
 | 
			
		||||
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 | 
			
		||||
  self.window = [[[UIWindow alloc]
 | 
			
		||||
      initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
 | 
			
		||||
  GooglePlusSampleMasterViewController *masterViewController =
 | 
			
		||||
      [[[GooglePlusSampleMasterViewController alloc]
 | 
			
		||||
          initWithNibName:@"GooglePlusSampleMasterViewController"
 | 
			
		||||
                   bundle:nil] autorelease];
 | 
			
		||||
  self.navigationController =
 | 
			
		||||
      [[[UINavigationController alloc]
 | 
			
		||||
          initWithRootViewController:masterViewController] autorelease];
 | 
			
		||||
  self.window.rootViewController = self.navigationController;
 | 
			
		||||
  [self.window makeKeyAndVisible];
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)application:(UIApplication *)application
 | 
			
		||||
              openURL:(NSURL *)url
 | 
			
		||||
    sourceApplication:(NSString *)sourceApplication
 | 
			
		||||
           annotation:(id)annotation {
 | 
			
		||||
  // Handle Google+ share dialog URL.
 | 
			
		||||
  if ([share_ handleURL:url
 | 
			
		||||
      sourceApplication:sourceApplication
 | 
			
		||||
             annotation:annotation]) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Handle Google+ sign-in button URL.
 | 
			
		||||
  if ([signInButton_ handleURL:url
 | 
			
		||||
             sourceApplication:sourceApplication
 | 
			
		||||
                    annotation:annotation]) {
 | 
			
		||||
    return YES;
 | 
			
		||||
  }
 | 
			
		||||
  return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										23
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,23 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleMasterViewController.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
 | 
			
		||||
@interface GooglePlusSampleMasterViewController : UITableViewController
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										98
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,98 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleMasterViewController.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleMasterViewController.h"
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleShareViewController.h"
 | 
			
		||||
#import "GooglePlusSampleSignInViewController.h"
 | 
			
		||||
#import "GooglePlusSampleMomentsViewController.h"
 | 
			
		||||
 | 
			
		||||
static const int kNumViewControllers = 3;
 | 
			
		||||
static NSString * const kMenuOptions[kNumViewControllers] = {
 | 
			
		||||
    @"Sign In", @"Share", @"Moments" };
 | 
			
		||||
static NSString * const kNibNames[kNumViewControllers] = {
 | 
			
		||||
    @"GooglePlusSampleSignInViewController",
 | 
			
		||||
    @"GooglePlusSampleShareViewController",
 | 
			
		||||
    @"GooglePlusSampleMomentsViewController" };
 | 
			
		||||
 | 
			
		||||
@implementation GooglePlusSampleMasterViewController
 | 
			
		||||
 | 
			
		||||
- (id)initWithNibName:(NSString *)nibNameOrNil
 | 
			
		||||
               bundle:(NSBundle *)nibBundleOrNil {
 | 
			
		||||
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
 | 
			
		||||
  if (self) {
 | 
			
		||||
    self.title = @"Google+ SDK Sample";
 | 
			
		||||
    UIBarButtonItem *backButton = [[[UIBarButtonItem alloc]
 | 
			
		||||
        initWithTitle:@"Back"
 | 
			
		||||
                style:UIBarButtonItemStylePlain
 | 
			
		||||
               target:self
 | 
			
		||||
               action:@selector(backPressed)] autorelease];
 | 
			
		||||
    self.navigationItem.backBarButtonItem = backButton;
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - View lifecycle
 | 
			
		||||
 | 
			
		||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
 | 
			
		||||
    interfaceOrientation {
 | 
			
		||||
  if ([[UIDevice currentDevice] userInterfaceIdiom] ==
 | 
			
		||||
      UIUserInterfaceIdiomPhone) {
 | 
			
		||||
    return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
 | 
			
		||||
  }
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UITableViewDelegate/UITableViewDataSource
 | 
			
		||||
 | 
			
		||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSInteger)tableView:(UITableView *)tableView
 | 
			
		||||
    numberOfRowsInSection:(NSInteger)section {
 | 
			
		||||
  return kNumViewControllers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (UITableViewCell *)tableView:(UITableView *)tableView
 | 
			
		||||
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 | 
			
		||||
  static NSString * const kCellIdentifier = @"Cell";
 | 
			
		||||
  UITableViewCell *cell =
 | 
			
		||||
      [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
 | 
			
		||||
  if (cell == nil) {
 | 
			
		||||
    cell =
 | 
			
		||||
        [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
 | 
			
		||||
                                reuseIdentifier:kCellIdentifier] autorelease];
 | 
			
		||||
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cell.textLabel.text = kMenuOptions[indexPath.row];
 | 
			
		||||
  return cell;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)tableView:(UITableView *)tableView
 | 
			
		||||
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 | 
			
		||||
  Class nibClass = NSClassFromString(kNibNames[indexPath.row]);
 | 
			
		||||
  UIViewController *controller =
 | 
			
		||||
      [[[nibClass alloc] initWithNibName:nil bundle:nil] autorelease];
 | 
			
		||||
  controller.navigationItem.title = kMenuOptions[indexPath.row];
 | 
			
		||||
 | 
			
		||||
  [self.navigationController pushViewController:controller animated:YES];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										251
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMasterViewController.xib
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,251 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
 | 
			
		||||
	<data>
 | 
			
		||||
		<int key="IBDocument.SystemTarget">1280</int>
 | 
			
		||||
		<string key="IBDocument.SystemVersion">10K549</string>
 | 
			
		||||
		<string key="IBDocument.InterfaceBuilderVersion">1938</string>
 | 
			
		||||
		<string key="IBDocument.AppKitVersion">1038.36</string>
 | 
			
		||||
		<string key="IBDocument.HIToolboxVersion">461.00</string>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			<string key="NS.object.0">933</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array key="IBDocument.IntegratedClassDependencies">
 | 
			
		||||
			<string>IBUINavigationItem</string>
 | 
			
		||||
			<string>IBUITableView</string>
 | 
			
		||||
			<string>IBUITableViewController</string>
 | 
			
		||||
			<string>IBUINavigationController</string>
 | 
			
		||||
			<string>IBUINavigationBar</string>
 | 
			
		||||
			<string>IBProxyObject</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<array key="IBDocument.PluginDependencies">
 | 
			
		||||
			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.Metadata">
 | 
			
		||||
			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
 | 
			
		||||
			<integer value="1" key="NS.object.0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 | 
			
		||||
			<object class="IBProxyObject" id="841351856">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBProxyObject" id="371349661">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUITableView" id="709618507">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">274</int>
 | 
			
		||||
				<string key="NSFrame">{{0, 20}, {320, 460}}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<object class="NSColor" key="IBUIBackgroundColor" id="800680415">
 | 
			
		||||
					<int key="NSColorSpace">3</int>
 | 
			
		||||
					<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
				</object>
 | 
			
		||||
				<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
				<bool key="IBUIAlwaysBounceVertical">YES</bool>
 | 
			
		||||
				<int key="IBUISeparatorStyle">1</int>
 | 
			
		||||
				<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
 | 
			
		||||
				<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
 | 
			
		||||
				<float key="IBUIRowHeight">44</float>
 | 
			
		||||
				<float key="IBUISectionHeaderHeight">22</float>
 | 
			
		||||
				<float key="IBUISectionFooterHeight">22</float>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUINavigationController" id="271496582">
 | 
			
		||||
				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
 | 
			
		||||
				<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
 | 
			
		||||
					<int key="IBUIInterfaceOrientation">1</int>
 | 
			
		||||
					<int key="interfaceOrientation">1</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
				<bool key="IBUIHorizontal">NO</bool>
 | 
			
		||||
				<object class="IBUINavigationBar" key="IBUINavigationBar" id="264651278">
 | 
			
		||||
					<nil key="NSNextResponder"/>
 | 
			
		||||
					<int key="NSvFlags">256</int>
 | 
			
		||||
					<string key="NSFrameSize">{0, 0}</string>
 | 
			
		||||
					<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
					<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
					<bool key="IBUIMultipleTouchEnabled">YES</bool>
 | 
			
		||||
					<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
				</object>
 | 
			
		||||
				<array key="IBUIViewControllers">
 | 
			
		||||
					<object class="IBUITableViewController" id="84492071">
 | 
			
		||||
						<object class="IBUITableView" key="IBUIView" id="1024288683">
 | 
			
		||||
							<reference key="NSNextResponder"/>
 | 
			
		||||
							<int key="NSvFlags">274</int>
 | 
			
		||||
							<string key="NSFrame">{{0, 64}, {320, 416}}</string>
 | 
			
		||||
							<reference key="NSSuperview"/>
 | 
			
		||||
							<reference key="NSWindow"/>
 | 
			
		||||
							<reference key="NSNextKeyView"/>
 | 
			
		||||
							<reference key="IBUIBackgroundColor" ref="800680415"/>
 | 
			
		||||
							<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
							<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
							<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
 | 
			
		||||
							<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
							<bool key="IBUIAlwaysBounceVertical">YES</bool>
 | 
			
		||||
							<int key="IBUISeparatorStyle">1</int>
 | 
			
		||||
							<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
 | 
			
		||||
							<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
 | 
			
		||||
							<float key="IBUIRowHeight">44</float>
 | 
			
		||||
							<float key="IBUISectionHeaderHeight">22</float>
 | 
			
		||||
							<float key="IBUISectionFooterHeight">22</float>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBUINavigationItem" key="IBUINavigationItem" id="848890509">
 | 
			
		||||
							<reference key="IBUINavigationBar"/>
 | 
			
		||||
							<string key="IBUITitle">Google Plus Sample App</string>
 | 
			
		||||
							<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="IBUIParentViewController" ref="271496582"/>
 | 
			
		||||
						<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
 | 
			
		||||
						<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
 | 
			
		||||
							<int key="IBUIInterfaceOrientation">1</int>
 | 
			
		||||
							<int key="interfaceOrientation">1</int>
 | 
			
		||||
						</object>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<bool key="IBUIHorizontal">NO</bool>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
			</object>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="IBObjectContainer" key="IBDocument.Objects">
 | 
			
		||||
			<array class="NSMutableArray" key="connectionRecords">
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">view</string>
 | 
			
		||||
						<reference key="source" ref="841351856"/>
 | 
			
		||||
						<reference key="destination" ref="709618507"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">3</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">dataSource</string>
 | 
			
		||||
						<reference key="source" ref="709618507"/>
 | 
			
		||||
						<reference key="destination" ref="841351856"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">4</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="709618507"/>
 | 
			
		||||
						<reference key="destination" ref="841351856"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">5</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="1024288683"/>
 | 
			
		||||
						<reference key="destination" ref="84492071"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">12</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">dataSource</string>
 | 
			
		||||
						<reference key="source" ref="1024288683"/>
 | 
			
		||||
						<reference key="destination" ref="84492071"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">13</int>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
			<object class="IBMutableOrderedSet" key="objectRecords">
 | 
			
		||||
				<array key="orderedObjects">
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">0</int>
 | 
			
		||||
						<array key="object" id="0"/>
 | 
			
		||||
						<reference key="children" ref="1000"/>
 | 
			
		||||
						<nil key="parent"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-1</int>
 | 
			
		||||
						<reference key="object" ref="841351856"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">File's Owner</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-2</int>
 | 
			
		||||
						<reference key="object" ref="371349661"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">2</int>
 | 
			
		||||
						<reference key="object" ref="709618507"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">6</int>
 | 
			
		||||
						<reference key="object" ref="271496582"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="264651278"/>
 | 
			
		||||
							<reference ref="84492071"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">7</int>
 | 
			
		||||
						<reference key="object" ref="264651278"/>
 | 
			
		||||
						<reference key="parent" ref="271496582"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">10</int>
 | 
			
		||||
						<reference key="object" ref="84492071"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="1024288683"/>
 | 
			
		||||
							<reference ref="848890509"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="271496582"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">11</int>
 | 
			
		||||
						<reference key="object" ref="1024288683"/>
 | 
			
		||||
						<reference key="parent" ref="84492071"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">14</int>
 | 
			
		||||
						<reference key="object" ref="848890509"/>
 | 
			
		||||
						<reference key="parent" ref="84492071"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
			</object>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="flattenedProperties">
 | 
			
		||||
				<string key="-1.CustomClassName">GooglePlusSampleMasterViewController</string>
 | 
			
		||||
				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="-2.CustomClassName">UIResponder</string>
 | 
			
		||||
				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			</dictionary>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
 | 
			
		||||
			<nil key="activeLocalization"/>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="localizations"/>
 | 
			
		||||
			<nil key="sourceID"/>
 | 
			
		||||
			<int key="maxID">14</int>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBClassDescriber" key="IBDocument.Classes">
 | 
			
		||||
			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
 | 
			
		||||
				<object class="IBPartialClassDescription">
 | 
			
		||||
					<string key="className">GooglePlusSampleMasterViewController</string>
 | 
			
		||||
					<string key="superclassName">UITableViewController</string>
 | 
			
		||||
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 | 
			
		||||
						<string key="majorKey">IBProjectSource</string>
 | 
			
		||||
						<string key="minorKey">./Classes/GooglePlusSampleMasterViewController.h</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
		</object>
 | 
			
		||||
		<int key="IBDocument.localizationMode">0</int>
 | 
			
		||||
		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
 | 
			
		||||
		<int key="IBDocument.defaultPropertyAccessControl">3</int>
 | 
			
		||||
		<string key="IBCocoaTouchPluginVersion">933</string>
 | 
			
		||||
	</data>
 | 
			
		||||
</archive>
 | 
			
		||||
							
								
								
									
										45
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,45 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleMomentsViewController.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
 | 
			
		||||
@class GTLServicePlus;
 | 
			
		||||
 | 
			
		||||
// A view controller for writing different kinds of moments to Google+ history.
 | 
			
		||||
// The open-source GTLPlus libraries are required. For more details, see
 | 
			
		||||
// https://developers.google.com/+/history/ .
 | 
			
		||||
@interface GooglePlusSampleMomentsViewController : UIViewController<
 | 
			
		||||
    UITableViewDelegate,
 | 
			
		||||
    UITableViewDataSource,
 | 
			
		||||
    UITextFieldDelegate> {
 | 
			
		||||
  BOOL keyboardVisible_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The table that displays the different kinds of moments available.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UITableView *momentsTable;
 | 
			
		||||
// The target URL to associate with this moment.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UITextField *momentURL;
 | 
			
		||||
// A label to display the result of writing a moment.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UILabel *momentStatus;
 | 
			
		||||
// The "Add Moment" button.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UIButton *addButton;
 | 
			
		||||
 | 
			
		||||
// Called when the user presses the "Add Moment" button.
 | 
			
		||||
- (IBAction)momentButton:(id)sender;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										334
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,334 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleMomentsViewController.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleMomentsViewController.h"
 | 
			
		||||
 | 
			
		||||
#import <QuartzCore/QuartzCore.h>
 | 
			
		||||
#import "GTLPlus.h"
 | 
			
		||||
#import "GTLPlusConstants.h"
 | 
			
		||||
#import "GTLPlusItemScope.h"
 | 
			
		||||
#import "GTLPlusMoment.h"
 | 
			
		||||
#import "GTLQueryPlus.h"
 | 
			
		||||
#import "GTLServicePlus.h"
 | 
			
		||||
#import "GTMLogger.h"
 | 
			
		||||
#import "GTMOAuth2Authentication.h"
 | 
			
		||||
#import "GooglePlusSampleAppDelegate.h"
 | 
			
		||||
 | 
			
		||||
@interface GooglePlusSampleMomentsViewController ()
 | 
			
		||||
- (GTLPlusItemScope *)resultFor:(NSString *)selectedMoment;
 | 
			
		||||
- (void)animateKeyboard:(NSNotification *)notification
 | 
			
		||||
             shouldShow:(BOOL)shouldShow;
 | 
			
		||||
- (NSString *)momentURLForIndex:(int)i;
 | 
			
		||||
- (void)reportAuthStatus;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation GooglePlusSampleMomentsViewController
 | 
			
		||||
 | 
			
		||||
@synthesize momentsTable = momentsTable_;
 | 
			
		||||
@synthesize momentURL = momentURL_;
 | 
			
		||||
@synthesize momentStatus = momentStatus_;
 | 
			
		||||
@synthesize addButton = addButton_;
 | 
			
		||||
 | 
			
		||||
// The different kinds of moments.
 | 
			
		||||
static const int kNumMomentTypes = 9;
 | 
			
		||||
static NSString * const kMomentTypes[kNumMomentTypes] = {
 | 
			
		||||
    @"AddActivity",
 | 
			
		||||
    @"BuyActivity",
 | 
			
		||||
    @"CheckInActivity",
 | 
			
		||||
    @"CommentActivity",
 | 
			
		||||
    @"CreateActivity",
 | 
			
		||||
    @"ListenActivity",
 | 
			
		||||
    @"ReserveActivity",
 | 
			
		||||
    @"ReviewActivity",
 | 
			
		||||
    @"ViewActivity" };
 | 
			
		||||
static NSString * const kMomentURLs[kNumMomentTypes] = {
 | 
			
		||||
    @"thing",
 | 
			
		||||
    @"a-book",
 | 
			
		||||
    @"place",
 | 
			
		||||
    @"blog-entry",
 | 
			
		||||
    @"photo",
 | 
			
		||||
    @"song",
 | 
			
		||||
    @"restaurant",
 | 
			
		||||
    @"widget",
 | 
			
		||||
    @"video" };
 | 
			
		||||
static NSString * const kMomentURLFormat =
 | 
			
		||||
    @"https://developers.google.com/+/plugins/snippet/examples/%@";
 | 
			
		||||
 | 
			
		||||
#pragma mark - Object lifecycle
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  // Unregister for keyboard notifications while not visible.
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
      removeObserver:self
 | 
			
		||||
                name:UIKeyboardWillShowNotification
 | 
			
		||||
              object:nil];
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
      removeObserver:self
 | 
			
		||||
                name:UIKeyboardWillHideNotification
 | 
			
		||||
              object:nil];
 | 
			
		||||
  [momentsTable_ release];
 | 
			
		||||
  [momentURL_ release];
 | 
			
		||||
  [momentStatus_ release];
 | 
			
		||||
  [addButton_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - View lifecycle
 | 
			
		||||
 | 
			
		||||
- (void)viewDidLoad {
 | 
			
		||||
  // Set up "Add Moment" button.
 | 
			
		||||
  [[addButton_ layer] setCornerRadius:5];
 | 
			
		||||
  [[addButton_ layer] setMasksToBounds:YES];
 | 
			
		||||
  CGColorRef borderColor = [[UIColor colorWithWhite:203.0/255.0
 | 
			
		||||
                                              alpha:1.0] CGColor];
 | 
			
		||||
  [[addButton_ layer] setBorderColor:borderColor];
 | 
			
		||||
  [[addButton_ layer] setBorderWidth:1.0];
 | 
			
		||||
 | 
			
		||||
  // Set up sample view of writing moments.
 | 
			
		||||
  int selectedRow = [[momentsTable_ indexPathForSelectedRow] row];
 | 
			
		||||
  momentURL_.text = [self momentURLForIndex:selectedRow];
 | 
			
		||||
 | 
			
		||||
  [self reportAuthStatus];
 | 
			
		||||
  [super viewDidLoad];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)viewWillAppear:(BOOL)animated {
 | 
			
		||||
  [super viewWillAppear:animated];
 | 
			
		||||
 | 
			
		||||
  // Register for keyboard notifications while visible.
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
      addObserver:self
 | 
			
		||||
         selector:@selector(keyboardWillShow:)
 | 
			
		||||
             name:UIKeyboardWillShowNotification
 | 
			
		||||
           object:nil];
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
      addObserver:self
 | 
			
		||||
         selector:@selector(keyboardWillHide:)
 | 
			
		||||
             name:UIKeyboardWillHideNotification
 | 
			
		||||
           object:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)viewWillDisappear:(BOOL)animated {
 | 
			
		||||
  // Unregister for keyboard notifications while not visible.
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
      removeObserver:self
 | 
			
		||||
                name:UIKeyboardWillShowNotification
 | 
			
		||||
              object:nil];
 | 
			
		||||
  [[NSNotificationCenter defaultCenter]
 | 
			
		||||
   removeObserver:self
 | 
			
		||||
             name:UIKeyboardWillHideNotification
 | 
			
		||||
           object:nil];
 | 
			
		||||
 | 
			
		||||
  [super viewWillDisappear:animated];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - IBActions
 | 
			
		||||
 | 
			
		||||
- (IBAction)momentButton:(id)sender {
 | 
			
		||||
  GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *)
 | 
			
		||||
      [[UIApplication sharedApplication] delegate];
 | 
			
		||||
  if (!appDelegate.auth) {
 | 
			
		||||
    // To authenticate, use Google+ sign-in button.
 | 
			
		||||
    momentStatus_.text = @"Status: Not authenticated";
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Here is an example of writing a moment to Google+ history:
 | 
			
		||||
  // 1. Create a |GTLServicePlus| instance to send a request to Google+.
 | 
			
		||||
  GTLServicePlus* plusService = [[[GTLServicePlus alloc] init] autorelease];
 | 
			
		||||
  plusService.retryEnabled = YES;
 | 
			
		||||
 | 
			
		||||
  // 2. Set a valid |GTMOAuth2Authentication| object as the authorizer.
 | 
			
		||||
  [plusService setAuthorizer:appDelegate.auth];
 | 
			
		||||
 | 
			
		||||
  // 3. Create a |GTLPlusMoment| object with required fields. For reference, see
 | 
			
		||||
  // https://developers.google.com/+/history/ .
 | 
			
		||||
  int selectedRow = [[momentsTable_ indexPathForSelectedRow] row];
 | 
			
		||||
  NSString *selectedMoment = kMomentTypes[selectedRow];
 | 
			
		||||
 | 
			
		||||
  GTLPlusMoment *moment = [[[GTLPlusMoment alloc] init] autorelease];
 | 
			
		||||
  moment.type = [NSString stringWithFormat:@"https://schemas.google.com/%@",
 | 
			
		||||
                                           selectedMoment];
 | 
			
		||||
  GTLPlusItemScope *target = [[[GTLPlusItemScope alloc] init] autorelease];
 | 
			
		||||
  target.url = momentURL_.text;
 | 
			
		||||
  if ([target.url isEqualToString:@""]) {
 | 
			
		||||
    target.url = [self momentURLForIndex:selectedRow];
 | 
			
		||||
  }
 | 
			
		||||
  moment.target = target;
 | 
			
		||||
 | 
			
		||||
  // CommentActivity, ReserveActivity, and ReviewActivity require setting a
 | 
			
		||||
  // |result| field in the request.
 | 
			
		||||
  GTLPlusItemScope *result = [self resultFor:selectedMoment];
 | 
			
		||||
  if (result) {
 | 
			
		||||
    moment.result = result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 4. Create a |GTLQuery| object to write a moment.
 | 
			
		||||
  GTLQueryPlus *query =
 | 
			
		||||
      [GTLQueryPlus queryForMomentsInsertWithObject:moment
 | 
			
		||||
                                             userId:@"me"
 | 
			
		||||
                                         collection:kGTLPlusCollectionVault];
 | 
			
		||||
 | 
			
		||||
  [plusService executeQuery:query
 | 
			
		||||
          completionHandler:^(GTLServiceTicket *ticket,
 | 
			
		||||
                              id object,
 | 
			
		||||
                              NSError *error) {
 | 
			
		||||
              if (error) {
 | 
			
		||||
                GTMLoggerError(@"Error: %@", error);
 | 
			
		||||
                momentStatus_.text =
 | 
			
		||||
                    [NSString stringWithFormat:@"Status: Error: %@", error];
 | 
			
		||||
              } else {
 | 
			
		||||
                momentStatus_.text = [NSString stringWithFormat:
 | 
			
		||||
                    @"Status: Saved to Google+ history (%@)",
 | 
			
		||||
                    selectedMoment];
 | 
			
		||||
              }
 | 
			
		||||
          }];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UITableViewDelegate/UITableViewDataSource
 | 
			
		||||
 | 
			
		||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSInteger)tableView:(UITableView *)tableView
 | 
			
		||||
    numberOfRowsInSection:(NSInteger)section {
 | 
			
		||||
  return kNumMomentTypes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (UITableViewCell *)tableView:(UITableView *)tableView
 | 
			
		||||
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 | 
			
		||||
  static NSString * const kCellIdentifier = @"Cell";
 | 
			
		||||
  UITableViewCell *cell =
 | 
			
		||||
      [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
 | 
			
		||||
  if (cell == nil) {
 | 
			
		||||
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
 | 
			
		||||
                                   reuseIdentifier:kCellIdentifier]
 | 
			
		||||
        autorelease];
 | 
			
		||||
    cell.accessoryType = UITableViewCellAccessoryNone;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Configure the cell.
 | 
			
		||||
  cell.textLabel.text = kMomentTypes[indexPath.row];
 | 
			
		||||
  return cell;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)tableView:(UITableView *)tableView
 | 
			
		||||
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 | 
			
		||||
  int selectedRow = [[momentsTable_ indexPathForSelectedRow] row];
 | 
			
		||||
  momentURL_.text = [self momentURLForIndex:selectedRow];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UITextFieldDelegate
 | 
			
		||||
 | 
			
		||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
 | 
			
		||||
  [textField resignFirstResponder];
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UIKeyboard
 | 
			
		||||
 | 
			
		||||
- (void)keyboardWillShow:(NSNotification *)notification {
 | 
			
		||||
  [self animateKeyboard:notification shouldShow:YES];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)keyboardWillHide:(NSNotification *)notification {
 | 
			
		||||
  [self animateKeyboard:notification shouldShow:NO];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - Private methods
 | 
			
		||||
 | 
			
		||||
// Helps set required result field for select moment types.
 | 
			
		||||
- (GTLPlusItemScope *)resultFor:(NSString *)selectedMoment {
 | 
			
		||||
  GTLPlusItemScope *result = [[[GTLPlusItemScope alloc] init] autorelease];
 | 
			
		||||
  if ([selectedMoment isEqualToString:@"CommentActivity"]) {
 | 
			
		||||
    result.type = @"http://schema.org/Comment";
 | 
			
		||||
    result.url =
 | 
			
		||||
    @"https://developers.google.com/+/plugins/snippet/examples/blog-entry#comment-1";
 | 
			
		||||
    result.name = @"This is amazing!";
 | 
			
		||||
    result.text = @"I can't wait to use it on my site :)";
 | 
			
		||||
    return result;
 | 
			
		||||
  } else if ([selectedMoment isEqualToString:@"ReserveActivity"]) {
 | 
			
		||||
    result.type = @"http://schema.org/Reservation";
 | 
			
		||||
    result.startDate = @"2012-06-28T19:00:00-08:00";
 | 
			
		||||
    result.attendeeCount = [[[NSNumber alloc] initWithInt:3] autorelease];
 | 
			
		||||
    return result;
 | 
			
		||||
  } else if ([selectedMoment isEqualToString:@"ReviewActivity"]) {
 | 
			
		||||
    result.type = @"http://schema.org/Review";
 | 
			
		||||
    result.name = @"A Humble Review of Widget";
 | 
			
		||||
    result.url =
 | 
			
		||||
    @"https://developers.google.com/+/plugins/snippet/examples/review";
 | 
			
		||||
    result.text =
 | 
			
		||||
    @"It's amazingly effective at whatever it is that it's supposed to do.";
 | 
			
		||||
    GTLPlusItemScope *rating = [[[GTLPlusItemScope alloc] init] autorelease];
 | 
			
		||||
    rating.type = @"http://schema.org/Rating";
 | 
			
		||||
    rating.ratingValue = @"100";
 | 
			
		||||
    rating.bestRating = @"100";
 | 
			
		||||
    rating.worstRating = @"0";
 | 
			
		||||
    result.reviewRating =
 | 
			
		||||
    [[[NSArray alloc] initWithObjects:rating, nil] autorelease];
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
  return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helps animate keyboard for target URL text field.
 | 
			
		||||
- (void)animateKeyboard:(NSNotification *)notification
 | 
			
		||||
             shouldShow:(BOOL)shouldShow {
 | 
			
		||||
  NSDictionary *userInfo = [notification userInfo];
 | 
			
		||||
  CGFloat height = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey]
 | 
			
		||||
      CGRectValue].size.height;
 | 
			
		||||
  CGFloat duration = [[userInfo
 | 
			
		||||
      objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
 | 
			
		||||
  [UIView beginAnimations:nil context:NULL];
 | 
			
		||||
  [UIView setAnimationDuration:duration];
 | 
			
		||||
  CGRect newFrame = self.view.frame;
 | 
			
		||||
  if (shouldShow) {
 | 
			
		||||
    newFrame.size.height -= height;
 | 
			
		||||
  } else {
 | 
			
		||||
    newFrame.size.height += height;
 | 
			
		||||
  }
 | 
			
		||||
  self.view.frame = newFrame;
 | 
			
		||||
  [UIView commitAnimations];
 | 
			
		||||
  if (shouldShow) {
 | 
			
		||||
    keyboardVisible_ = YES;
 | 
			
		||||
  } else {
 | 
			
		||||
    keyboardVisible_ = NO;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)momentURLForIndex:(int)i {
 | 
			
		||||
  return [NSString stringWithFormat:kMomentURLFormat, kMomentURLs[i]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)reportAuthStatus {
 | 
			
		||||
  NSString *authStatus = @"";
 | 
			
		||||
  GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *)
 | 
			
		||||
      [[UIApplication sharedApplication] delegate];
 | 
			
		||||
 | 
			
		||||
  if (appDelegate.auth) {
 | 
			
		||||
    authStatus = @"Status: Authenticated";
 | 
			
		||||
  } else {
 | 
			
		||||
    // To authenticate, use Google+ sign-in button.
 | 
			
		||||
    authStatus = @"Status: Not authenticated";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  momentStatus_.text = authStatus;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										462
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleMomentsViewController.xib
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,462 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
 | 
			
		||||
	<data>
 | 
			
		||||
		<int key="IBDocument.SystemTarget">1280</int>
 | 
			
		||||
		<string key="IBDocument.SystemVersion">10K549</string>
 | 
			
		||||
		<string key="IBDocument.InterfaceBuilderVersion">1938</string>
 | 
			
		||||
		<string key="IBDocument.AppKitVersion">1038.36</string>
 | 
			
		||||
		<string key="IBDocument.HIToolboxVersion">461.00</string>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			<string key="NS.object.0">933</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array key="IBDocument.IntegratedClassDependencies">
 | 
			
		||||
			<string>IBUITextField</string>
 | 
			
		||||
			<string>IBUITableView</string>
 | 
			
		||||
			<string>IBUIButton</string>
 | 
			
		||||
			<string>IBUIView</string>
 | 
			
		||||
			<string>IBUILabel</string>
 | 
			
		||||
			<string>IBProxyObject</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<array key="IBDocument.PluginDependencies">
 | 
			
		||||
			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.Metadata">
 | 
			
		||||
			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
 | 
			
		||||
			<integer value="1" key="NS.object.0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 | 
			
		||||
			<object class="IBProxyObject" id="372490531">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBProxyObject" id="975951072">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUIView" id="191373211">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">274</int>
 | 
			
		||||
				<array class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
					<object class="IBUILabel" id="29623071">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">290</int>
 | 
			
		||||
						<string key="NSFrame">{{10, 5}, {296, 21}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="1013113918"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<int key="IBUIContentMode">7</int>
 | 
			
		||||
						<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<string key="IBUIText">Select an activity (scroll for more)</string>
 | 
			
		||||
						<object class="NSColor" key="IBUITextColor" id="216027142">
 | 
			
		||||
							<int key="NSColorSpace">1</int>
 | 
			
		||||
							<bytes key="NSRGB">MCAwIDAAA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
						<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">10</float>
 | 
			
		||||
						<object class="IBUIFontDescription" key="IBUIFontDescription" id="950407250">
 | 
			
		||||
							<int key="type">1</int>
 | 
			
		||||
							<double key="pointSize">17</double>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSFont" key="IBUIFont" id="63576769">
 | 
			
		||||
							<string key="NSName">Helvetica</string>
 | 
			
		||||
							<double key="NSSize">17</double>
 | 
			
		||||
							<int key="NSfFlags">16</int>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUITableView" id="1013113918">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">274</int>
 | 
			
		||||
						<string key="NSFrame">{{0, 32}, {320, 132}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="885245054"/>
 | 
			
		||||
						<object class="NSColor" key="IBUIBackgroundColor" id="373936525">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<bool key="IBUIAlwaysBounceVertical">YES</bool>
 | 
			
		||||
						<int key="IBUISeparatorStyle">1</int>
 | 
			
		||||
						<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
 | 
			
		||||
						<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
 | 
			
		||||
						<float key="IBUIRowHeight">44</float>
 | 
			
		||||
						<float key="IBUISectionHeaderHeight">22</float>
 | 
			
		||||
						<float key="IBUISectionFooterHeight">22</float>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUIView" id="885245054">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">266</int>
 | 
			
		||||
						<array class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
							<object class="IBUILabel" id="625104685">
 | 
			
		||||
								<reference key="NSNextResponder" ref="885245054"/>
 | 
			
		||||
								<int key="NSvFlags">266</int>
 | 
			
		||||
								<string key="NSFrame">{{11, 20}, {296, 21}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="885245054"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView" ref="621451586"/>
 | 
			
		||||
								<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
								<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
								<int key="IBUIContentMode">7</int>
 | 
			
		||||
								<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<string key="IBUIText">Enter a Moment URL</string>
 | 
			
		||||
								<reference key="IBUITextColor" ref="216027142"/>
 | 
			
		||||
								<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
								<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
								<float key="IBUIMinimumFontSize">10</float>
 | 
			
		||||
								<reference key="IBUIFontDescription" ref="950407250"/>
 | 
			
		||||
								<reference key="IBUIFont" ref="63576769"/>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBUITextField" id="621451586">
 | 
			
		||||
								<reference key="NSNextResponder" ref="885245054"/>
 | 
			
		||||
								<int key="NSvFlags">266</int>
 | 
			
		||||
								<string key="NSFrame">{{11, 51}, {291, 31}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="885245054"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView" ref="525343048"/>
 | 
			
		||||
								<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
								<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<int key="IBUIContentVerticalAlignment">0</int>
 | 
			
		||||
								<string key="IBUIText"/>
 | 
			
		||||
								<int key="IBUIBorderStyle">3</int>
 | 
			
		||||
								<object class="NSColor" key="IBUITextColor">
 | 
			
		||||
									<int key="NSColorSpace">3</int>
 | 
			
		||||
									<bytes key="NSWhite">MAA</bytes>
 | 
			
		||||
									<object class="NSColorSpace" key="NSCustomColorSpace" id="523142132">
 | 
			
		||||
										<int key="NSID">2</int>
 | 
			
		||||
									</object>
 | 
			
		||||
								</object>
 | 
			
		||||
								<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
 | 
			
		||||
								<float key="IBUIMinimumFontSize">17</float>
 | 
			
		||||
								<object class="IBUITextInputTraits" key="IBUITextInputTraits">
 | 
			
		||||
									<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="IBUIFontDescription" key="IBUIFontDescription">
 | 
			
		||||
									<int key="type">1</int>
 | 
			
		||||
									<double key="pointSize">14</double>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="NSFont" key="IBUIFont">
 | 
			
		||||
									<string key="NSName">Helvetica</string>
 | 
			
		||||
									<double key="NSSize">14</double>
 | 
			
		||||
									<int key="NSfFlags">16</int>
 | 
			
		||||
								</object>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBUIButton" id="525343048">
 | 
			
		||||
								<reference key="NSNextResponder" ref="885245054"/>
 | 
			
		||||
								<int key="NSvFlags">264</int>
 | 
			
		||||
								<string key="NSFrame">{{12, 113}, {142, 37}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="885245054"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView" ref="851809288"/>
 | 
			
		||||
								<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<int key="IBUIContentHorizontalAlignment">0</int>
 | 
			
		||||
								<int key="IBUIContentVerticalAlignment">0</int>
 | 
			
		||||
								<string key="IBUINormalTitle">Add Moment</string>
 | 
			
		||||
								<object class="NSColor" key="IBUIHighlightedTitleColor">
 | 
			
		||||
									<int key="NSColorSpace">1</int>
 | 
			
		||||
									<bytes key="NSRGB">MC40MzkyMTU2ODYzIDAuMTI1NDkwMTk2MSAwLjA2Mjc0NTA5ODA0AA</bytes>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="NSColor" key="IBUINormalTitleColor">
 | 
			
		||||
									<int key="NSColorSpace">1</int>
 | 
			
		||||
									<bytes key="NSRGB">MC42MzUyOTQxMTc2IDAuMzIxNTY4NjI3NSAwLjI1ODgyMzUyOTQAA</bytes>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="NSColor" key="IBUINormalTitleShadowColor">
 | 
			
		||||
									<int key="NSColorSpace">3</int>
 | 
			
		||||
									<bytes key="NSWhite">MC41AA</bytes>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="NSCustomResource" key="IBUINormalBackgroundImage">
 | 
			
		||||
									<string key="NSClassName">NSImage</string>
 | 
			
		||||
									<string key="NSResourceName">button_background.png</string>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="IBUIFontDescription" key="IBUIFontDescription">
 | 
			
		||||
									<int key="type">2</int>
 | 
			
		||||
									<double key="pointSize">15</double>
 | 
			
		||||
								</object>
 | 
			
		||||
								<object class="NSFont" key="IBUIFont">
 | 
			
		||||
									<string key="NSName">Helvetica-Bold</string>
 | 
			
		||||
									<double key="NSSize">15</double>
 | 
			
		||||
									<int key="NSfFlags">16</int>
 | 
			
		||||
								</object>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBUILabel" id="851809288">
 | 
			
		||||
								<reference key="NSNextResponder" ref="885245054"/>
 | 
			
		||||
								<int key="NSvFlags">266</int>
 | 
			
		||||
								<string key="NSFrame">{{11, 180}, {290, 21}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="885245054"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView"/>
 | 
			
		||||
								<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
								<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
								<int key="IBUIContentMode">7</int>
 | 
			
		||||
								<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<string key="IBUIText">Status:</string>
 | 
			
		||||
								<reference key="IBUITextColor" ref="216027142"/>
 | 
			
		||||
								<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
								<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
								<float key="IBUIMinimumFontSize">11</float>
 | 
			
		||||
								<reference key="IBUIFontDescription" ref="950407250"/>
 | 
			
		||||
								<reference key="IBUIFont" ref="63576769"/>
 | 
			
		||||
							</object>
 | 
			
		||||
						</array>
 | 
			
		||||
						<string key="NSFrame">{{0, 172}, {320, 244}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="625104685"/>
 | 
			
		||||
						<reference key="IBUIBackgroundColor" ref="373936525"/>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
				<string key="NSFrame">{{0, 64}, {320, 416}}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<reference key="NSWindow"/>
 | 
			
		||||
				<reference key="NSNextKeyView" ref="29623071"/>
 | 
			
		||||
				<object class="NSColor" key="IBUIBackgroundColor">
 | 
			
		||||
					<int key="NSColorSpace">3</int>
 | 
			
		||||
					<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
					<reference key="NSCustomColorSpace" ref="523142132"/>
 | 
			
		||||
				</object>
 | 
			
		||||
				<array key="IBUIGestureRecognizers" id="0"/>
 | 
			
		||||
				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
 | 
			
		||||
				<object class="IBUISimulatedNavigationBarMetrics" key="IBUISimulatedTopBarMetrics">
 | 
			
		||||
					<bool key="IBUIPrompted">NO</bool>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="IBObjectContainer" key="IBDocument.Objects">
 | 
			
		||||
			<array class="NSMutableArray" key="connectionRecords">
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">view</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">3</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">momentsTable</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="1013113918"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">17</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">momentStatus</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="851809288"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">25</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">addButton</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="525343048"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">28</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">momentURL</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="621451586"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">30</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">dataSource</string>
 | 
			
		||||
						<reference key="source" ref="1013113918"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">18</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="1013113918"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">19</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="621451586"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">31</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchEventConnection" key="connection">
 | 
			
		||||
						<string key="label">momentButton:</string>
 | 
			
		||||
						<reference key="source" ref="525343048"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
						<int key="IBEventType">7</int>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">20</int>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
			<object class="IBMutableOrderedSet" key="objectRecords">
 | 
			
		||||
				<array key="orderedObjects">
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">0</int>
 | 
			
		||||
						<reference key="object" ref="0"/>
 | 
			
		||||
						<reference key="children" ref="1000"/>
 | 
			
		||||
						<nil key="parent"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">1</int>
 | 
			
		||||
						<reference key="object" ref="191373211"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="29623071"/>
 | 
			
		||||
							<reference ref="885245054"/>
 | 
			
		||||
							<reference ref="1013113918"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-1</int>
 | 
			
		||||
						<reference key="object" ref="372490531"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">File's Owner</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-2</int>
 | 
			
		||||
						<reference key="object" ref="975951072"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">7</int>
 | 
			
		||||
						<reference key="object" ref="1013113918"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">26</int>
 | 
			
		||||
						<reference key="object" ref="29623071"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">27</int>
 | 
			
		||||
						<reference key="object" ref="885245054"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="621451586"/>
 | 
			
		||||
							<reference ref="525343048"/>
 | 
			
		||||
							<reference ref="625104685"/>
 | 
			
		||||
							<reference ref="851809288"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">13</int>
 | 
			
		||||
						<reference key="object" ref="625104685"/>
 | 
			
		||||
						<reference key="parent" ref="885245054"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">12</int>
 | 
			
		||||
						<reference key="object" ref="621451586"/>
 | 
			
		||||
						<reference key="parent" ref="885245054"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">16</int>
 | 
			
		||||
						<reference key="object" ref="525343048"/>
 | 
			
		||||
						<reference key="parent" ref="885245054"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">22</int>
 | 
			
		||||
						<reference key="object" ref="851809288"/>
 | 
			
		||||
						<reference key="parent" ref="885245054"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
			</object>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="flattenedProperties">
 | 
			
		||||
				<string key="-1.CustomClassName">GooglePlusSampleMomentsViewController</string>
 | 
			
		||||
				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="-2.CustomClassName">UIResponder</string>
 | 
			
		||||
				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="16.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<real value="0.0" key="16.IBUIButtonInspectorSelectedStateConfigurationMetadataKey"/>
 | 
			
		||||
				<string key="22.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="26.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="27.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			</dictionary>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
 | 
			
		||||
			<nil key="activeLocalization"/>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="localizations"/>
 | 
			
		||||
			<nil key="sourceID"/>
 | 
			
		||||
			<int key="maxID">31</int>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBClassDescriber" key="IBDocument.Classes">
 | 
			
		||||
			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
 | 
			
		||||
				<object class="IBPartialClassDescription">
 | 
			
		||||
					<string key="className">GooglePlusSampleMomentsViewController</string>
 | 
			
		||||
					<string key="superclassName">UIViewController</string>
 | 
			
		||||
					<object class="NSMutableDictionary" key="actions">
 | 
			
		||||
						<string key="NS.key.0">momentButton:</string>
 | 
			
		||||
						<string key="NS.object.0">id</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSMutableDictionary" key="actionInfosByName">
 | 
			
		||||
						<string key="NS.key.0">momentButton:</string>
 | 
			
		||||
						<object class="IBActionInfo" key="NS.object.0">
 | 
			
		||||
							<string key="name">momentButton:</string>
 | 
			
		||||
							<string key="candidateClassName">id</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="outlets">
 | 
			
		||||
						<string key="addButton">UIButton</string>
 | 
			
		||||
						<string key="momentStatus">UILabel</string>
 | 
			
		||||
						<string key="momentURL">UITextField</string>
 | 
			
		||||
						<string key="momentsTable">UITableView</string>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="addButton">
 | 
			
		||||
							<string key="name">addButton</string>
 | 
			
		||||
							<string key="candidateClassName">UIButton</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="momentStatus">
 | 
			
		||||
							<string key="name">momentStatus</string>
 | 
			
		||||
							<string key="candidateClassName">UILabel</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="momentURL">
 | 
			
		||||
							<string key="name">momentURL</string>
 | 
			
		||||
							<string key="candidateClassName">UITextField</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="momentsTable">
 | 
			
		||||
							<string key="name">momentsTable</string>
 | 
			
		||||
							<string key="candidateClassName">UITableView</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 | 
			
		||||
						<string key="majorKey">IBProjectSource</string>
 | 
			
		||||
						<string key="minorKey">./Classes/GooglePlusSampleMomentsViewController.h</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
		</object>
 | 
			
		||||
		<int key="IBDocument.localizationMode">0</int>
 | 
			
		||||
		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
 | 
			
		||||
		<int key="IBDocument.defaultPropertyAccessControl">3</int>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
 | 
			
		||||
			<string key="NS.key.0">button_background.png</string>
 | 
			
		||||
			<string key="NS.object.0">{1, 1}</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<string key="IBCocoaTouchPluginVersion">933</string>
 | 
			
		||||
	</data>
 | 
			
		||||
</archive>
 | 
			
		||||
							
								
								
									
										50
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,50 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleShareViewController.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <MessageUI/MFMailComposeViewController.h>
 | 
			
		||||
#import <MessageUI/MessageUI.h>
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
#import "GooglePlusShare.h"
 | 
			
		||||
 | 
			
		||||
// A view controller for the Google+ share dialog which contains a text field
 | 
			
		||||
// to prefill the user comment, and a text field for an optional URL to share.
 | 
			
		||||
// A Google+ share button is provided to launch the share dialog.
 | 
			
		||||
@interface GooglePlusSampleShareViewController : UIViewController<
 | 
			
		||||
    GooglePlusShareDelegate,
 | 
			
		||||
    UITextFieldDelegate,
 | 
			
		||||
    UIActionSheetDelegate,
 | 
			
		||||
    MFMailComposeViewControllerDelegate> {
 | 
			
		||||
  // The Google+ share object to manage the share dialog.
 | 
			
		||||
  GooglePlusShare *share_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The text to prefill the user comment in the share dialog.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UITextField *sharePrefillText;
 | 
			
		||||
// The URL resource to share in the share dialog.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UITextField *shareURL;
 | 
			
		||||
// A label to display the result of the share action.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UILabel *shareStatus;
 | 
			
		||||
// A toolbar to share via Google+ or email.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UIToolbar *shareToolbar;
 | 
			
		||||
 | 
			
		||||
// Called when the share button is pressed.
 | 
			
		||||
- (IBAction)shareButton:(id)sender;
 | 
			
		||||
// Called when the toolbar share button is pressed.
 | 
			
		||||
- (IBAction)shareToolbar:(id)sender;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										145
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.m
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,145 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSampleShareViewController.m
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleShareViewController.h"
 | 
			
		||||
 | 
			
		||||
#import "GooglePlusSampleAppDelegate.h"
 | 
			
		||||
 | 
			
		||||
@implementation GooglePlusSampleShareViewController
 | 
			
		||||
 | 
			
		||||
@synthesize sharePrefillText = sharePrefillText_;
 | 
			
		||||
@synthesize shareURL = shareURL_;
 | 
			
		||||
@synthesize shareStatus = shareStatus_;
 | 
			
		||||
@synthesize shareToolbar = shareToolbar_;
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
  [sharePrefillText_ release];
 | 
			
		||||
  [shareURL_ release];
 | 
			
		||||
  [shareStatus_ release];
 | 
			
		||||
  [share_ release];
 | 
			
		||||
  [shareToolbar_ release];
 | 
			
		||||
  [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - View lifecycle
 | 
			
		||||
 | 
			
		||||
- (void)viewDidLoad {
 | 
			
		||||
  // Set up Google+ share dialog.
 | 
			
		||||
  GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *)
 | 
			
		||||
      [[UIApplication sharedApplication] delegate];
 | 
			
		||||
  NSString *clientID = [GooglePlusSampleAppDelegate clientID];
 | 
			
		||||
  share_ = [[GooglePlusShare alloc] initWithClientID:clientID];
 | 
			
		||||
  share_.delegate = self;
 | 
			
		||||
  appDelegate.share = share_;
 | 
			
		||||
 | 
			
		||||
  [super viewDidLoad];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)viewDidUnload {
 | 
			
		||||
  GooglePlusSampleAppDelegate *appDelegate = (GooglePlusSampleAppDelegate *)
 | 
			
		||||
      [[UIApplication sharedApplication] delegate];
 | 
			
		||||
  appDelegate.share = nil;
 | 
			
		||||
  share_.delegate = nil;
 | 
			
		||||
  [share_ release];
 | 
			
		||||
  share_ = nil;
 | 
			
		||||
 | 
			
		||||
  [super viewDidUnload];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UITextFieldDelegate
 | 
			
		||||
 | 
			
		||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
 | 
			
		||||
  [textField resignFirstResponder];
 | 
			
		||||
  return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - GooglePlusShareDelegate
 | 
			
		||||
 | 
			
		||||
- (void)finishedSharing:(BOOL)shared {
 | 
			
		||||
  NSString *text = shared ? @"Success" : @"Canceled";
 | 
			
		||||
  shareStatus_.text = [NSString stringWithFormat:@"Status: %@", text];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - UIActionSheetDelegate
 | 
			
		||||
 | 
			
		||||
- (void)actionSheet:(UIActionSheet *)actionSheet
 | 
			
		||||
    didDismissWithButtonIndex:(NSInteger)buttonIndex {
 | 
			
		||||
  if (buttonIndex == 0) {
 | 
			
		||||
    [self shareButton:nil];
 | 
			
		||||
  } else if (buttonIndex == 1) {
 | 
			
		||||
    shareStatus_.text = @"Status: Sharing...";
 | 
			
		||||
    MFMailComposeViewController *picker =
 | 
			
		||||
        [[[MFMailComposeViewController alloc] init] autorelease];
 | 
			
		||||
    picker.mailComposeDelegate = self;
 | 
			
		||||
    [picker setSubject:sharePrefillText_.text];
 | 
			
		||||
    [picker setMessageBody:shareURL_.text isHTML:NO];
 | 
			
		||||
 | 
			
		||||
    [self presentModalViewController:picker animated:YES];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - MFMailComposeViewControllerDelegate
 | 
			
		||||
 | 
			
		||||
- (void)mailComposeController:(MFMailComposeViewController *)controller
 | 
			
		||||
          didFinishWithResult:(MFMailComposeResult)result
 | 
			
		||||
                        error:(NSError*)error {
 | 
			
		||||
  NSString *text;
 | 
			
		||||
  switch (result) {
 | 
			
		||||
    case MFMailComposeResultCancelled:
 | 
			
		||||
      text = @"Canceled";
 | 
			
		||||
      break;
 | 
			
		||||
    case MFMailComposeResultSaved:
 | 
			
		||||
      text = @"Saved";
 | 
			
		||||
      break;
 | 
			
		||||
    case MFMailComposeResultSent:
 | 
			
		||||
      text = @"Sent";
 | 
			
		||||
      break;
 | 
			
		||||
    case MFMailComposeResultFailed:
 | 
			
		||||
      text = @"Failed";
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      text = @"Not sent";
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  shareStatus_.text = [NSString stringWithFormat:@"Status: %@", text];
 | 
			
		||||
  [self dismissModalViewControllerAnimated:YES];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark - IBActions
 | 
			
		||||
 | 
			
		||||
- (IBAction)shareButton:(id)sender {
 | 
			
		||||
  NSString *inputURL = shareURL_.text;
 | 
			
		||||
  NSURL *urlToShare = [inputURL length] ? [NSURL URLWithString:inputURL] : nil;
 | 
			
		||||
  NSString *inputText = sharePrefillText_.text;
 | 
			
		||||
  NSString *text = [inputText length] ? inputText : nil;
 | 
			
		||||
  shareStatus_.text = @"Status: Sharing...";
 | 
			
		||||
  [[[[share_ shareDialog] setURLToShare:urlToShare] setPrefillText:text] open];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (IBAction)shareToolbar:(id)sender {
 | 
			
		||||
  UIActionSheet *actionSheet =
 | 
			
		||||
      [[[UIActionSheet alloc] initWithTitle:@"Share this post"
 | 
			
		||||
                                   delegate:self
 | 
			
		||||
                          cancelButtonTitle:@"Cancel"
 | 
			
		||||
                     destructiveButtonTitle:nil
 | 
			
		||||
                          otherButtonTitles:@"Google+", @"Email", nil]
 | 
			
		||||
          autorelease];
 | 
			
		||||
  [actionSheet showFromToolbar:shareToolbar_];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										493
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleShareViewController.xib
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,493 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
 | 
			
		||||
	<data>
 | 
			
		||||
		<int key="IBDocument.SystemTarget">1280</int>
 | 
			
		||||
		<string key="IBDocument.SystemVersion">10K549</string>
 | 
			
		||||
		<string key="IBDocument.InterfaceBuilderVersion">1938</string>
 | 
			
		||||
		<string key="IBDocument.AppKitVersion">1038.36</string>
 | 
			
		||||
		<string key="IBDocument.HIToolboxVersion">461.00</string>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			<string key="NS.object.0">933</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array key="IBDocument.IntegratedClassDependencies">
 | 
			
		||||
			<string>IBUIView</string>
 | 
			
		||||
			<string>IBProxyObject</string>
 | 
			
		||||
			<string>IBUILabel</string>
 | 
			
		||||
			<string>IBUIToolbar</string>
 | 
			
		||||
			<string>IBUIBarButtonItem</string>
 | 
			
		||||
			<string>IBUITextField</string>
 | 
			
		||||
			<string>IBUIButton</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<array key="IBDocument.PluginDependencies">
 | 
			
		||||
			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.Metadata">
 | 
			
		||||
			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
 | 
			
		||||
			<integer value="1" key="NS.object.0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 | 
			
		||||
			<object class="IBProxyObject" id="372490531">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBProxyObject" id="975951072">
 | 
			
		||||
				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBUIView" id="191373211">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">274</int>
 | 
			
		||||
				<array class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
					<object class="IBUITextField" id="914769097">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrame">{{20, 55}, {280, 31}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="72662020"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<int key="IBUIContentVerticalAlignment">0</int>
 | 
			
		||||
						<string key="IBUIText">http://developers.google.com/</string>
 | 
			
		||||
						<int key="IBUIBorderStyle">3</int>
 | 
			
		||||
						<object class="NSColor" key="IBUITextColor">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MAA</bytes>
 | 
			
		||||
							<object class="NSColorSpace" key="NSCustomColorSpace" id="191774102">
 | 
			
		||||
								<int key="NSID">2</int>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
						<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">17</float>
 | 
			
		||||
						<object class="IBUITextInputTraits" key="IBUITextInputTraits">
 | 
			
		||||
							<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBUIFontDescription" key="IBUIFontDescription" id="494599157">
 | 
			
		||||
							<int key="type">1</int>
 | 
			
		||||
							<double key="pointSize">14</double>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSFont" key="IBUIFont" id="583966885">
 | 
			
		||||
							<string key="NSName">Helvetica</string>
 | 
			
		||||
							<double key="NSSize">14</double>
 | 
			
		||||
							<int key="NSfFlags">16</int>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUITextField" id="410760382">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrame">{{20, 144}, {280, 31}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="483186074"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<int key="IBUIContentVerticalAlignment">0</int>
 | 
			
		||||
						<string key="IBUIText">Welcome to Google+ Platform</string>
 | 
			
		||||
						<int key="IBUIBorderStyle">3</int>
 | 
			
		||||
						<object class="NSColor" key="IBUITextColor">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MAA</bytes>
 | 
			
		||||
							<reference key="NSCustomColorSpace" ref="191774102"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">17</float>
 | 
			
		||||
						<object class="IBUITextInputTraits" key="IBUITextInputTraits">
 | 
			
		||||
							<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="IBUIFontDescription" ref="494599157"/>
 | 
			
		||||
						<reference key="IBUIFont" ref="583966885"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUILabel" id="108661184">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrame">{{20, 26}, {179, 21}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="914769097"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<int key="IBUIContentMode">7</int>
 | 
			
		||||
						<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<string key="IBUIText">URL to Share (optional)</string>
 | 
			
		||||
						<object class="NSColor" key="IBUITextColor" id="867790682">
 | 
			
		||||
							<int key="NSColorSpace">1</int>
 | 
			
		||||
							<bytes key="NSRGB">MCAwIDAAA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
						<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">10</float>
 | 
			
		||||
						<object class="IBUIFontDescription" key="IBUIFontDescription" id="1056628031">
 | 
			
		||||
							<int key="type">1</int>
 | 
			
		||||
							<double key="pointSize">17</double>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSFont" key="IBUIFont" id="1071033096">
 | 
			
		||||
							<string key="NSName">Helvetica</string>
 | 
			
		||||
							<double key="NSSize">17</double>
 | 
			
		||||
							<int key="NSfFlags">16</int>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUILabel" id="72662020">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrame">{{20, 115}, {156, 21}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="410760382"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<int key="IBUIContentMode">7</int>
 | 
			
		||||
						<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<string key="IBUIText">Prefill Text (optional)</string>
 | 
			
		||||
						<reference key="IBUITextColor" ref="867790682"/>
 | 
			
		||||
						<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
						<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">10</float>
 | 
			
		||||
						<reference key="IBUIFontDescription" ref="1056628031"/>
 | 
			
		||||
						<reference key="IBUIFont" ref="1071033096"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUIButton" id="483186074">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">292</int>
 | 
			
		||||
						<string key="NSFrame">{{21, 209}, {112, 32}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="94975264"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<int key="IBUIContentHorizontalAlignment">0</int>
 | 
			
		||||
						<int key="IBUIContentVerticalAlignment">0</int>
 | 
			
		||||
						<object class="NSColor" key="IBUIHighlightedTitleColor">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSColor" key="IBUINormalTitleColor">
 | 
			
		||||
							<int key="NSColorSpace">1</int>
 | 
			
		||||
							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSColor" key="IBUINormalTitleShadowColor">
 | 
			
		||||
							<int key="NSColorSpace">3</int>
 | 
			
		||||
							<bytes key="NSWhite">MC41AA</bytes>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSCustomResource" key="IBUINormalBackgroundImage">
 | 
			
		||||
							<string key="NSClassName">NSImage</string>
 | 
			
		||||
							<string key="NSResourceName">google_plus_share_large.png</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBUIFontDescription" key="IBUIFontDescription">
 | 
			
		||||
							<int key="type">2</int>
 | 
			
		||||
							<double key="pointSize">15</double>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSFont" key="IBUIFont">
 | 
			
		||||
							<string key="NSName">Helvetica-Bold</string>
 | 
			
		||||
							<double key="NSSize">15</double>
 | 
			
		||||
							<int key="NSfFlags">16</int>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUILabel" id="94975264">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">290</int>
 | 
			
		||||
						<string key="NSFrame">{{20, 283}, {280, 21}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="819777366"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClipsSubviews">YES</bool>
 | 
			
		||||
						<int key="IBUIContentMode">7</int>
 | 
			
		||||
						<bool key="IBUIUserInteractionEnabled">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<string key="IBUIText">Status:</string>
 | 
			
		||||
						<reference key="IBUITextColor" ref="867790682"/>
 | 
			
		||||
						<nil key="IBUIHighlightedColor"/>
 | 
			
		||||
						<int key="IBUIBaselineAdjustment">1</int>
 | 
			
		||||
						<float key="IBUIMinimumFontSize">15</float>
 | 
			
		||||
						<reference key="IBUIFontDescription" ref="1056628031"/>
 | 
			
		||||
						<reference key="IBUIFont" ref="1071033096"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBUIToolbar" id="819777366">
 | 
			
		||||
						<reference key="NSNextResponder" ref="191373211"/>
 | 
			
		||||
						<int key="NSvFlags">266</int>
 | 
			
		||||
						<string key="NSFrame">{{0, 372}, {320, 44}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="191373211"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView"/>
 | 
			
		||||
						<bool key="IBUIOpaque">NO</bool>
 | 
			
		||||
						<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
 | 
			
		||||
						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
						<array class="NSMutableArray" key="IBUIItems">
 | 
			
		||||
							<object class="IBUIBarButtonItem" id="937701942">
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<reference key="IBUIToolbar" ref="819777366"/>
 | 
			
		||||
								<int key="IBUISystemItemIdentifier">5</int>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBUIBarButtonItem" id="47552833">
 | 
			
		||||
								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
								<int key="IBUIStyle">1</int>
 | 
			
		||||
								<reference key="IBUIToolbar" ref="819777366"/>
 | 
			
		||||
								<int key="IBUISystemItemIdentifier">9</int>
 | 
			
		||||
							</object>
 | 
			
		||||
						</array>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
				<string key="NSFrame">{{0, 64}, {320, 416}}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<reference key="NSWindow"/>
 | 
			
		||||
				<reference key="NSNextKeyView" ref="108661184"/>
 | 
			
		||||
				<object class="NSColor" key="IBUIBackgroundColor">
 | 
			
		||||
					<int key="NSColorSpace">3</int>
 | 
			
		||||
					<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
					<reference key="NSCustomColorSpace" ref="191774102"/>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
 | 
			
		||||
				<object class="IBUISimulatedNavigationBarMetrics" key="IBUISimulatedTopBarMetrics">
 | 
			
		||||
					<bool key="IBUIPrompted">NO</bool>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
			</object>
 | 
			
		||||
		</array>
 | 
			
		||||
		<object class="IBObjectContainer" key="IBDocument.Objects">
 | 
			
		||||
			<array class="NSMutableArray" key="connectionRecords">
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">view</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">3</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">sharePrefillText</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="410760382"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">11</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">shareStatus</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="94975264"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">14</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">shareToolbar</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="819777366"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">19</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">shareURL</string>
 | 
			
		||||
						<reference key="source" ref="372490531"/>
 | 
			
		||||
						<reference key="destination" ref="914769097"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">21</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="914769097"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">23</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="410760382"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">22</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchEventConnection" key="connection">
 | 
			
		||||
						<string key="label">shareButton:</string>
 | 
			
		||||
						<reference key="source" ref="483186074"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
						<int key="IBEventType">7</int>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">10</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBCocoaTouchEventConnection" key="connection">
 | 
			
		||||
						<string key="label">shareToolbar:</string>
 | 
			
		||||
						<reference key="source" ref="47552833"/>
 | 
			
		||||
						<reference key="destination" ref="372490531"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">20</int>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
			<object class="IBMutableOrderedSet" key="objectRecords">
 | 
			
		||||
				<array key="orderedObjects">
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">0</int>
 | 
			
		||||
						<array key="object" id="0"/>
 | 
			
		||||
						<reference key="children" ref="1000"/>
 | 
			
		||||
						<nil key="parent"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">1</int>
 | 
			
		||||
						<reference key="object" ref="191373211"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="108661184"/>
 | 
			
		||||
							<reference ref="914769097"/>
 | 
			
		||||
							<reference ref="72662020"/>
 | 
			
		||||
							<reference ref="410760382"/>
 | 
			
		||||
							<reference ref="483186074"/>
 | 
			
		||||
							<reference ref="94975264"/>
 | 
			
		||||
							<reference ref="819777366"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-1</int>
 | 
			
		||||
						<reference key="object" ref="372490531"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">File's Owner</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-2</int>
 | 
			
		||||
						<reference key="object" ref="975951072"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">5</int>
 | 
			
		||||
						<reference key="object" ref="914769097"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">6</int>
 | 
			
		||||
						<reference key="object" ref="410760382"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">7</int>
 | 
			
		||||
						<reference key="object" ref="108661184"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">8</int>
 | 
			
		||||
						<reference key="object" ref="72662020"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">9</int>
 | 
			
		||||
						<reference key="object" ref="483186074"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">13</int>
 | 
			
		||||
						<reference key="object" ref="94975264"/>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">15</int>
 | 
			
		||||
						<reference key="object" ref="819777366"/>
 | 
			
		||||
						<array class="NSMutableArray" key="children">
 | 
			
		||||
							<reference ref="47552833"/>
 | 
			
		||||
							<reference ref="937701942"/>
 | 
			
		||||
						</array>
 | 
			
		||||
						<reference key="parent" ref="191373211"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">17</int>
 | 
			
		||||
						<reference key="object" ref="47552833"/>
 | 
			
		||||
						<reference key="parent" ref="819777366"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">18</int>
 | 
			
		||||
						<reference key="object" ref="937701942"/>
 | 
			
		||||
						<reference key="parent" ref="819777366"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</array>
 | 
			
		||||
			</object>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="flattenedProperties">
 | 
			
		||||
				<string key="-1.CustomClassName">GooglePlusSampleShareViewController</string>
 | 
			
		||||
				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="-2.CustomClassName">UIResponder</string>
 | 
			
		||||
				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="15.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="17.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="18.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
				<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
 | 
			
		||||
			</dictionary>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
 | 
			
		||||
			<nil key="activeLocalization"/>
 | 
			
		||||
			<dictionary class="NSMutableDictionary" key="localizations"/>
 | 
			
		||||
			<nil key="sourceID"/>
 | 
			
		||||
			<int key="maxID">23</int>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBClassDescriber" key="IBDocument.Classes">
 | 
			
		||||
			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
 | 
			
		||||
				<object class="IBPartialClassDescription">
 | 
			
		||||
					<string key="className">GooglePlusSampleShareViewController</string>
 | 
			
		||||
					<string key="superclassName">UIViewController</string>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="actions">
 | 
			
		||||
						<string key="shareButton:">id</string>
 | 
			
		||||
						<string key="shareToolbar:">id</string>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="actionInfosByName">
 | 
			
		||||
						<object class="IBActionInfo" key="shareButton:">
 | 
			
		||||
							<string key="name">shareButton:</string>
 | 
			
		||||
							<string key="candidateClassName">id</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBActionInfo" key="shareToolbar:">
 | 
			
		||||
							<string key="name">shareToolbar:</string>
 | 
			
		||||
							<string key="candidateClassName">id</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="outlets">
 | 
			
		||||
						<string key="sharePrefillText">UITextField</string>
 | 
			
		||||
						<string key="shareStatus">UILabel</string>
 | 
			
		||||
						<string key="shareToolbar">UIToolbar</string>
 | 
			
		||||
						<string key="shareURL">UITextField</string>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="sharePrefillText">
 | 
			
		||||
							<string key="name">sharePrefillText</string>
 | 
			
		||||
							<string key="candidateClassName">UITextField</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="shareStatus">
 | 
			
		||||
							<string key="name">shareStatus</string>
 | 
			
		||||
							<string key="candidateClassName">UILabel</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="shareToolbar">
 | 
			
		||||
							<string key="name">shareToolbar</string>
 | 
			
		||||
							<string key="candidateClassName">UIToolbar</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="IBToOneOutletInfo" key="shareURL">
 | 
			
		||||
							<string key="name">shareURL</string>
 | 
			
		||||
							<string key="candidateClassName">UITextField</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</dictionary>
 | 
			
		||||
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 | 
			
		||||
						<string key="majorKey">IBProjectSource</string>
 | 
			
		||||
						<string key="minorKey">./Classes/GooglePlusSampleShareViewController.h</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</array>
 | 
			
		||||
		</object>
 | 
			
		||||
		<int key="IBDocument.localizationMode">0</int>
 | 
			
		||||
		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
 | 
			
		||||
		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
 | 
			
		||||
		<int key="IBDocument.defaultPropertyAccessControl">3</int>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
 | 
			
		||||
			<string key="NS.key.0">google_plus_share_large.png</string>
 | 
			
		||||
			<string key="NS.object.0">{112, 32}</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<string key="IBCocoaTouchPluginVersion">933</string>
 | 
			
		||||
	</data>
 | 
			
		||||
</archive>
 | 
			
		||||
							
								
								
									
										40
									
								
								External/google-plus-ios-sdk/SampleCode/GooglePlusSampleSignInViewController.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
//  GooglePlusSignInViewController.h
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <UIKit/UIKit.h>
 | 
			
		||||
#import "GooglePlusSignIn.h"
 | 
			
		||||
 | 
			
		||||
@class GooglePlusSignInButton;
 | 
			
		||||
 | 
			
		||||
// A view controller for the Google+ sign-in button which initiates a standard
 | 
			
		||||
// OAuth 2.0 flow and provides an access token and a refresh token. A "Sign out"
 | 
			
		||||
// button is provided to allow users to sign out of this application.
 | 
			
		||||
@interface GooglePlusSampleSignInViewController : UIViewController<
 | 
			
		||||
    GooglePlusSignInDelegate>
 | 
			
		||||
 | 
			
		||||
// The button that handles Google+ sign-in.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet GooglePlusSignInButton *signInButton;
 | 
			
		||||
// A label to display the result of the sign-in action.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UILabel *signInAuthStatus;
 | 
			
		||||
// A button to sign out of this application.
 | 
			
		||||
@property (retain, nonatomic) IBOutlet UIButton *signOutButton;
 | 
			
		||||
 | 
			
		||||
// Called when the user presses the "Sign out" button.
 | 
			
		||||
- (IBAction)signOut:(id)sender;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||