How to create a Twitter Helper Class with I-OS 5 support and I-OS 4 Fallback for cocos2d!
In my last article I wrode about how to create a Facebook Helper Class. This time I would like to write about how to create a Twitter Helper Class which uses the I-Os 5 implementation of Twitter, but provides a fallback for devices with I-OS 4.
Before we start, you need to download Ben Gottlieb’s Twitterengine as I use it for the fallback… when you downloaded it drag it into your XCode Project.
We need to add some Frameworks for this to work:
- Twitter.framework
- libxml2.dylib
You need to add this line to header search paths: $(SDKROOT)/usr/include/libxml2
Excursion: I added a root view controller instance in the app delegate:
@class RootViewController;
@interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
}
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic,retain) RootViewController *viewController;
@end
You need to synthesize it and change the
- (void) applicationDidFinishLaunching:(UIApplication*)application
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
First I would like to explain the TwitterHelper.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <Twitter/Twitter.h>
#import "AppDelegate.h"
#import "SA_OAuthTwitterController.h"
@interface TwitterHelper : NSObject<SA_OAuthTwitterControllerDelegate,UITextViewDelegate>{
AppDelegate *appDelegate;
BOOL iOS4vs5;
SA_OAuthTwitterEngine *_engine;
UIViewController * viewController;
UITextView *twitterTextView;
}
@property(assign)AppDelegate *appDelegate;
+(id)alloc;
+(TwitterHelper*)sharedTwitterHelper;
-(void)postTweed;
@end
Import this files into you .h file.
#import <UIKit/UIKit.h>
#import <Twitter/Twitter.h>
#import "AppDelegate.h"
#import "SA_OAuthTwitterController.h"
The Appdelegate.h is especially for cocos2d so we can access the root view controller.
Next we need to implement some delegates:
<SA_OAuthTwitterControllerDelegate,UITextViewDelegate>
The SA_OAuthTwitterControllerDelegate is needed for the fallback as well as the UITextViewDelegate.
Now we need to declare some variables:
AppDelegate *appDelegate;
BOOL iOS4vs5;
SA_OAuthTwitterEngine *_engine;
UIViewController * viewController;
UITextView *twitterTextView;
The appDelegate is needed to access the RootViewController, iOS4vs5 is to decide which kind of Twittercontroller is to be called, the textview and the Viewcontroller are needed for the IOs4 fallback.
The rest is adding the properties and the functions we need.
@property(assign)AppDelegate *appDelegate;
+(id)alloc;
+(TwitterHelper*)sharedTwitterHelper;
-(void)postTweed;
As I am trying to create the TwitterHelper Class as Semi-Singleton we need sharedTwitterHelper and alloc for this purpose. And postTweed is obvious :-)
TwitterHelper.m:
#import "TwitterHelper.h"
#import "SA_OAuthTwitterEngine.h"
#import "Common.h"
@interface TwitterHelper(PrivateMethods)
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
-(void)sendTweetWithString;
-(void)cancelTweet;
@end
@implementation TwitterHelper
@synthesize appDelegate;
static TwitterHelper *instanceOfTwitterHelper;
#pragma mark Singleton
+(TwitterHelper*)sharedTwitterHelper
{
@synchronized(self)
{
if (instanceOfTwitterHelper == nil)
{
[[TwitterHelper alloc] init];
}
return instanceOfTwitterHelper;
}
// to avoid compiler warning
return nil;
}
+(id) alloc
{
@synchronized(self)
{
NSAssert(instanceOfTwitterHelper == nil, @"Attempted to allocate a second instance of the singleton: TwitterHelper");
instanceOfTwitterHelper = [[super alloc] retain];
return instanceOfTwitterHelper;
}
// to avoid compiler warning
return nil;
}
-(id)init{
if ((self = [super init])) {
NSString *deviceVersion = [UIDevice currentDevice].systemVersion;
int deviceVersionInt = [deviceVersion intValue];
NSLog(@"DeviceVersion: %i",deviceVersionInt);
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (deviceVersionInt < 5) {
iOS4vs5 = NO;
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
}else if ((deviceVersionInt == 5)||(deviceVersionInt>5)) {
if ([TWTweetComposeViewController canSendTweet]) {
iOS4vs5 = YES;
}else {
iOS4vs5 = NO;
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
}
}
}
return self;
}
-(void)postTweed{
if (!iOS4vs5) {
viewController = [[[UIViewController alloc]init]autorelease];
UIView *view = [[[UIView alloc]init]autorelease];
view.backgroundColor = [UIColor blueColor];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
UIImageView *imageView = [[[UIImageView alloc]init]autorelease];
imageView.frame = CGRectMake(90, 10, 200, 150);
imageView.image = [UIImage imageNamed:@"logotwitter.png"];
[imageView sizeToFit];
[view addSubview:imageView];
twitterTextView = [[UITextView alloc]initWithFrame:CGRectMake(width *0.015625, 50, width *0.96875, 80)];
twitterTextView.delegate = self;
twitterTextView.text = @"Your Text";
[view addSubview:twitterTextView];
UIButton *tweetButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[tweetButton setTitle:@"tweet!" forState:UIControlStateNormal];
[tweetButton addTarget:self action:@selector(sendTweetWithString) forControlEvents:UIControlEventTouchDown];
tweetButton.frame = CGRectMake(width *0.78125f,125.0f, 331.0f, 32.0f);
[tweetButton sizeToFit];
[view addSubview:tweetButton];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelButton setTitle:NSLocalizedString(@"Back", @"TwitterHelper post to Wall:Back!") forState:UIControlStateNormal];
[cancelButton addTarget:self action:@selector(cancelTweet) forControlEvents:UIControlEventTouchDown];
cancelButton.frame = CGRectMake(width*0.03125f,125.0f, 331.0f, 32.0f);
[cancelButton sizeToFit];
[view addSubview:cancelButton];
viewController.view = view;
[appDelegate.viewController presentModalViewController:viewController animated:YES];
}else if (iOS4vs5) {
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:@"Your text"];
[tweetSheet addImage:[UIImage imageNamed:@"Your picture"]];
[tweetSheet addURL:[NSURL URLWithString:@"your Link"]];
[appDelegate.viewController presentModalViewController:tweetSheet animated:YES];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Sorry"
message:@"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
NSUInteger newLength = [textView.text length] + [text length] - range.length;
return (newLength > 140) ? NO : YES;
}
-(void)sendTweetWithString{
NSLog(@"%@",twitterTextView.text);
[_engine sendUpdate:twitterTextView.text];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
-(void)cancelTweet{
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
#pragma mark SA_OAuthTwitterEngineDelegate
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: @"authData"];
[defaults synchronize];
}
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {
return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];
}
#pragma mark TwitterEngineDelegate
- (void) requestSucceeded: (NSString *) requestIdentifier {
NSLog(@"Request %@ succeeded", requestIdentifier);
}
- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {
NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);
}
#pragma mark dealloc
-(void) dealloc
{
[twitterTextView release];
[_engine release];
[instanceOfTwitterHelper release];
instanceOfTwitterHelper = nil;
[super dealloc];
}
@end
So lets start with our .m file:
#import "SA_OAuthTwitterEngine.h"
#import "Common.h"
First we need to import SA_OAuthTwitterEngine.h.
I use a Common.h to store my Consumer Key and Consumer Secret like this:
#define kOAuthConsumerKey @”Your Twitter Consumer Key “
#define kOAuthConsumerSecret @”Your Twitter Consumer Secret”
Next up lets declare some private Methods:
@interface TwitterHelper(PrivateMethods)
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
-(void)sendTweetWithString;
-(void)cancelTweet;
@end
The first Method textView is to check the length of the string to make sure it is below 140 signs. The others are obvious… :-)
Lets have a look at the implementation:
@implementation TwitterHelper
@synthesize appDelegate;
static TwitterHelper *instanceOfTwitterHelper;
#pragma mark Singleton
+(TwitterHelper*)sharedTwitterHelper
{
@synchronized(self)
{
if (instanceOfTwitterHelper == nil)
{
[[TwitterHelper alloc] init];
}
return instanceOfTwitterHelper;
}
// to avoid compiler warning
return nil;
}
+(id) alloc
{
@synchronized(self)
{
NSAssert(instanceOfTwitterHelper == nil, @"Attempted to allocate a second instance of the singleton: TwitterHelper");
instanceOfTwitterHelper = [[super alloc] retain];
return instanceOfTwitterHelper;
}
// to avoid compiler warning
return nil;
}
After synthesizing the appdelegate variable we create a singleton instance, to make sure that there can’t be more then one TwitterHelper instance at the time.
Let’s have a look at the init Method, where most of the magic happens: ;-)
-(id)init{
if ((self = [super init])) {
NSString *deviceVersion = [UIDevice currentDevice].systemVersion;
int deviceVersionInt = [deviceVersion intValue];
NSLog(@"DeviceVersion: %i",deviceVersionInt);
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (deviceVersionInt < 5) {
iOS4vs5 = NO;
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
}else if ((deviceVersionInt == 5)||(deviceVersionInt>5)) {
if ([TWTweetComposeViewController canSendTweet]) {
iOS4vs5 = YES;
}else {
iOS4vs5 = NO;
}
}
}
return self;
}
First we create a string of the device version that is used:
NSString *deviceVersion = [UIDevice currentDevice].systemVersion;
Next we create an int from that:
int deviceVersionInt = [deviceVersion intValue];
Now we get our appdelegate instance:
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
Next we find out which IOs is on this device:
if (deviceVersionInt < 5) {
iOS4vs5 = NO;
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
}else if ((deviceVersionInt == 5)||(deviceVersionInt>5)) {
if ([TWTweetComposeViewController canSendTweet]) {
iOS4vs5 = YES;
}else {
iOS4vs5 = NO;
}
}
We set iOS4vs5 = NO if the int is below 5 else we set iOS4vs5 = YES.
In case the IOs is below 5 we initiate the Twitter Engine:
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
and autorize Twitter if necessary.
In case the device has iOs 5 or higher we check if we can use the Twitter.framework:
if ([TWTweetComposeViewController canSendTweet]) {
iOS4vs5 = YES;
}else {
iOS4vs5 = NO;
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
}
if(![_engine isAuthorized]){
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[appDelegate.viewController presentModalViewController: controller animated: YES];
}}
}
If there is no account on the device we set up the iOs4 version…
So let’s have a look at the postTweet Method:
-(void)postTweed{
if (!iOS4vs5) {
viewController = [[[UIViewController alloc]init]autorelease];
UIView *view = [[[UIView alloc]init]autorelease];
view.backgroundColor = [UIColor blueColor];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
UIImageView *imageView = [[[UIImageView alloc]init]autorelease];
imageView.frame = CGRectMake(90, 10, 200, 150);
imageView.image = [UIImage imageNamed:@"logotwitter.png"];
[imageView sizeToFit];
[view addSubview:imageView];
twitterTextView = [[UITextView alloc]initWithFrame:CGRectMake(width *0.015625, 50, width *0.96875, 80)];
twitterTextView.delegate = self;
twitterTextView.text = @"Your Text";
[view addSubview:twitterTextView];
UIButton *tweetButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[tweetButton setTitle:@"tweet!" forState:UIControlStateNormal];
[tweetButton addTarget:self action:@selector(sendTweetWithString) forControlEvents:UIControlEventTouchDown];
tweetButton.frame = CGRectMake(width *0.78125f,125.0f, 331.0f, 32.0f);
[tweetButton sizeToFit];
[view addSubview:tweetButton];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelButton setTitle:NSLocalizedString(@"Back", @"TwitterHelper post to Wall:Back!") forState:UIControlStateNormal];
[cancelButton addTarget:self action:@selector(cancelTweet) forControlEvents:UIControlEventTouchDown];
cancelButton.frame = CGRectMake(width*0.03125f,125.0f, 331.0f, 32.0f);
[cancelButton sizeToFit];
[view addSubview:cancelButton];
viewController.view = view;
[appDelegate.viewController presentModalViewController:viewController animated:YES];
}else if (iOS4vs5) {
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:@"Your Text"];
[tweetSheet addImage:[UIImage imageNamed:@"Your Image"]];
[tweetSheet addURL:[NSURL URLWithString:@"Your link"]];
[appDelegate.viewController presentModalViewController:tweetSheet animated:YES];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Sorry"
message:@"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
}
This Method is separated in two different parts, first the IOs 4 part:
if (!iOS4vs5) {
viewController = [[[UIViewController alloc]init]autorelease];
UIView *view = [[[UIView alloc]init]autorelease];
view.backgroundColor = [UIColor blueColor];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
UIImageView *imageView = [[[UIImageView alloc]init]autorelease];
imageView.frame = CGRectMake(90, 10, 200, 150);
imageView.image = [UIImage imageNamed:@"logotwitter.png"];
[imageView sizeToFit];
[view addSubview:imageView];
twitterTextView = [[UITextView alloc]initWithFrame:CGRectMake(width *0.015625, 50, width *0.96875, 80)];
twitterTextView.delegate = self;
twitterTextView.text = @"your text";
[view addSubview:twitterTextView];
UIButton *tweetButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[tweetButton setTitle:@"tweet!" forState:UIControlStateNormal];
[tweetButton addTarget:self action:@selector(sendTweetWithString) forControlEvents:UIControlEventTouchDown];
tweetButton.frame = CGRectMake(width *0.78125f,125.0f, 331.0f, 32.0f);
[tweetButton sizeToFit];
[view addSubview:tweetButton];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelButton setTitle:NSLocalizedString(@"Back", @"TwitterHelper post to Wall:Back!") forState:UIControlStateNormal];
[cancelButton addTarget:self action:@selector(cancelTweet) forControlEvents:UIControlEventTouchDown];
cancelButton.frame = CGRectMake(width*0.03125f,125.0f, 331.0f, 32.0f);
[cancelButton sizeToFit];
[view addSubview:cancelButton];
viewController.view = view;
[appDelegate.viewController presentModalViewController:viewController animated:YES];
}
As I did not want to make a Xib file for this I created a view controller within the Method:
viewController = [[[UIViewController alloc]init]autorelease];
UIView *view = [[[UIView alloc]init]autorelease];
view.backgroundColor = [UIColor blueColor];
First we set up the viewController we declared in our .h file, next we declare a view. I gave this view the color blue, but you can change that to your liking.
Next up we get the screen dimesions of the actual device, that is important as the TwitterHelper Class is designed to work on Ipad as well as on Iphone:
CGFloat width = [UIScreen mainScreen].bounds.size.width;
Next we create an image view to display the twitter logo. You can get logos from the Twitter resources page.
UIImageView *imageView = [[[UIImageView alloc]init]autorelease];
imageView.frame = CGRectMake(90, 10, 200, 150);
imageView.image = [UIImage imageNamed:@"logotwitter.png"];
[imageView sizeToFit];
[view addSubview:imageView];
And add this image view to our view we created before.
Next we create an UITextView:
twitterTextView = [[UITextView alloc]initWithFrame:CGRectMake(width *0.015625, 50, width *0.96875, 80)];
twitterTextView.delegate = self;
twitterTextView.text = @"Your Text";
[view addSubview:twitterTextView];
We use the width we got earlier to change the width according to the device the app is running on.
We set the delegate to self. In twitterTextView.text = @”Your Text” you can choose which text the user will be prompted to tweet… Then we add the text view to our view as well.
The next part is to create the necessary buttons Buttons:
UIButton *tweetButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[tweetButton setTitle:@"tweet!" forState:UIControlStateNormal];
[tweetButton addTarget:self action:@selector(sendTweetWithString) forControlEvents:UIControlEventTouchDown];
tweetButton.frame = CGRectMake(width *0.78125f,125.0f, 331.0f, 32.0f);
[tweetButton sizeToFit];
[view addSubview:tweetButton];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelButton setTitle:NSLocalizedString(@"Back", @"TwitterHelper post to Wall:Back!") forState:UIControlStateNormal];
[cancelButton addTarget:self action:@selector(cancelTweet) forControlEvents:UIControlEventTouchDown];
cancelButton.frame = CGRectMake(width*0.03125f,125.0f, 331.0f, 32.0f);
[cancelButton sizeToFit];
[view addSubview:cancelButton];
I use NSLocalizedString as it gives you the possibility to localize your app later…
And link the buttons to their Methods:
[tweetButton addTarget:self action:@selector(sendTweetWithString) forControlEvents:UIControlEventTouchDown];
[cancelButton addTarget:self action:@selector(cancelTweet) forControlEvents:UIControlEventTouchDown];
Next we set our view on the viewcontroller we declared earlier:
viewController.view = view;
At last we call the root controller an let him present our viewcontroller:
[appDelegate.viewController presentModalViewController:viewController animated:YES];
This is specifically for cocos2d…
The second part of the postTweet Method is for I-Os 5 when there is a Twitter account on the device:
else if (iOS4vs5) {
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:@"Your Text"];
[tweetSheet addImage:[UIImage imageNamed:@"Your Image"]];
[tweetSheet addURL:[NSURL URLWithString:@"Your link"]];
[appDelegate.viewController presentModalViewController:tweetSheet animated:YES];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Sorry"
message:@"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
The first part is to tweet via the Twitter.framework:
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:@"Your Text"];
[tweetSheet addImage:[UIImage imageNamed:@"Your Image"]];
[tweetSheet addURL:[NSURL URLWithString:@"Your link"]];
[appDelegate.viewController presentModalViewController:tweetSheet animated:YES];
}
First it is checked again if the app can send a tweet.
I just would like to mention the important parts:
[tweetSheet setInitialText:@"Your Text"];
[tweetSheet addImage:[UIImage imageNamed:@"Your Image"]];
[tweetSheet addURL:[NSURL URLWithString:@"Your link"]];
You can select which text will be prompted, you can choose a picture to be shown and add a link…
After that we let the root view controller present the twitter view:
[appDelegate.viewController presentModalViewController:tweetSheet animated:YES];
The second part:
else
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Sorry"
message:@"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
is just to make sure if anything gets wrong the user gets a feedback…
The next method is to make sure that in our IOs 4 version the user cannot type more than 140 signs:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
NSUInteger newLength = [textView.text length] + [text length] - range.length;
return (newLength > 140) ? NO : YES;
}
The next two methods are for the IOs4 version as well:
-(void)sendTweetWithString{
NSLog(@"%@",twitterTextView.text);
[_engine sendUpdate:twitterTextView.text];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
-(void)cancelTweet{
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
The sendTweetWithString obviously sends the text in the twitterTextView. The cancelTweet is the possibility for the user to cancel the operation.
The rest of the Methods is the integration of the SA_OAuthTwitterEngineDelegate:
#pragma mark SA_OAuthTwitterEngineDelegate
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: @"authData"];
[defaults synchronize];
}
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {
return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];
}
#pragma mark TwitterEngineDelegate
- (void) requestSucceeded: (NSString *) requestIdentifier {
NSLog(@"Request %@ succeeded", requestIdentifier);
}
- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {
NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);
}
And last but not least we clean the memory in our dealloc:
#pragma mark dealloc
-(void) dealloc
{
[twitterTextView release];
[_engine release];
[instanceOfTwitterHelper release];
instanceOfTwitterHelper = nil;
[super dealloc];
}
For the fallback I used Ben Gottlieb’s Twitterengine (Thank you Ben), it includes Matt Gemmell’s MGTwitterEngine (Thank you Matt), the OAuthConsumer Framework by Jon Crosby (Thanks Jon) and OAuth-MyTwitter by Chris Kimpton (Thanks Chris). And for the IOS 5 support I orientated myself on a tutorial by Mark Hammonds and a tutorial by Felipe Laso on Ray Wenderlich’ s site. I used some ideas from Steffen Itterheim’s Gamecenter Helper class.
Ok that was a really long post… again… I would appreciate your feedback and comments. If something is wrong or you have a question or an addition please tell me.
Next time I plan to go a bit into localization, if you have topics you would like to hear about, I’ll try my best…
I hope you enjoy this post and it helps you.
—————————-
Update: After the comment of Fenix I realized that I missed to mention that you need to add the Twitter-Framework as weak (optional). Thank you Fenix.