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.
This commit is contained in:
441
External/google-plus-ios-sdk/OpenSource/GTMHTTPFetcherService.m
vendored
Normal file
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
|
Reference in New Issue
Block a user