NewsBlur/clients/ios/Other Sources/Overshare Kit/OSKFacebookUtility.m
2014-09-17 16:58:44 -07:00

189 lines
7.9 KiB
Objective-C
Executable file

//
// OSKFacebookUtility.m
// Overshare
//
// Created by Jared Sinclair 10/29/13.
// Copyright (c) 2013 Overshare Kit. All rights reserved.
//
@import Social;
#import "OSKFacebookUtility.h"
#import "OSKShareableContentItem.h"
#import "OSKSystemAccountStore.h"
#import "OSKLogger.h"
@implementation OSKFacebookUtility
+ (void)renewCredentials:(ACAccount *)account completion:(void(^)(BOOL success, NSError *error))completion {
[[OSKSystemAccountStore sharedInstance] renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *theError) {
if (completion) {
completion((renewResult == ACAccountCredentialRenewResultRenewed), theError);
}
}];
}
+ (void)postContentItem:(OSKFacebookContentItem *)item toSystemAccount:(ACAccount *)account options:(NSDictionary *)options completion:(void(^)(BOOL success, NSError *error))completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self renewCredentials:(ACAccount *)account completion:^(BOOL theSuccess, NSError *theError) {
if (theSuccess) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self _postContentItem:item toSystemAccount:account options:options completion:completion];
});
} else {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO, theError);
});
}
}
}];
});
}
+ (void)_postContentItem:(OSKFacebookContentItem *)item toSystemAccount:(ACAccount *)account options:(NSDictionary *)options completion:(void(^)(BOOL success, NSError *error))completion {
SLRequestHandler requestHandler = ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData != nil) {
__unused NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
OSKLog(@"%@", response);
NSInteger statusCode = urlResponse.statusCode;
if ((statusCode >= 200) && (statusCode < 300)) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(YES, nil);
});
}
else {
NSString *errorMessage = [NSString stringWithFormat:@"[OSKFacebookUtility] Error received when trying to create a new tweet. Server responded with status code %li and response: %@", (long)statusCode, [NSHTTPURLResponse localizedStringForStatusCode:statusCode]];
OSKLog(@"%@", errorMessage);
NSError *error = [NSError errorWithDomain:@"com.overshare.errors"
code:statusCode
userInfo:@{NSLocalizedFailureReasonErrorKey:errorMessage}];
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO, error);
});
}
}
else {
NSString *errorMessage = [NSString stringWithFormat:@"[OSKFacebookUtility] An error occurred while attempting to post a new tweet: %@", [error localizedDescription]];
OSKLog(@"%@", errorMessage);
NSError *error = [NSError errorWithDomain:@"com.overshare.errors"
code:400
userInfo:@{NSLocalizedFailureReasonErrorKey:errorMessage}];
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO, error);
});
}
};
if (item.images.count == 0) {
SLRequest *feedRequest = [self plainTextMessageRequestForContentItem:item options:options account:account];
[feedRequest performRequestWithHandler:requestHandler];
} else {
__block NSInteger remainingCount = item.images.count;
__block BOOL failed = NO;
NSIndexSet *successRange = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
for (UIImage *image in item.images) {
SLRequest *feedRequest = [self photoUploadRequestForContentItem:item options:options image:image account:account];
[feedRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
remainingCount--;
if (error != nil || [successRange containsIndex:[urlResponse statusCode]] == NO) {
failed = YES;
completion(NO, error);
}
if (remainingCount == 0 && failed == NO) {
completion(YES, nil);
}
});
}
}];
}
}
}
+ (SLRequest *)plainTextMessageRequestForContentItem:(OSKFacebookContentItem *)item options:(NSDictionary *)options account:(ACAccount *)account {
SLRequest *feedRequest = nil;
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
if (item.text.length) {
[parameters setObject:item.text.copy forKey:@"message"];
}
if (item.link.absoluteString) {
[parameters setObject:item.link.absoluteString forKey:@"link"];
}
[parameters setObject:[self _queryParameterForAudience:options[ACFacebookAudienceKey]] forKey:@"privacy"];
NSURL *feedURL = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];
feedRequest = [SLRequest
requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:feedURL
parameters:parameters];
feedRequest.account = account;
return feedRequest;
}
+ (SLRequest *)photoUploadRequestForContentItem:(OSKFacebookContentItem *)item options:(NSDictionary *)options image:(UIImage *)image account:(ACAccount *)account {
SLRequest *feedRequest = nil;
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
if (item.text.length) {
[parameters setObject:item.text.copy forKey:@"message"];
}
[parameters setObject:[self _queryParameterForAudience:options[ACFacebookAudienceKey]] forKey:@"privacy"];
NSURL *feedURL = [NSURL URLWithString:@"https://graph.facebook.com/me/photos"];
feedRequest = [SLRequest
requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:feedURL
parameters:parameters];
feedRequest.account = account;
NSData *imageData = UIImageJPEGRepresentation(image, 0.25f);
NSString *dateSuffix = [self _todaysDateSuffix];
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
NSString *filename = [NSString stringWithFormat:@"Image_from_%@_%@.jpg", appName, dateSuffix];
[feedRequest addMultipartData:imageData withName:@"source" type:@"image/jpeg" filename:filename];
return feedRequest;
}
+ (NSString *)_todaysDateSuffix {
NSDate *today = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
NSString *suffix = [formatter stringFromDate:today];
return suffix;
}
+ (NSString *)_queryParameterForAudience:(NSString *)audience {
NSString *param = nil;
if ([audience isEqualToString:ACFacebookAudienceEveryone]) {
param = @"{\"value\":\"EVERYONE\"}";
}
else if ([audience isEqualToString:ACFacebookAudienceFriends]) {
param = @"{\"value\":\"ALL_FRIENDS\"}";
}
else if ([audience isEqualToString:ACFacebookAudienceOnlyMe]) {
param = @"{\"value\":\"SELF\"}";
}
return param;
}
@end