NewsBlur/clients/ios/Other Sources/Overshare Kit/OSKTwitterActivity.m
2014-05-19 13:33:42 -07:00

254 lines
8.2 KiB
Objective-C
Executable file

//
// OSKTwitterActivity.m
// Overshare
//
//
// Copyright (c) 2013 Overshare Kit. All rights reserved.
//
@import Accounts;
#import "OSKTwitterActivity.h"
#import "OSKTwitterUtility.h"
#import "OSKMicrobloggingActivity.h"
#import "OSKShareableContentItem.h"
#import "OSKSystemAccountStore.h"
#import "OSKActivity_SystemAccounts.h"
#import "OSKTwitterText.h"
#import "NSString+OSKEmoji.h"
static NSInteger OSKTwitterActivity_MaxCharacterCount = 140;
static NSInteger OSKTwitterActivity_MaxUsernameLength = 20;
static NSInteger OSKTwitterActivity_MaxImageCount = 1;
static NSInteger OSKTwitterActivity_FallbackShortURLEstimate = 24;
@interface OSKTwitterActivity ()
@property (copy, nonatomic) NSNumber *estimatedShortURLLength_http;
@property (copy, nonatomic) NSNumber *estimatedShortURLLength_https;
@end
@implementation OSKTwitterActivity
@synthesize activeSystemAccount = _activeSystemAccount;
@synthesize remainingCharacterCount = _remainingCharacterCount;
- (instancetype)initWithContentItem:(OSKShareableContentItem *)item {
self = [super initWithContentItem:item];
if (self) {
//
}
return self;
}
#pragma mark - System Accounts
+ (NSString *)systemAccountTypeIdentifier {
return ACAccountTypeIdentifierTwitter;
}
#pragma mark - Methods for OSKActivity Subclasses
+ (NSString *)supportedContentItemType {
return OSKShareableContentItemType_MicroblogPost;
}
+ (BOOL)isAvailable {
return YES; // This is *in general*, not whether account access has been granted.
}
+ (NSString *)activityType {
return OSKActivityType_iOS_Twitter;
}
+ (NSString *)activityName {
return @"Twitter";
}
+ (UIImage *)iconForIdiom:(UIUserInterfaceIdiom)idiom {
UIImage *image = nil;
if (idiom == UIUserInterfaceIdiomPhone) {
image = [UIImage imageNamed:@"osk-twitterIcon-60.png"];
} else {
image = [UIImage imageNamed:@"osk-twitterIcon-76.png"];
}
return image;
}
+ (UIImage *)settingsIcon {
return [self iconForIdiom:UIUserInterfaceIdiomPhone];
}
+ (OSKAuthenticationMethod)authenticationMethod {
return OSKAuthenticationMethod_SystemAccounts;
}
+ (BOOL)requiresApplicationCredential {
return NO;
}
+ (OSKPublishingMethod)publishingMethod {
return OSKPublishingMethod_ViewController_Microblogging;
}
- (BOOL)isReadyToPerform {
BOOL accountPresent = (self.activeSystemAccount != nil);
BOOL textIsValid = (0 <= self.remainingCharacterCount && self.remainingCharacterCount < [self maximumCharacterCount]);
return (accountPresent && textIsValid);
}
- (void)performActivity:(OSKActivityCompletionHandler)completion {
__weak OSKTwitterActivity *weakSelf = self;
UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
if (completion) {
completion(weakSelf, NO, nil);
}
}];
[OSKTwitterUtility
postContentItem:(OSKMicroblogPostContentItem *)self.contentItem
toSystemAccount:self.activeSystemAccount
completion:^(BOOL success, NSError *error) {
if (completion) {
completion(weakSelf, (error == nil), error);
}
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];
}];
}
+ (BOOL)canPerformViaOperation {
return NO;
}
- (OSKActivityOperation *)operationForActivityWithCompletion:(OSKActivityCompletionHandler)completion {
return nil;
}
#pragma mark - Microblogging Activity Protocol
- (NSInteger)maximumCharacterCount {
return OSKTwitterActivity_MaxCharacterCount;
}
- (NSInteger)maximumImageCount {
return OSKTwitterActivity_MaxImageCount;
}
- (NSInteger)maximumUsernameLength {
return OSKTwitterActivity_MaxUsernameLength;
}
- (NSInteger)updateRemainingCharacterCount:(OSKMicroblogPostContentItem *)contentItem urlEntities:(NSArray *)urlEntities {
NSString *text = contentItem.text;
NSInteger estimatedShortURLLength_http = [self estimatedShortURLLength_http].integerValue;
NSInteger estimatedShortURLLength_https = [self estimatedShortURLLength_https].integerValue;
NSInteger textLengthAdjustmentForTCOLinks = 0;
for (OSKTwitterTextEntity *entity in urlEntities) {
NSString *urlText = [text substringWithRange:entity.range];
NSUInteger composedLength = [urlText osk_lengthAdjustingForComposedCharacters];
NSUInteger difference;
if ([urlText rangeOfString:@"https://"].location == 0) {
difference = estimatedShortURLLength_https - composedLength;
} else {
difference = estimatedShortURLLength_http - composedLength;
}
textLengthAdjustmentForTCOLinks += difference;
}
NSInteger composedLength = [text osk_lengthAdjustingForComposedCharacters];
NSInteger reservedLengthForImageAttachment = (contentItem.images.count) ? estimatedShortURLLength_http : 0;
NSInteger estimatedLength = composedLength + textLengthAdjustmentForTCOLinks + reservedLengthForImageAttachment;
NSInteger remainingCharacterCount = [self maximumCharacterCount] - estimatedLength;
[self setRemainingCharacterCount:remainingCharacterCount];
return remainingCharacterCount;
}
- (OSKSyntaxHighlighting)syntaxHighlighting {
return OSKSyntaxHighlighting_Usernames | OSKSyntaxHighlighting_Links | OSKSyntaxHighlighting_Hashtags;
}
- (BOOL)allowLinkShortening {
// Twitter's API wraps all links in t.co links that count as 23/24 characters,
// even short links. So there's no point in using a link shortening service.
return NO;
}
#pragma mark - Updating Estimated Short URL Lengths
- (NSNumber *)estimatedShortURLLength_http {
NSNumber *estimatedLength = nil;
if (_estimatedShortURLLength_http != nil) {
estimatedLength = _estimatedShortURLLength_http;
} else {
estimatedLength = @(OSKTwitterActivity_FallbackShortURLEstimate);
__weak OSKTwitterActivity *weakSelf = self;
[self updateOfficialShortURLLengths:^(NSInteger httpLength, NSInteger httpsLength, BOOL retrievedFromOfficialSource) {
[weakSelf setEstimatedShortURLLength_http:@(httpLength)];
[weakSelf setEstimatedShortURLLength_http:@(httpsLength)];
}];
}
return estimatedLength;
}
- (NSNumber *)estimatedShortURLLength_https {
NSNumber *estimatedLength = nil;
if (_estimatedShortURLLength_https != nil) {
estimatedLength = _estimatedShortURLLength_https;
} else {
estimatedLength = @(OSKTwitterActivity_FallbackShortURLEstimate);
__weak OSKTwitterActivity *weakSelf = self;
[self updateOfficialShortURLLengths:^(NSInteger httpLength, NSInteger httpsLength, BOOL retrievedFromOfficialSource) {
[weakSelf setEstimatedShortURLLength_http:@(httpLength)];
[weakSelf setEstimatedShortURLLength_http:@(httpsLength)];
}];
}
return estimatedLength;
}
- (void)updateOfficialShortURLLengths:(void(^)(NSInteger httpLength, NSInteger httpsLength, BOOL retrievedFromOfficialSource))completion {
if (self.activeSystemAccount) {
[OSKTwitterUtility
requestTwitterConfiguration:self.activeSystemAccount
completion:^(NSError *error, NSDictionary *configurationParameters) {
NSNumber *httpNumber = configurationParameters[OSKTwitterImageHttpURLLengthKey];
CGFloat httpEstimate = (httpNumber.integerValue)
? httpNumber.integerValue
: OSKTwitterActivity_FallbackShortURLEstimate;
NSNumber *httpsNumber = configurationParameters[OSKTwitterImageHttpsURLLengthKey];
CGFloat httpsEstimate = (httpsNumber.integerValue)
? httpsNumber.integerValue
: OSKTwitterActivity_FallbackShortURLEstimate;
if (completion) {
completion(httpEstimate, httpsEstimate, (httpNumber != nil && httpsNumber != nil));
}
}];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion(OSKTwitterActivity_FallbackShortURLEstimate, OSKTwitterActivity_FallbackShortURLEstimate, NO);
}
});
}
}
@end