how to pass self to function in other class in objective c - objective-c

Hi I am new in development of iOS. I make class named socialClass.h
#import <Social/Social.h>
#import <Accounts/Accounts.h>
- (void)facebookSharingStatusCheckCall:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew;
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew;
and in socialClass.m
- (void)facebookSharingStatusCheckCall:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew
{
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
NSLog(#"service available");
[self facebookForIosSix:url image:img status:text viewCont:uiVew];
} else {
// facebook for iOS 5 function will be called here
}
}
-(void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)uiVew
{
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
SLComposeViewController *fbcontroller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
SLComposeViewControllerCompletionHandler myBlock = ^(SLComposeViewControllerResult result){
if (result == SLComposeViewControllerResultCancelled) {
NSLog(#"Post Cancelled");
} else
{
NSLog(#"Post Done");
}
[fbcontroller dismissViewControllerAnimated:YES completion:Nil];
};
fbcontroller.completionHandler =myBlock;
//Adding the Text to the facebook post value from iOS
[fbcontroller setInitialText:text];
//Adding the URL to the facebook post value from iOS
[fbcontroller addURL:[NSURL URLWithString:url]];
//Adding the Image to the facebook post value from iOS
[fbcontroller addImage:[UIImage imageNamed:img]];
[uiVew presentViewController:fbcontroller animated:YES completion:nil];
}
else{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Sorry"
message:#"You can't Post a Status right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
NSLog(#"UnAvailable");
}
}
Now I call in mainViewController.h
#import "socialClass.h"
and in mainViewController.m
- (IBAction)facebookShareBtn:(id)sender {
[[socialClass facebookSharingStatusCheckCall:[[DataPassing sharedManager] pageURL ]
image:[[DataPassing sharedManager]
pageIMGurl]
status:[[DataPassing sharedManager] pageTEXT]]
viewCont:(UIViewController*)self];
}
When I use this below code with self it gives error. Definitely because there is no self view
[self presentViewController:fbcontroller animated:YES completion:nil];
so i put uiView in function and try to pass self from mainViewController. again error in mainview
How can I use this facebook from other calls function in mainviewcontroller. thx
[EDIT]
i declare socialClass.h in mainViewController and call the function in button
[socialClass facebookForIosSix:...]
This error is comming... after updating to (UIViewController*)self

OK, a couple of things need to change in you function definition.
First you need a - at the front not a +. The plus denotes a class method whereas the - is for an instance method. You are using this like an instance method.
Second you need to include MainViewController.h in your SocialClass.h file. Then name the function like...
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(MainViewController *)mainViewController;
Then in mainViewController you can run...
[socialViewController facebookSharingStatusCheckCall:#"url" image:#"hello.png" status:#"Posting from App" viewCont:self];
this should work fine.
EDIT
If you want to run the function fro multiple places then don't import MainViewController.h and define the function like...
- (void)facebookForIosSix:(NSString *)url image:(NSString *)img status:(NSString *)text viewCont:(UIViewController *)viewController;
then run it like...
[socialViewController facebookSharingStatusCheckCall:#"url" image:#"hello.png" status:#"Posting from App" viewCont:(UIViewController*)self];
TBH, I don't think you'll need to cast it at all but just to be safe you can.
EDIT
You haven't balanced your brackets...
- (IBAction)facebookShareBtn:(id)sender {
[socialClass facebookSharingStatusCheckCall:[[DataPassing sharedManager] pageURL ]
image:[[DataPassing sharedManager] pageIMGurl]
status:[[DataPassing sharedManager] pageTEXT]
viewCont:(UIViewController*)self];
}
This will work.

Related

How to fix '[LoginVC viewControllers]: unrecognized selector sent to instance'

Im trying to use split view controllers for iphone but when i add the code for AppDelegate.m as below, i get the error. My app also utilises a login system using file LoginVC and that file was working fine before.
[Storyboard image here][1]: https://i.stack.imgur.com/GRosR.png
#import "AppDelegate.h"
#import "RightVC.h"
#import "LeftVC.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UISplitViewController *splitViewController = (UISplitViewController
*)self.window.rootViewController;
UINavigationController *leftNavController =
[splitViewController.viewControllers objectAtIndex:0];
LeftVC *leftViewController = (LeftVC *)[leftNavController
topViewController];
RightVC *rightViewController = [splitViewController.viewControllers
objectAtIndex:1];
Recipe *firstRecipe = [[leftViewController recipes] objectAtIndex:0];
[rightViewController setRecipe:firstRecipe];
return YES;
}
And my LoginVC.m
#import "LoginVC.h"
#interface LoginVC ()
#end
#implementation LoginVC
- (void)viewDidLoad {
[super viewDidLoad];
self.checkLogin = [[LoginService alloc]init];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) alertStatus:(NSString *)msg :(NSString *) title: (int) tag {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil,
nil];
alertView.tag = tag;
[alertView show];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little
preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)btnLogin:(id)sender {
if([self.txtUsername.text isEqualToString:#""] || [self.txtPassword.text
isEqualToString:#""]) {
[self alertStatus:#"Username and/or Password cannot be blank!"
:#"Sign in Failed" :0];
} else{
self.checkLogin.strUsername = self.txtUsername.text;
self.checkLogin.strPassword = self.txtPassword.text;
BOOL lgs = self.checkLogin.success;
if(lgs==1){
[self performSegueWithIdentifier:#"ShowMain" sender:self];
}else{
[self alertStatus:#"Wrong Username and/or Password!" :#"Sign in
Failed":0];
}
}
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.txtUsername resignFirstResponder];
[self.txtPassword resignFirstResponder];
[[self.view window] endEditing:YES];
}
#end
Been trying to fix but all i have are a few split view guides on the net

iOS 8 Map Kit Obj-C Cannot Get Users Location

I am working with Map Kit in iOS 8 using Obj-C NOT SWIFT. I cannot get the device location it is set a 0.00, 0.00 and I am getting the error:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I have implemented: ( I have tried only one at a time and no luck )
if(IS_OS_8_OR_LATER) {
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
And in info.plist
NSLocationWhenInUseUsageDescription : App would like to use your location.
NSLocationAlwaysUsageDescription : App would like to use your location.
I do get prompted to allow the app to use my location but after I agree nothing changes. The location is being showed as 0.00, 0.00.
Code for displaying users location:
//Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
Mike.
**EDIT: View Answer Below.
I got it working. I've posted my code below to help anyone else having issues.
Here is my full code to get the MapKit Map View working in iOS 8.
In your AppName-Info.plist
Add a new row with the key name being:
NSLocationWhenInUseUsageDescription
Or
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
Enjoy!
--Mike
It's not written anywhere, but if your app starts with MapKit, you will still receive the error message "Trying to start MapKit location updates without prompting for location authorization" even after implementing MBarton's answer. To avoid it, you have to create a new view controller before the MapKit, and implement the location manager delegates there. I called it AuthorizationController.
So, in AuthorizationController.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MCIAuthorizationController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
And in AuthorizationController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Location manager
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
}
#pragma mark - Location Manager delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(#"didUpdateLocations: %#", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"Location manager error: %#", error.localizedDescription);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
[self performSegueWithIdentifier:#"startSegue" sender:self];
} else if (status == kCLAuthorizationStatusDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location services not authorized"
message:#"This app needs you to authorize locations services to work."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} else
NSLog(#"Wrong location status");
}
Try This One:
(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
Your code looks fine, though you do not need to call requestWhenInUseAuthorization and the other requestAlwaysAuthorization , choose one you need.
Code for displaying locations is just yet allocating locationManager, do not expect to get location data instantly.
you need to wait till delegate method gets called :
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
, then self.locationManager.location will also be set.
Further to Mikes answer, I found that using both [self.locationManager requestWhenInUseAuthorization]; and [self.locationManager requestAlwaysAuthorization]; as demonstrated in his code does not work. You should only use ONE.
I assume some further changes were made with a more recent/stable version of the API.
I had the same problem but adding these two line in plist file solved my problems
NSLocationWhenInUseUsageDescription
And
NSLocationAlwaysUsageDescription
NOTE : Must provide string description of both these values. You can use any of them in your controller file as below
self.locationManager= [[CLLocationManager alloc] init];
self.locationManager.delegate=self;
[self.locationManager requestAlwaysAuthorization];
You must implement CLLOcationManagerDelegate in your controller to access this functionality
To extend the accepted answer and if you create a sample project with just the above functionality, then apart from CoreLocation and Mapkit frameworks, you might need to add UIKit, Foundation and CoreGraphics framework manually as well in Xcode 6.
Actually, I am studying the CS193P Lecture 16, which is about location and map view, and I could not make the location manager work in iOS 8, applying what was in the video.
Looking at your answer, I could make it work.
The Info.plist was modified as described in the answers (I use the NSLocationWhenInUseUsageDescription).
In AddPhotoViewController.hn the define was added :
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
In AddPhotoViewController.m, the following code was added in ViewDidLoad (after self.image):
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
[self.locationManager requestWhenInUseAuthorization];
}
#endif
The authorization will be asked only once, the first time you launch the application.
The following was also added to AddPhotoViewController.h because it was not said in Lecture 16 :
#property (nonatomic) NSInteger locationErrorCode;
shouldPerformSegueWithIdentifier was modified to include else if (!self.location) :
else if (![self.titleTextField.text length])
{
[self alert:#"Title required"];
return NO;
}
else if (!self.location)
{
switch (self.locationErrorCode)
{
case kCLErrorLocationUnknown:
[self alert:#"Couldn't figure out where this photo was taken (yet)."]; break;
case kCLErrorDenied:
[self alert:#"Location Services disabled under Privacy in Settings application."]; break;
case kCLErrorNetwork:
[self alert:#"Can't figure out where this photo is being taken. Verify your connection to the network."]; break;
default:
[self alert:#"Cant figure out where this photo is being taken, sorry."]; break;
}
return NO;
}
else
{ // should check imageURL too to be sure we could write the file
return YES;
}
didFailWithError was added :
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
self.locationErrorCode = error.code;
}

application:openURL not triggered

I have a problem implementing - (BOOL)application:openURL and using UIDocumentInteractionController for exporting PDF file from an application to another.
(1) Target application does nothing but just display URL of the imported PDF file (in a label).
here is the code in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithText:#"No file is imported."];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication: (NSString *)sourceApplication annotation:(id)annotation
{
if (url != nil)
{
[self.viewController handleOpenURL:url];
return YES;
}
else
{
[self.viewController handleOpenURL:[NSURL fileURLWithPath:#"AppDelegate.h"]];
return NO;
}
}
Method "handleOpenURL" just take the url and put in a label in the view controller and show an alert:
- (void)handleOpenURL:(NSURL *)fileURL
{
_text = [fileURL absoluteString];
self.lblText.text = _text;
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:_text delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];
}
(2) In source application, I simply use UIDocumentInteractionController to list "Open In" options (my target application appears well in the list)
Here is the code:
_docInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:attachmentFile]];
_docInteractionController.delegate = self;
_docInteractionController.UTI = [_extensionUTIs objectForKey:[[attachmentFile pathExtension] lowercaseString]];
BOOL opened = [_docInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:NO];
(3) Problem:
- When I select the target application (from "Open In" list), simulator switches from source application to target application okay, but looks like application:openURL method is not invoked because the label keeps as initial (No file is imported.) and no alert view shows up.
Please advise me what could be wrong here ?
Thanks in advance.
I used these two methods for facebook integration to handle openURL...its working fine.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [ [[HIFacebookConnect sharedGameObject] facebook] handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[[HIFacebookConnect sharedGameObject] facebook] handleOpenURL:url];
}
Just want to mark my question as answered because I have already found the glitch.
Update: It was my fault when not including full file path when initiating UIDocumentInteractionController object.

Delegating UIAlertView to another class / file? Not working?

so I'm new to iOS development and I'm trying to delegate the button click event to another class. Whenever I click a button on the alert, the app crashes and I get an error saying Thread_1 EXC_BAD_ACCESS.
This is my code.
// theDelegateTester.h
#import <UIKit/UIKit.h>
#interface theDelegateTester : UIResponder <UIAlertViewDelegate>
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
Implementation..
// theDelegateTester.m
#import "theDelegateTester.h"
#implementation theDelegateTester
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"Delegated");
}
#end
And here's the implementation for my view file..
#import "appleTutorialViewController.h"
#import "theDelegateTester.h"
#interface appleTutorialViewController ()
- (IBAction)tapReceived:(id)sender;
#end
#implementation appleTutorialViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)tapReceived:(id)sender {
theDelegateTester *newTester = [[theDelegateTester alloc] init];
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"Alert!" message:#"This is a delegated alert" delegate:newTester cancelButtonTitle:#"Close" otherButtonTitles:#"Cool!", nil];
[myAlert show];
}
#end
First of all, you should always start your class names with a capital letter, so you can differentiate between classes and instances or methods easily.
And you probably leak the delegate class. You should declare a strong/retained property TheDelegateTester *myDelegate in your view controller. Then in tapReceived: something like this:
- (IBAction)tapReceived:(id)sender {
if (!self.myDelegate) {
TheDelegateTester *del = [[TheDelegateTester alloc] init];
self.myDelegate = del;
[del release];
}
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"Alert!" message:#"This is a delegated alert" delegate:newTester cancelButtonTitle:#"Close" otherButtonTitles:#"Cool!", nil];
[myAlert show];
[myAlert release];
}

Tab bar Controller and Facebook Connect Issues Xcode 4.3 IOS 5.1

I am trying to connect to the facebook and take the users name and picture, so far i can connect and fetch user name . i have a working code can be downloaded from here (single view application)
But if i put a tab bar controller to the code, it can not receive a response from facebook.
I add a tabbar controller programatically like below code
in app.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Regular Code
/*self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
*/
//Tab bar controller code
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIViewController *viewController1 = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.rootController = [[[UITabBarController alloc] init] autorelease];
self.rootController.viewControllers = [NSArray arrayWithObjects:viewController1, nil];
self.window.rootViewController = self.rootController;
[self.window makeKeyAndVisible];
return YES;
}
// This method will be used for iOS versions greater than 4.2.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[_viewController facebook] handleOpenURL:url];
}
If i put a breaking point at line handleOpenurl In NSUrl there is this= fbAPPID://authorize/#access_token=BABABSbbsabsbabb
I guess access_token means i have succesfully loged in . So tab bar doesnt block me to login put blokcs my facebook methods in Viewcontroller.m
Without tab bar all methods in Viewcontroller.m works great when i add tab bar and breakpoints none of the facebook methods below works. I dont get any errors though.
-(void)request:(FBRequest *)request didLoad:(id)result
-(void)fbDidLogin
ViewController.m
#import "ViewController.h"
#import "FBConnect.h"
#import "Facebook.h"
#implementation ViewController
#synthesize btnLogin;
#synthesize btnPublish;
#synthesize lblUser;
#synthesize actView;
#synthesize facebook;
#synthesize permissions;
#synthesize isConnected;
#synthesize imageView;
// The alert view that will be shown while the game will upload to facebook.
UIAlertView *msgAlert;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
-(void)checkForPreviouslySavedAccessTokenInfo{
// Initially set the isConnected value to NO.
isConnected = NO;
// Check if there is a previous access token key in the user defaults file.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"] &&
[defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
// Check if the facebook session is valid.
// If it’s not valid clear any authorization and mark the status as not connected.
if (![facebook isSessionValid]) {
[facebook authorize:nil];
isConnected = NO;
}
else {
isConnected = YES;
}
}
}
-(void)setLoginButtonImage{
UIImage *imgNormal;
UIImage *imgHighlighted;
UIImageView *tempImage;
// Check if the user is connected or not.
if (!isConnected) {
// In case the user is not connected (logged in) show the appropriate
// images for both normal and highlighted states.
imgNormal = [UIImage imageNamed:#"LoginNormal.png"];
imgHighlighted = [UIImage imageNamed:#"LoginPressed.png"];
}
else {
imgNormal = [UIImage imageNamed:#"LogoutNormal.png"];
imgHighlighted = [UIImage imageNamed:#"LogoutPressed.png"];
}
// Get the screen width to use it to center the login/logout button.
// We’ll use a temporary image view to get the appopriate width and height.
float screenWidth = [UIScreen mainScreen].bounds.size.width;
tempImage = [[UIImageView alloc] initWithImage:imgNormal];
[btnLogin setFrame:CGRectMake(screenWidth / 2 - tempImage.frame.size.width / 2, btnLogin.frame.origin.y, tempImage.frame.size.width, tempImage.frame.size.height)];
// Set the button’s images.
[btnLogin setBackgroundImage:imgNormal forState:UIControlStateNormal];
[btnLogin setBackgroundImage:imgHighlighted forState:UIControlStateHighlighted];
// Release the temporary image view.
[tempImage release];
}
-(void)showActivityView{
// Show an alert with a message without the buttons.
msgAlert = [[UIAlertView alloc] initWithTitle:#"My test app" message:#"Please wait..." delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[msgAlert show];
// Show the activity view indicator.
actView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 40.0, 40.0)];
[actView setCenter:CGPointMake(160.0, 350.0)];
[actView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[self.view addSubview:actView];
[actView startAnimating];
}
-(void)stopShowingActivity{
[actView stopAnimating];
[msgAlert dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)saveAccessTokenKeyInfo{
// Save the access token key info into the user defaults.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Set the permissions.
// Without specifying permissions the access to Facebook is imposibble.
permissions = [[NSArray arrayWithObjects:#"read_stream", #"publish_stream", nil] retain];
// Set the Facebook object we declared. We’ll use the declared object from the application
// delegate.
facebook = [[Facebook alloc] initWithAppId:#"331327710279153" andDelegate:self];
// Check if there is a stored access token.
[self checkForPreviouslySavedAccessTokenInfo];
// Depending on the access token existence set the appropriate image to the login button.
[self setLoginButtonImage];
// Specify the lblUser label's message depending on the isConnected value.
// If the access token not found and the user is not connected then prompt him/her to login.
if (!isConnected) {
[lblUser setText:#"Tap on the Login to connect to Facebook"];
}
else {
// Get the user's name from the Facebook account.
[facebook requestWithGraphPath:#"me" andDelegate:self];
}
// Initially hide the publish button.
[btnPublish setHidden:YES];
}
- (void)viewDidUnload
{
[self setBtnLogin:nil];
[self setLblUser:nil];
[self setBtnPublish:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
// Keep this just for testing purposes.
NSLog(#"received response");
}
-(void)request:(FBRequest *)request didLoad:(id)result{
// With this method we’ll get any Facebook response in the form of an array.
// In this example the method will be used twice. Once to get the user’s name to
// when showing the welcome message and next to get the ID of the published post.
// Inside the result array there the data is stored as a NSDictionary.
if ([result isKindOfClass:[NSArray class]]) {
// The first object in the result is the data dictionary.
result = [result objectAtIndex:0];
}
// Check it the “first_name” is contained into the returned data.
if ([result objectForKey:#"first_name"]) {
// If the current result contains the "first_name" key then it's the user's data that have been returned.
// Change the lblUser label's text.
[lblUser setText:[NSString stringWithFormat:#"Welcome %#!", [result objectForKey:#"first_name"]]];
// Show the publish button.
[btnPublish setHidden:NO];
}
else if ([result objectForKey:#"id"]) {
// Stop showing the activity view.
[self stopShowingActivity];
// If the result contains the "id" key then the data have been posted and the id of the published post have been returned.
UIAlertView *al = [[UIAlertView alloc] initWithTitle:#"My test app" message:#"Your message has been posted on your wall!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[al show];
[al release];
}
}
-(void)request:(FBRequest *)request didFailWithError:(NSError *)error{
NSLog(#"%#", [error localizedDescription]);
// Stop the activity just in case there is a failure and the activity view is animating.
if ([actView isAnimating]) {
[self stopShowingActivity];
}
}
-(void)fbDidLogin{
// Save the access token key info.
[self saveAccessTokenKeyInfo];
// Get the user's info.
[facebook requestWithGraphPath:#"me" andDelegate:self];
}
-(void)fbDidNotLogin:(BOOL)cancelled{
// Keep this for testing purposes.
//NSLog(#"Did not login");
UIAlertView *al = [[UIAlertView alloc] initWithTitle:#"My test app" message:#"Login cancelled." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[al show];
}
-(void)fbDidLogout{
// Keep this for testing purposes.
//NSLog(#"Logged out");
// Hide the publish button.
[btnPublish setHidden:YES];
}
- (IBAction)LoginOrLogout {
// If the user is not connected (logged in) then connect.
// Otherwise logout.
if (!isConnected) {
[facebook authorize:permissions];
// Change the lblUser label's message.
[lblUser setText:#"Please wait..."];
}
else {
[facebook logout:self];
[lblUser setText:#"Tap on the Login to connect to Facebook"];
}
isConnected = !isConnected;
[self setLoginButtonImage];
}
- (IBAction)Publish {
// Show the activity indicator.
[self showActivityView];
// Create the parameters dictionary that will keep the data that will be posted.
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"My test app", #"name",
#"http://www.google.com", #"link",
#"FBTestApp app for iPhone!", #"caption",
#"This is a description of my app", #"description",
#"Hello!\n\nThis is a test message\nfrom my test iPhone app!", #"message",
nil];
// Publish.
// This is the most important method that you call. It does the actual job, the message posting.
[facebook requestWithGraphPath:#"me/feed" andParams:params andHttpMethod:#"POST" andDelegate:self];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc {
[btnLogin release];
[lblUser release];
[btnPublish release];
[actView release];
[facebook release];
[permissions release];
[super dealloc];
}
#end
I am confused how can i make this tab bar controlling working.
I have changed the design
Now Login view is displayed first then it continues to real app which has tab bar controller.
Issue was _viewcontroller facebook , when _viewcontroller has been called it was not returning any thing
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[_viewController facebook] handleOpenURL:url];
}
So I changed my code(especially _viewcontroller line) to below code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIViewController * viewController1 = [[[VoteMe alloc] initWithNibName:#"VoteMe" bundle:nil] autorelease];
UIViewController *viewController2 = [[[PostController alloc] initWithNibName:#"PostController" bundle:nil] autorelease];
UIViewController *viewController3 = [[[FriendsController alloc] initWithNibName:#"FriendsController" bundle:nil] autorelease];
UIViewController *viewController4 = [[[Responses alloc] initWithNibName:#"Responses" bundle:nil] autorelease];
UIViewController *viewController5 = [[[User alloc] initWithNibName:#"User" bundle:nil] autorelease];
self.rootController = [[[UITabBarController alloc] init] autorelease];
self.rootController.viewControllers = [NSArray arrayWithObjects:viewController1,viewController2,viewController3,viewController4,viewController5, nil];
self.window.rootViewController = self.rootController;
[self.window makeKeyAndVisible];
loginView=[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self.window addSubview:loginView.view];
return YES;
}
// This method will be used for iOS versions greater than 4.2.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[loginView facebook] handleOpenURL:url];
}
It works fine