Heads Up: I'm not too comfortable with Objective C to know exactly what I'm talking about..
Here's my life story:
My app basically consists of 3 views: main, facebook, and twitter.. No problems with the twitter, no problems switching back and forth between views until... bum bum bum.. I started using the Facebook API in guidance from this site: http://www.mobisoftinfotech.com/blog/iphone/iphone-fbconnect-facebook-connect-tutorial/
Now I can connect to FB and use their API and post without any problem, but when I switch back from the Facebook View on my app to the main view, it switches and then immediately crashes..
FacebookViewController.m
#import "FacebookViewController.h"
#import "Crush_LoveAppDelegate.h"
#define _APP_KEY #"43e37a535cc09c2013bd76fde78dfcc7"
#define _SECRET_KEY #"cc14801521a0c4d1dc31b7cacb891072"
#implementation FacebookViewController
#synthesize facebookFeed;
#synthesize delegate;
#synthesize loginButton;
#synthesize facebookAlert;
#synthesize usersession;
#synthesize username;
#synthesize post;
- (void)viewDidLoad {
Crush_LoveAppDelegate *appDelegate =
(Crush_LoveAppDelegate *) [[UIApplication
sharedApplication]delegate];
if (appDelegate._session == nil){
appDelegate._session = [FBSession sessionForApplication:_APP_KEY secret:_SECRET_KEY delegate:self];
}
if(self.loginButton == NULL)
self.loginButton = [[[FBLoginButton alloc] init] autorelease];
loginButton.frame = CGRectMake(110, 200, 100, 50);
[self.view addSubview:loginButton];
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
}
- (IBAction)done:(id)sender {
[self.delegate facebookViewControllerDidFinish:self];
}
FacebookViewController.h
#import <UIKit/UIKit.h>
#import "FBConnect/FBConnect.h"
#import "FBConnect/FBSession.h"
#import "FBConnect/FBRequest.h"
#import "FBConnect/FBStreamDialog.h"
#protocol FacebookViewControllerDelegate;
#interface FacebookViewController : UIViewController <UIApplicationDelegate, FBSessionDelegate, FBRequestDelegate>{
IBOutlet UIWebView *facebookFeed;
id <FacebookViewControllerDelegate> delegate;
FBLoginButton *loginButton;
UIAlertView *facebookAlert;
FBSession *usersession;
NSString *username;
BOOL post;
}
#property(nonatomic,retain) FBLoginButton *loginButton;
#property(nonatomic,retain) UIAlertView *facebookAlert;
#property(nonatomic,retain) FBSession *usersession;
#property(nonatomic,retain) NSString *username;
#property(nonatomic,assign) BOOL post;
#property (nonatomic, assign) id <FacebookViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIWebView *facebookFeed;
- (IBAction)done:(id)sender;
#end
#protocol FacebookViewControllerDelegate
- (void)facebookViewControllerDidFinish:(FacebookViewController *)controller;
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
-(void)getFacebookName;
-(void)postToWall;
#end
I chopped some of the .m off of the post to save space, but you get the idea.. I've narrowed it down and it seems like the problem is caused during this line in .m
appDelegate._session = [FBSession sessionForApplication:_APP_KEY secret:_SECRET_KEY delegate:self];
I've been trying to debug it myself for a few hours and I don't know enough on my own to diagnose it myself..
Any thoughts?
Im not sure why your app is crashing, but thought I'd mention that there are a few really good Apple WWDC videos about bug checking and crashing in XCode. In particular, "Debugging with Xcode 4 and LLDB" and "Understanding Crash Reports on iPhone OS", both from the WWDC 2010 videos. I believe you need a developer login to access these videos however but certainly worth a look if you're interested in learning more about debugging.
Okay, for anyone else who had this issue, here's what I did..
FacebookViewController.m File
- (void)dealloc {
[username release];
[usersession release];
[loginButton release];
[super dealloc];
}
I commented out the [loginButton release]; line and it worked oddly enough.. I don't know if this will give me serious problems down the road, but it works for now..
Related
I just got to start developing for ios 6 on xcode.
But as a novice developer, i have come into a problem.
Following the guide in the book 'beginning ios5 development: exploring the ios sdk' on chapter 3, the 'Button fun' example.
I am having problems with the identifier 'statusText' which i have already declared in the .h code.
Here's my code so far, any help would be highly appreciated. thank you in advance.
my BIDViewController.h is like so
#import <UIKit/UIKit.h>
#interface BIDViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *
statusText;
- (IBAction)buttonPress:(UIButton *)sender;
#end`
and my BIDViewController.m is like so
#import "BIDViewController.h"
#interface BIDViewController ()
#end
#implementation BIDViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonPress:(UIButton *)sender {
NSString *title = [sender titleForState:<#(UIControlState)#>];
statusText.text = [NSString stringWithFormat:#"%# button pressed.", title];
}
#end
i have followed the book but can't seem to understand why this occurs, pls help.
Well, for starters, this should be only one line
#property (weak, nonatomic) IBOutlet UILabel *statusText;
Now, when you declare a property, you don't get a variable named like that unless you synthesize it like this:
#implementation Class
#synthesize propertyName;
#end
That's why statusText doesn't exist.
You have three options:
Synthesize statusText like that so you can use that ivar.
instead of accessing the var directly, access the property like this self.statusText.
XCode is creating it's own variable, it's probably named _statusText, access it like that to access the variable directly.
You can also use a combination of 2 and 3
I am using the same book and had that problem, too. I have learned to use an underscore in the .m file
- (IBAction)buttonPressed:(UIButton *)sender {
NSString *title = [sender titleForState:UIControlStateNormal];
**_statusText**.text = [NSString stringWithFormat:#"%# button pressed.", title];
}
I found several posts online stating that I could access my application delegate object from any view controller through the following call:
[[UIApplication sharedApplicaton] delegate];
(For instance: data between Views UIApplication, iOS - Calling App Delegate method from ViewController)
However, whenever I include this line in a function in one of my view controllers, the application crashes.
This is the first application that I'm writing, and I cannot see the difference between my code and how other posts have said I should be using this sharedApplication call. For completeness, below is an excerpt from my application delegate and view controller.
FirstViewController.h:
#class wStreamAppDelegate;
#define URL_ADDRESS #"http://google.com"
#interface FirstViewController : UIViewController <UIWebViewDelegate>{
IBOutlet UIWebView * webView;
wStreamAppDelegate* appDelegate;
}
#property(nonatomic,retain) wStreamAppDelegate* appDelegate;
#property(nonatomic,retain) IBOutlet UIWebView* webView;
FirstViewController.m:
#import "FirstViewController.h"
#import "wStreamAppDelegate.h"
#implementation FirstViewController
#synthesize webView,appDelegate;
#class wStreamAppDelegate;
- (void)viewDidLoad {
[super viewDidLoad];
NSString* urlAddress = URL_ADDRESS;
NSURL* url = [NSURL URLWithString:urlAddress];
NSURLRequest * requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
self.appDelegate = (wStreamAppDelegate*)[[UIApplication sharedApplicaton] delegate];
//This doesn't work either
// wStreamAppDelegate *appDelegate= (wStreamAppDelegate*)[[UIApplication sharedApplicaton] delegate];
wStreamAppDelegate.h:
#interface wStreamAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
If anyone has any thoughts on what may be going wrong, general advice for debugging problems like these, or tips, I'd really appreciate it. Thanks.
Typos get everyone sooner or later... in this case, you wrote "sharedApplicaton" instead of "sharedApplication".
I have recently started to learn Obj-C and Iphone development basically through Lynda.com iOs SDK essentials course. But it was written for Xcode 3.x and I have 4.0.x installed, so things are different.
Basically, I take example from there and it just doesn't work for me and I can't figure it out being a noob to it.
//basicViewController.h
#import <UIKit/UIKit.h>
#interface basicViewController : UIViewController {
IBOutlet UITextField *txtName;
IBOutlet UILabel *lblMessage;
}
#property (nonatomic, retain) IBOutlet UITextField *txtName;
#property (nonatomic, retain) IBOutlet UILabel *lblMessage;
- (IBAction) doSomething;
#end
And my basicViewController.m
#import "basicViewController.h"
#implementation basicViewController
#synthesize txtName;
#synthesize lblMessage;
- (IBAction) doSomething
{
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#",txtName.text];
[lblMessage setText:msg];
[msg release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
I haven't changed basicAppDelegate.h and .m from what they were created like. I think I will post them anyway.
//
// basicAppDelegate.h
#import <UIKit/UIKit.h>
#class basicViewController;
#interface basicAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
basicViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet basicViewController *viewController;
#end
//
// basicAppDelegate.m
#import "basicAppDelegate.h"
#import "basicViewController.h"
#implementation basicAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
And here's my main.m:
//
// main.m
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Also, on the Interface Builder window I have linked through File's Owner: label to lblMessage, TextField to txtName and doSomething to Button.
Now, the problem is: actually, the thing kinda works, only if I use the popup keyboard, not my physical one. And only if I type less than 3-4-5 symbols(differs sometimes).
If I use my keyboard, not the popping one - it gives me Thread 1 received signal EXC_BAD_ACCESS.
Same if I type too many symbols.
And I don't see much in All Output - just some usual stuff, the only suspicious line is:
warning:unable to compile regular expression "dyld"
Current language: auto; currently objective-c
(gdb)
So, guys, any kind help is appreciated.
First, there didn't change something since Xcode 3 except the interface.
Try to set a breakpoint and look where you app is crashing...
Try to delete the IBOutlets and create it new...
Try to create a new app...
If all not works, take your Mac and throw it outside a window, bring it back to Apple. (or install Xcode again --> much cheaper..)
I had the exact same problem and spent AGES looking for the solution. I found out how to make it work and I've made a tutorial on how to make the Hello, Name application on XCode. Take a look and see if it helps. I think if you follow the steps one by one you should have your app running in no time.
http://techtalktone.wordpress.com/2011/11/26/hello-world/
Hope this helps ;)
I have an App Delegate and a 3 view controllers in my project. I have a variable(a NSMutable Array) in my App Delegate which I want to access from my view controllers. So I decided to create a pointer to my App Delegate and access the variables.
Here is my code:
iSolveMathAppDelegate.h
#import <UIKit/UIKit.h>
#interface iSolveMathAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
NSMutableArray *tmpArray;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) NSMutableArray *tmpArray; // variable I want to access
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
iSolveMathAppDelegate.m
#import "iSolveMathAppDelegate.h"
#implementation iSolveMathAppDelegate
#synthesize window;
#synthesize tabBarController;
#synthesize tmpArray;
...
- (void)dealloc {
[tabBarController release];
[window release];
[tmpArray release];
[super dealloc];
}
#end
The view controller class from which I want to access the tmpArray.
referenceViewController.h
#import <UIKit/UIKit.h>
#class iSolveMathAppDelegate;
#interface referenceViewController : UITableViewController {
NSMutableArray *equationTypes;
iSolveMathAppDelegate *data;
}
#property(nonatomic, retain) NSMutableArray *equationTypes;
#property(nonatomic, retain) iSolveMathAppDelegate *data;
#end
And finally referenceViewController.m
#import "referenceViewController.h"
#implementation referenceViewController
#synthesize equationTypes, data;
data = (iSolveMathAppDelegate *)[[UIApplication sharedApplication] delegate];
//says that initializer element is not constant...ERROR!
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"equationTemplates"ofType:#"plist"];
data.tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.equationTypes = data.tmpArray;
[data.tmpArray release]; // obviously none of these work, as data is not set.
}
- (void)dealloc {
[super dealloc];
[equationTypes release];
[data release];
}
#end
So anyway at the line data = (iSolveMathAppDelegate *)[[UIApplication sharedApplication] delegate]; the compiler says that the initializer element is not constant.
I have scrouged the web for answers, and for all it seems to work...but no dice for me :( Can you please advice me on where I have gone wrong? I am using XCode 3.2 and iOS SDK 3....maybe the SDK is the problem.
Thank You
That line of code isn't in a method or function, so the compiler is treating it as the definition of a compile-time constant or static/global variable. Those need constant values for initialization.
You should put the assignment of data within a method. A good place would be -viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
data = (iSolveMathAppDelegate *)[[UIApplication sharedApplication] delegate];
...
}
I figured out the struct and union problem. All I had to do was change #class iSolveAppDelegate to #import "iSolveAppDelegate.h" in my referenceViewController.h file. Thanks Jonathan for your help!
I have three view controllers, one root controller, one login view controller and one customers view controller. I want to pass the entered username and password in login view controller to the customers view controller. My files and code is displayed below, could you please guide me, how can access to variables set in the login view controller? Or how can I pass variables to customers view controller?
I have these class files:
/classes/MySoftwareAppDelegate.h
/classes/MySoftwareAppDelegate.m
/classes/ViewController.h
/classes/ViewController.m
/classes/LoginController.h
/classes/LoginController.m
/classes/CustomersController.h
/classes/CustomersController.m
I have these views:
/resources/MainWindow.xib
/resources/Login.xib
/resources/Customers.xib
In the AppDelegate, I have successfully inserted the sub view "Login" and it's displayed whenever the app starts.
In the login view, I enter my username and password and then click the "Login" button. When this button is clicked, an IBAction is triggered. In this IBAction, I want to change the current subview with the Customers.
Here's the code I have used:
MySoftwareAppDelegate.h
#import <UIKit/UIKit.h>
#class ViewController;
#interface MySoftwareAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet ViewController *viewController;
#end
MySoftwareAppDelegate.m
#import "MySoftwareAppDelegate.h"
#import "ViewController.h"
#implementation MySoftwareAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#class LoginController;
#interface ViewController : UIViewController {
LoginController *loginController;
}
#property (nonatomic, retain) LoginController *loginController;
#end
ViewController.m
#import "ViewController.h"
#import "LoginController.h"
#implementation ViewController
#synthesize loginController;
- (void)viewDidLoad {
LoginController *tmpViewController = [[LoginController alloc] initWithNibName:#"Login" bundle:nil];
self.loginController = tmpViewController;
[self.view insertSubview:loginController.view atIndex:0];
[tmpViewController release];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
if (self.loginController.view.superview == nil) {
self.loginController = nil;
}
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[loginController release];
[super dealloc];
}
#end
LoginController.h
#import <UIKit/UIKit.h>
#class CustomersController;
#interface LoginController : UIViewController {
UIButton *loginButton;
UITextField *usernameTextField;
UITextField *passwordTextField;
NSMutableString *available_credits;
NSString *current_xml_element;
CustomersController *customersController;
}
#property (nonatomic, retain) IBOutlet UIButton *loginButton;
#property (nonatomic, retain) IBOutlet UITextField *usernameTextField;
#property (nonatomic, retain) IBOutlet UITextField *passwordTextField;
#property (nonatomic, retain) NSMutableString *available_credits;
#property (nonatomic, retain) NSString *current_xml_element;
#property (nonatomic, retain) CustomersController *customersController;
-(IBAction)textFieldDoneEditing:(id)sender;
-(IBAction)backgroundTap:(id)sender;
-(IBAction)loginToAccount:(id)sender;
#end
LoginController.m
#import "LoginController.h"
#import "CustomersController.h"
#implementation LoginController
#synthesize loginButton;
#synthesize usernameTextField;
#synthesize passwordTextField;
#synthesize customersController;
- (void)viewDidLoad {
UIImage *buttonImageNormal = [UIImage imageNamed:#"whiteButton.png"];
UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
UIImage *buttonImagePressed = [UIImage imageNamed:#"blueButton.png"];
UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[loginButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
[loginButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[usernameTextField release];
[passwordTextField release];
[super dealloc];
}
-(IBAction)textFieldDoneEditing:(id)sender {
[sender resignFirstResponder];
}
-(IBAction)backgroundTap:(id)sender {
[usernameTextField resignFirstResponder];
[passwordTextField resignFirstResponder];
}
-(IBAction)loginToAccount:(id)sender {
// bla bla bla... Login check process is done here
CustomersController *tmpViewController = [[CustomersController alloc] initWithNibName:#"Customers" bundle:nil];
self.customersController = tmpViewController;
[self presentModalViewController:tmpViewController animated:YES];
[self.view removeFromSuperview];
[tmpViewController release];
}
#end
As you can see above, in LoginController.m's loginToAccount method, I am checking the login info and then setting the new view controller for the "customers" sub-view.
Then I am removing the current "Login" subview from the super view but don't know how to add the new "Customers" sub view.
In MainWindow.xib, I have one view controller which is linked to ViewController class and it's the root contoller.
Any help is appreciated. Because I am new to Objective-C and iPhone programming, please do your best to explain considering a novice programmer :)
Thanks again.
Okay, let me answer my question. I just found the answer on StackOverFlow.com
In the view controller which is going to load the next view controller, just add these lines:
NextController *tmpViewController = [[NextController alloc] initWithNibName:#"NextView" bundle:nil];
tmpViewController.enteredUsername = usernameTextField.text;
tmpViewController.enteredPassword = passwordTextField.text;
I'd say that better way is to have separate class for storing globally needed data (and that would be compliant with MVC model).
For example you can store you login information in your MySoftwareAppDelegate, which is easily accessible with [[UIApplication sharedApplication] delegate] call from any part of your application.
It all depends on how serious the data you want to pass it. For a quick variable (maybe a settings change in a modal view controller) TamTam's solution makes the most sense. You alloc/init'ed it, you got the variable, why not access it properties? That same (modally presented) view controller might pass variables back via a delegate pattern.
If you're data needs to be system wide, you can use the singleton pattern. Using "[[UIApplication sharedApplication] delegate]" gets the application delegation (which is a singleton), and many people stuff their variables there for convenience. However, your app delegate wasn't designed for this, and so it's considered bad form. Create your own singleton if your apple isn't a quickie.
If you use a persistent data store like sql, plists or coredata, you can put your system wide data there.