Permalink
Browse files

added DDSocialMessenger class that wraps accounts & social frameworks…

… and provides one shot methods to post tweets or fb messages
  • Loading branch information...
1 parent f5bef93 commit acced50ee6cf9f032a6aa12772e0927faf06d6e2 @Daij-Djan committed Apr 7, 2013
View
@@ -6,6 +6,8 @@ most of the classes are not tested and have no documentation. They also arent me
model:
<ul>
+<li><b>DDSocialMessenger [ios+osx]</b> - provides easy-to-use methods to post to twitter or facebook or both! It encapsulates all dealings with accounts and social framework
+
<li><b>BonjourServicesBrowser [ios+osx]</b> - asynchronously finds services using NSNetServiceBrowser
<li><b>DBPrefsWindowController [osx]</b> - a window controller that is tailored for doing preferences windows. (has a tabbar, crossfades. Meant to be subclassed. Based on class by Dave Batton)
@@ -75,17 +77,18 @@ screen
<li><b>M42WebviewTableViewCell [ios]</b> - Interesting cell that displays html content
-<li><b>NSWindow+localize [osx]</b>-Category on NSWindow that localizes itself and all its subviews. (knows many defacto default selectors so it works with many views out-of-the-box)
+<li><b>NSWindow+localize [osx]</b> - Category on NSWindow that localizes itself and all its subviews. (knows many defacto default selectors so it works with many views out-of-the-box)
-<li><b>NSWindow+Fade [osx]</b>-Category on NSWindow that adds fadeIn and fadeOut actions that work like animated order in order out
+<li><b>NSWindow+Fade [osx]</b> - Category on NSWindow that adds fadeIn and fadeOut actions that work like animated order in order out
-<li><b>NSView+findSubview [osx]</b>-Category on NSView that provides aa method to find a subview (by class and or tag) in its subview-tree.
+<li><b>NSView+findSubview [osx]</b> - Category on NSView that provides aa method to find a subview (by class and or tag) in its subview-tree.
-<li><b>NSWorkspace+IconBadging [osx] + demo</b>-Category on NSWorkspace that allows setting icon <b>badges</b> on files/folder (like dropbox or torquoise SVN). (wraps carbon's IconServices API for that)
+<li><b>NSWorkspace+IconBadging [osx] + demo</b> - Category on NSWorkspace that allows setting icon <b>badges</b> on files/folder (like dropbox or torquoise SVN). (wraps carbon's IconServices API for that)
-<li><b>NSAttributedString+DDConvenience [ios+osx]</b>-Category on NSAttributedString to create it from printf like varargs (like stringWithFormat:)<br/>
+<li><b>NSAttributedString+DDConvenience [ios+osx]</b> - Category on NSAttributedString to create it from printf like varargs (like stringWithFormat:)<br/>
On OSX there's also attributedStringWithImage.
+<li><b>UIAlertView+UserInfo [ios]</b> - Category on UIAlertView that adds a userInfo NSDictionary property to the alert that you can set and get (like it works for NSTimer)
</ul>
###ALL IS AVAIABLE under MIT
@@ -0,0 +1,23 @@
+//
+// DDSocialMessenger.h
+//
+// Created by Dominik Pich on 17.08.11.
+// Copyright (c) 2013 Dominik Pich. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <Accounts/ACAccountType.h>
+
+typedef void (^DDSocialMessengerCompletionBlock)(NSArray *accountsNotified);
+#define DDFacebookAppIdKey @"DDFacebookAppIdKey"
+
+@interface DDSocialMessenger : NSObject
+
++ (NSString*)facebookAppID; //read from info.plist
+
++ (void)postToTwitter:(NSString *)text completion:(DDSocialMessengerCompletionBlock)completion;
++ (void)postToFacebook:(NSString *)text completion:(DDSocialMessengerCompletionBlock)completion;
+
++ (void)broadcast:(NSString*)text to:(NSArray*)accounts completion:(DDSocialMessengerCompletionBlock)completion;
+
+@end
@@ -0,0 +1,133 @@
+//
+// DDSocialMessenger.m
+//
+// Created by Dominik Pich on 17.08.11.
+// Copyright (c) 2013 Dominik Pich. All rights reserved.
+//
+
+#import "DDSocialMessenger.h"
+#import <Accounts/Accounts.h>
+#import <Social/Social.h>
+
+@implementation DDSocialMessenger
+
++ (void)postToTwitter:(NSString *)text remaining:(NSMutableArray *)accounts done:(NSMutableArray*)accountsDone completion:(DDSocialMessengerCompletionBlock)completion {
+
+ ACAccountStore *accountStore = [[ACAccountStore alloc] init];
+ ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier: ACAccountTypeIdentifierTwitter];
+
+ [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
+ if (granted) {
+ NSArray *arrayOfAccounts = [accountStore accountsWithAccountType:accountType];
+ if ([arrayOfAccounts count] > 0) {
+ ACAccount *account = [arrayOfAccounts lastObject];
+
+ NSDictionary *message = @{@"status":text};
+ NSURL *requestURL = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.json"];
+ SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:message];
+ postRequest.account = account;
+
+ [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
+ if(urlResponse.statusCode==200) //all good
+ [accountsDone addObject:ACAccountTypeIdentifierTwitter];
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ }];
+
+ return;
+ }
+ }
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ }];
+}
+
++ (void)postToFacebook:(NSString *)text remaining:(NSMutableArray *)accounts done:(NSMutableArray*)accountsDone completion:(DDSocialMessengerCompletionBlock)completion {
+
+ ACAccountStore *accountStore = [[ACAccountStore alloc] init];
+ ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier: ACAccountTypeIdentifierFacebook];
+
+ // Specify FB App ID and permissions
+ NSString *facebookID = [self facebookAppID];
+ if(!facebookID.length) {
+ NSLog(@"Skipping Facebook as no AppID is specified");
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ return;
+ }
+
+ //first we need basic read rights THEN we publish
+ __block NSDictionary *options = @{ACFacebookAppIdKey: facebookID, ACFacebookPermissionsKey: @[@"email"], ACFacebookAudienceKey: ACFacebookAudienceOnlyMe};
+
+ [accountStore requestAccessToAccountsWithType:accountType options:options completion:^(BOOL granted, NSError *error) {
+ if (granted) {
+ options = @{ACFacebookAppIdKey: facebookID, ACFacebookPermissionsKey: @[@"publish_stream", @"publish_actions"], ACFacebookAudienceKey: ACFacebookAudienceFriends};
+
+ [accountStore requestAccessToAccountsWithType:accountType options:options completion:^(BOOL granted, NSError *error) {
+ if (granted) {
+ NSArray *arrayOfAccounts = [accountStore accountsWithAccountType:accountType];
+ if ([arrayOfAccounts count] > 0) {
+ ACAccount *account = [arrayOfAccounts lastObject];
+
+ NSDictionary *message = @{@"message":text};
+ NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];
+ SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:requestURL parameters:message];
+ postRequest.account = account;
+
+ [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
+ if(urlResponse.statusCode==200) //all good
+ [accountsDone addObject:ACAccountTypeIdentifierFacebook];
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ }];
+
+ return;
+ }
+ }
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ }];
+ return;
+ }
+ [self broadcast:text remaining:accounts done:accountsDone completion:completion];
+ }];
+}
+
++ (void)broadcast:(NSString *)text remaining:(NSMutableArray *)remaining done:(NSMutableArray*)accountsDone completion:(DDSocialMessengerCompletionBlock)completion {
+ if(remaining.count) {
+ id identifier = remaining[0];
+ [remaining removeObjectAtIndex:0];
+
+ if([identifier isEqualToString:ACAccountTypeIdentifierTwitter]) {
+ [self postToTwitter:text remaining:remaining done:accountsDone completion:completion];
+ }
+ else if([identifier isEqualToString:ACAccountTypeIdentifierFacebook]) {
+ [self postToFacebook:text remaining:remaining done:accountsDone completion:completion];
+ }
+ else {
+ NSLog(@"Skipping unknown account type %@", identifier);
+ [self broadcast:text remaining:remaining done:accountsDone completion:completion];
+ }
+ }
+ else {
+ if(completion) {
+ completion(accountsDone);
+ }
+ }
+}
+
+//---
+
++ (NSString*)facebookAppID {
+ return [[NSBundle mainBundle] objectForInfoDictionaryKey:DDFacebookAppIdKey];
+}
+
++ (void)postToTwitter:(NSString *)text completion:(DDSocialMessengerCompletionBlock)completion {
+ [self broadcast:text remaining:@[ACAccountTypeIdentifierTwitter].mutableCopy done:[NSMutableArray arrayWithCapacity:1] completion:completion];
+}
+
++ (void)postToFacebook:(NSString *)text completion:(DDSocialMessengerCompletionBlock)completion {
+ [self broadcast:text remaining:@[ACAccountTypeIdentifierFacebook].mutableCopy done:[NSMutableArray arrayWithCapacity:1] completion:completion];
+}
+
++ (void)broadcast:(NSString *)text to:(NSArray *)accounts completion:(DDSocialMessengerCompletionBlock)completion {
+ NSMutableArray *maccounts = [accounts mutableCopy];
+ NSMutableArray *mdone = [NSMutableArray array];
+ [self broadcast:text remaining:maccounts done:mdone completion:completion];
+}
+@end

0 comments on commit acced50

Please sign in to comment.