Learn the concept of Wrapper Class in Java along with its Implementation, benifits & methods. Also, explore Autoboxing and Unboxing in Java with examples.

#batman#dc#dc comics#bruce wayne#dick grayson#tim drake#dc fanart#batfamily#batfam

seen from Netherlands
seen from United States

seen from Germany
seen from China
seen from United States
seen from United States

seen from Malaysia
seen from Vietnam
seen from China
seen from United States
seen from United States
seen from Singapore
seen from United States
seen from Canada

seen from China
seen from Russia

seen from United States

seen from Türkiye
seen from China
seen from Russia
Learn the concept of Wrapper Class in Java along with its Implementation, benifits & methods. Also, explore Autoboxing and Unboxing in Java with examples.
What is Wrapper Class & How to use wrapper class in salesforce Visualforce?
Apex and Visualforce this can be to a great degree supportive to accomplish numerous business situations inside the Salesforce.
What is Wrapper class? Wrapper Class It is a custom question characterized by Salesforce designer where he characterizes the properties of the wrapper class. Inside to a great degree normal in Visualforce advancement to need to play out some change on information questioned out of Salesforce before showing that information. Each wrapper class looks somewhat changed, in light of the fact that it's exceptionally particular to the individual utilize case and Visualforce page. The general example frequently looks rather like this precedent, which wraps either a Contact or a Lead in an internal class, called Wrapper, of the page controller. Wrapper classes don't need to be inward classes; however the utilization of an internal class is normal and viable. Wrapper classes are in some routes like structures, association composes, or arithmetical composes given by different dialects, to the degree such examples are conceivable with the constrained contemplation and dynamism accessible in Apex.
Use of Wrapper Class Individuals have made the inquiries on how they can show a table of records with a check box and afterward process just the records that are chosen. You can utilize wrapper class to show records from numerous records inside a solitary table based around the business needs. About BISP Expertise:
We have superb learning stuff and material with business scenario designs. With regular and real-time examples our execution of training each day by experienced and profoundly qualified professionals. If you found this post is valuable for yourself, you can check our website for Instructor-Led training or learning courses & for more tips, tricks and methods for successful implementation of real world business scenarios in working life.
Our online training is a mixture of study materials, real-world scenario, Salesforce use cases, hands-on experience & real time project involvement in our training, so the candidate have a better understanding over concepts & fundamentals. We have recommend our experienced experts and real time professionals for the Salesforce certification training and their guidance out there, as well as they shares real time experience with candidates.
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.
How to create a Facebook Wrapper class for cocos2d? (I-OS)
As I am working on my new App, I was trying to implement Facebook, so the users can post on their wall, and as I had some trouble I thought I'll make a post on how to do that.
My target was to get as much of the Facebook implementation in one Class as I could get... I called it FacebookHelper Class like the GamkitHelper Class Steffen Itterheim created in his book Learn cocos2d Game Development with iOS 5. I tried to design it as a semi singleton.
So first things first :-) I used a lot of the Facebook Tutorial especially the first few steps:
1. Set up your app on Facebook.
2. Download the Facebook SDK and put the necessary files into your Xcode project. as well as changing the info.plist!
The necessary steps are on the Facebook developer site!
I would like to focus on creating a Facebook Helper Class:
As first step I created the FacebookHelper.h and FacebookHelper.m as an NSObject.
Let's have a look at the FacebookHelper.h:
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "FBConnect.h" #import "Common.h" @interface FacebookHelper : NSObject<UIApplicationDelegate,FBSessionDelegate,FBDialogDelegate>{ Facebook *facebook;
} @property (nonatomic, retain) Facebook *facebook; +(id)alloc; +(FacebookHelper*) sharedFacebookHelper; -(void)postToWall; @end
Import UIKit and FBConnect.h in my Common.h I store the Facebook Keys:
#define kFacebookAppId @"your App ID" #define kFacebookAppSecret @"Your App Secret"
Add the following delegates <UIApplicationDelegate,FBSessionDelegate,FBDialogDelegate> which are needed later on.
The next step is to create an instance of Facebook including a property.
As I tried to design the class as a semi singleton you need to implement the following methods:
+(id)alloc; +(FacebookHelper*) sharedFacebookHelper;
And to post on the Wall add the -(void)postToWall; as well.
The second part is the FacebookHelper.m:
#import "FacebookHelper.h" @implementation FacebookHelper @synthesize facebook; static FacebookHelper *instanceOfFacebookHelper; #pragma mark Singleton +(FacebookHelper*) sharedFacebookHelper { @synchronized(self) { if (instanceOfFacebookHelper == nil) { [[FacebookHelper alloc] init]; } return instanceOfFacebookHelper; } // to avoid compiler warning return nil; } +(id) alloc { @synchronized(self) { NSAssert(instanceOfFacebookHelper == nil, @"Attempted to allocate a second instance of the singleton: FacebookHelper"); instanceOfFacebookHelper = [[super alloc] retain]; return instanceOfFacebookHelper; } // to avoid compiler warning return nil; } #pragma mark init -(id)init { if ((self = [super init])) { facebook = [[Facebook alloc] initWithAppId:kFacebookAppId andDelegate:self]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; } NSLog(@"%@",facebook.isSessionValid? @"YES" : @"NO"); if (![facebook isSessionValid]) { [facebook authorize:nil]; } } return self; } #pragma mark - FBSessionDelegate Methods - (void)fbDidLogin { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"]; [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"]; [defaults synchronize]; NSLog(@"Did Log in!"); [self postToWall]; } - (void)fbDidNotLogin:(BOOL)cancelled{ NSLog(@"No Log in!"); } - (void)fbDidLogout{ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:@"FBAccessTokenKey"]; [defaults removeObjectForKey:@"FBExpirationDateKey"]; [defaults synchronize]; } - (void)fbDidExtendToken:(NSString*)accessToken expiresAt:(NSDate*)expiresAt{ NSLog(@"token extended"); [self storeAuthData:accessToken expiresAt:expiresAt]; } - (void)fbSessionInvalidated{ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Auth Exception" message:@"Your session has expired." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alertView show]; [alertView release]; [self fbDidLogout]; } - (void)storeAuthData:(NSString *)accessToken expiresAt:(NSDate *)expiresAt { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:accessToken forKey:@"FBAccessTokenKey"]; [defaults setObject:expiresAt forKey:@"FBExpirationDateKey"]; [defaults synchronize]; } -(void)postToWall{ NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys: kFacebookAppId, @"app_id", @"http:// www. yourwebsite. com", @"link", @"http:// www. yourpicture. com/picture.png", @"picture", @"Your Title!", @"name", @"Your caption!", @"caption", @"Your description", @"description", nil]; [facebook dialog:@"feed" andParams:params andDelegate:self]; } #pragma mark dealloc -(void) dealloc { [facebook release]; [instanceOfFacebookHelper release]; instanceOfFacebookHelper = nil; [super dealloc]; } @end
Ok, I will go through the methods one by one and describe what each one does:
Don’t forget to @synthesize facebook…
First I create a static instance of FacebookHelper. This instance will be returned to the calling class.
The +(FacebookHelper*) sharedFacebookHelper and +(id) alloc methods make sure only one Instance of FaceBookHelper is used at all times.
In the init method the facebook variable is initilized with the app id and self as delegate.
Furthermore the access token and the expiry date is accessed from the user defaults:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; }
And it is checked if the session is valid. If not facebook is authorized:
if (![facebook isSessionValid]) { [facebook authorize:nil]; //here is the possibility to ask for more permissions! }
The next few methods are delegate methods for FBConnect:
The fbDidLogin method stores the access token and the expiry date, which can be used to access Facebook next time without extra authorization. In my case I added a call to post here to make it easier for me.
The next one fbDidNotLogin gives you feedback if the user cancelled.
The fbDidLogout handles if the user logs out and removes the access token.
The fbDidExtendToken:(NSString*)accessToken expiresAt:(NSDate*)expiresAt method extends the access token.
The fbSessionInvalidated gives the user feedback if the session was invalidated for some reason.
The storeAuthData method is used to save the extension of the access token.
In the postToWall you can give the information you want to post with the users comment, you can localize the with NSLocalizedString.
The last step is to #import "FacebookHelper.h" in the class you want to call Facebook from.
You can call it like that:
FacebookHelper *facebookHelper = [FacebookHelper sharedFacebookHelper]; NSLog(@"%@",facebookHelper.description); if (facebookHelper.facebook.isSessionValid) { [facebookHelper saveScore:scoreVal]; [facebookHelper postToWall]; }
Ok, that was a long post, I hope it helps you to implement Facebook in your App. As you see you can expand the class to your liking... and add more features. As this is my first tutorial, I would appreciate some feedback and would be happy to add your suggestions...
Next time I plan to make a tutorial of my Twitter Helper class with I-OS 5 support and I-OS 4 fallback. So stay tuned...