I have a UISplitViewController which implements a masterNavigationController and a detailNavigationController, basic from the XCode template.
The masterNavigationController calls an other NSObject called "API" which in its turn uses ASIHTTPRequest to retrieve certain JSON data from an server.
Everything is fine and dandy, until I the call from the request starts. It shows the GUI of iPad and crashes straight after with an EXC_BAD_ACCESS. The error message I get is the following:
2012-10-10 21:13:42.357 myapp[24409:c07] Splitview controller
is expected to have a view
controller at index 0 before it's used!
I have tried different things to try to solve the issue, one of them being setting the SplitViewController delegate after settings the view controllers, an other is using the NetworkQueue instead.
This is the code of the masterNavigationController:
[...]
- (void)viewDidLoad
{
[UIHelper setNavigationBackBackground:self.navigationController.navigationBar widePage:NO];
[UIHelper setViewBackground:self.parentViewController.view widePage:NO];
[UIHelper setTableViewStyle:self.tableView];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
API *api = [[API alloc] init];
[api setDelegate:self];
[api setDidFinishSelector:#selector(didFinish:)];
[api getCommingRetrievals];
}
[...]
The AppDelegate:
[...]
MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.view.opaque = NO;
self.splitViewController.view.backgroundColor = [UIColor clearColor];
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
masterViewController.managedObjectContext = self.managedObjectContext;
self.splitViewController.delegate = detailViewController;
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
[...]
This is the API object's code:
- (void)getCommingRetrievals
{
[self getRetrievalsForDate:[NSDate date]];
}
- (void)getRetrievalsForDate:(NSDate*)date
{
NSString *stringFromDate = #"";
if (date != nil)
{
// Set date string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyyMMdd"];
stringFromDate = [formatter stringFromDate:date];
}
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/bookings/%#", API_BASE_DOMAIN, stringFromDate]];
[self callApi:url requestMethod:#"GET"];
}
#pragma mark -
#pragma mark API methods
- (void)callApi:(NSURL*)url requestMethod:(NSString*)requestMethod
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:requestMethod];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestFinished:)];
[request setDidFailSelector:#selector(didFailWithError:)];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
if (self.delegate && [self.delegate respondsToSelector:didFinishSelector]) {
[self.delegate performSelector:didFinishSelector withObject:self];
}
}
If I comment out the line [request startAsynchronous];, the app doesn't crash.
What am I missing here, and how can I solve the problem?
Check that your UISplitViewController has been passed 2 view controllers.
Other than that, some idiomatic stuff:
This should go right at the beginning of any setting up stuff:
[super viewDidLoad];
e.g. `[super viewDidLoad]` convention
And consider using another framework than ASI. It's a dead library. AFNetworking, MKNetworkingKit or RESTKit are good alternatives.
Related
I am creating an app where the user can share different forms. What is weird is when I test the app on a iPhone, the Activity View controller works fine
But when I do the exact same thing on the ipad, but in a different storyboard. It does this:
Here is the code from which both of these views are getting their actions:
#import "FluteS.h"
#import "TUSafariActivity.h"
#import "ARChromeActivity.h"
#interface FluteS ()
#end
#implementation FluteS
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(IBAction)actionButton:(id)sender;{
NSLog(#"actionButton pressed");
NSBundle *bundle=[NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:#"Flute" ofType: #"pdf"];
NSURL *fileURL= [NSURL URLWithString:#"http://www.friendswoodmustangband.org/wp-content/uploads/2012/04/Flute-Audition-Scales1.pdf"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSArray *activityItems = #[fileUrl, fileURL];
ARChromeActivity *chromeActivity = [[ARChromeActivity alloc] init];
TUSafariActivity *TUSafari = [[TUSafariActivity alloc] init];
NSArray *applicationActivities = [NSArray arrayWithObjects:TUSafari,chromeActivity, nil];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities: applicationActivities];
activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
activityVC.excludedActivityTypes = #[UIActivityTypeAssignToContact, UIActivityTypePostToWeibo];
[self presentViewController:activityVC animated:YES completion:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSBundle *bundle=[NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:#"Flute" ofType: #"pdf"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:fileUrl];
[_webView loadRequest:request];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I have already checked the localized part of the Info.plist, but I can't Figure out why it works on the iPhone, but not on the iPad. Does anybody have any idea what is happening?
When presenting the view controller, you must do so using the appropriate means for the current device. On iPad, you must present the view controller in a popover. On iPhone and iPod touch, you must present it modally.
You can use the following code for iPad.
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[#"something"] applicationActivities:nil];
self.popover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
self.popover.delegate = self;
[self.popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Hope it helps you.
I am using a Window based application and then loading up my initial navigationview based controller in the appDelegate part - application didFinishLaunchingwithOptions (UPDATED)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
The method of getting the data from the webservice is usually triggered in this method of viewdidload .... in the [self getData]; method.
- (void)viewDidLoad
{
[super viewDidLoad];
if (_refreshHeaderView == nil) {
EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];
}
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
[self loadImages];
HUDMB = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUDMB];
HUDMB.dimBackground = YES;
// Regiser for HUD callbacks so we can remove it from the window at the right time
HUDMB.delegate = self;
HUDMB.labelText = #"Loading..";
[HUDMB show:TRUE];
[self getData];
[self.tableView reloadData];
}
Before loading it if the user is not registered/ does not have a credentials present then it takes the user to a login view controller .
- (void)loadView {
[super loadView];
if([Preferences isValid]?YES:NO)
{
}
else
{
int r = arc4random() % 5;
switch (r) {
case 0:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 1:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 2:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 4:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 3:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
default:
break;
}
}
}
I think the getdata function is making a lot of troubles. so let me add that and also the corresponding functions i use for data retrieval and serialization.
-(void)getData{
NSLog(#"loggin into call sheet page");
[self getCallSheetData];
NSLog(#"after call sheet");
}
- (void)getCallSheetData
{
NSString *postCMD = #"Blah... Blah... Blah...";
NSMutableData *postDataCMD = (NSMutableData *)[postCMD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSURL *url = [NSURL URLWithString:[Preferences getURL]];
// NSLog(#"get call Sheet");
NSString *postLengthCMD = [NSString stringWithFormat:#"%d", [postDataCMD length]+1];
// NSLog(#"The CS String: %#",[Preferences retriveSession]);
requestCMD = [ASIHTTPRequest requestWithURL:url];
[requestCMD setURL:url];
[requestCMD addRequestHeader:#"Content-Length" value:postLengthCMD];
[requestCMD addRequestHeader:#"Content-Type" value:#"application/x-www-form-urlencoded"];
[requestCMD addRequestHeader:#"user-Agent" value:#"Mobile 1.4" ];
[requestCMD addRequestHeader:#"Content-Language" value:#"en-US"];
[requestCMD addRequestHeader:#"Accept-Encoding" value:#"gzip"];
[requestCMD addRequestHeader:#"Cookie" value:[Preferences retriveSession]];
[requestCMD setPostBody:postDataCMD];
[requestCMD setDelegate:self];
[requestCMD startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSMutableArray *CSArray = [[NSMutableArray alloc] init];
if( [[request responseString] isEqualToString:#"OK"]){
return;
}
// Use when fetching binary data
NSData *responseData = [request responseData];
NSDateFormatter *formatter1=[[NSDateFormatter alloc]init];
[formatter1 setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[formatter1 setTimeZone:gmt];
NSDateFormatter *formatterFinal=[[NSDateFormatter alloc]init];
[formatterFinal setDateStyle:NSDateFormatterMediumStyle];
[formatterFinal setTimeStyle: NSDateFormatterShortStyle];
[formatterFinal setLocale:[NSLocale currentLocale]];
JSONDecoder *jCSArray = [[JSONDecoder alloc]init];
NSMutableArray *theObject = [jCSArray objectWithData:responseData];
// CallSheet= [NSMutableArray arrayWithCapacity:50];
for(id key in theObject)
{
csr = [[CallSheetRecord alloc] init];
// cName,cCompany,cId,cMemberId,crcStatus,crcTarget,cImportance,cLastContact
csr.importance = #"1";
csr.rcstatus = #"1";
csr.rcTarget = #"1";
csr.company = #"";
csr.lastContact= #"";
if([key valueForKey:#"firstName"] != Nil)
{
csr.name = [NSString stringWithFormat:#"%#",[key valueForKey:#"firstName"]] ;
if ([key valueForKey:#"lastName"] != Nil) {
csr.name = [csr.name stringByAppendingString:#" "];
csr.name = [csr.name stringByAppendingString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastName"]]];
}
}
if([key valueForKey:#"company"] != Nil)
{
csr.company = [NSString stringWithFormat:#"%#",[key valueForKey:#"company"]] ;
}
if([key valueForKey:#"memberId"] != Nil)
{
csr.memberId = [NSString stringWithFormat:#"%#",[key valueForKey:#"memberId"]] ;
}
if([key valueForKey:#"id"] != Nil)
{
csr.id_ = [NSString stringWithFormat:#"%#",[key valueForKey:#"id"]] ;
}
if([key valueForKey:#"lastContact"] != Nil)
{
NSDate *finalDate =[formatter1 dateFromString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastContact"]]];
//NSString *timeStamp = [formatter1 stringFromDate:[finalDate descriptionWithLocale:[NSLocale currentLocale]]];
//NSLog(#"Time stamp : %#",[finalDate descriptionWithLocale:[NSLocale currentLocale]]);
//NSLog(#"Time stamp : %#",timeStamp);
//csr.lastContact = [key valueForKey:#"lastContact"];
csr.lastContact = [formatterFinal stringFromDate:finalDate];
}
if([key valueForKey:#"importance"] != Nil)
{
csr.importance = [NSString stringWithFormat:#"%#",[key valueForKey:#"importance"]];
}
if([key valueForKey:#"rcStatus"] != Nil)
{
csr.rcstatus= [NSString stringWithFormat:#"%#",[key valueForKey:#"rcStatus"]] ;
}
if([key valueForKey:#"rcTarget"] != Nil)
{
csr.rcTarget = [NSString stringWithFormat:#"%#",[key valueForKey:#"rcTarget"]] ;
}
[CSArray addObject:csr];
}
CSD = [CSArray mutableCopy];
[CSArray release];
[formatter1 release];
[formatterFinal release];
//CallSheetArray = [CSArray mutableCopy];
//[csr release];
[jCSArray release];
[HUDMB hide:TRUE];
[self.tableView reloadData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
UIAlertView *message = [[[UIAlertView alloc] initWithTitle:#"Hello World!"
message:[NSString stringWithFormat:#"%#",error]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]autorelease];
[message show];
}
then right after that i try to load the table with [self getData]; that i get make using webservice call using asiHTTP .. for this question lets say it takes 3 seconds time to get the data and then deserialize it . now... my question is it works out okey in the later runs as I store the username and password in a seure location... but in the first instance.... i am not able to get the data to laod to the tableview... I have tried a lot of things...
1. Initially the data fetch methods was in a diffrent methods.. so i thought that might be the problem as then moved it the same place as the tbleviewController(navigationController)
2. I event put in the Reload data at the end of the functionality for the data parsing and deserialization... nothing happens.
3. The screen is black screen with nothing displayed on it for a good 5 seconds in the consecutive launches of the app.... so could we have something like a MBPorgressHUD implemented for the same.
could any one please help for these scenarios and guidance as to what paths to take from here. ...
Update:
Bounty Just answer 2 of the questions the best you can... The property was a thing i tried but it did not work... but my problem is not that... my problem is my screen is not able to load data from a webservice after i login until i do the "pull to refresh". Next eventualy starting my app takes about 5 seconds to show the screen(till that it shows a black screen)... what is the best way to show the apps Blank screen to the End- user when they make it to the app. I dont want the user to think the app is not working or has adversly affected their phone.
There are a number of potential issues here. The first is related to [self getData] - is this blocking or not?
1. getData is blocking (synchronous)
If this method is blocking (i.e. does not return immediately) then this will explain why you are not seeing anything on the screen for a few seconds. You are currently calling this method in the main thread, so it will stop the UI from being updated until is complete.
You can make it run in the background by doing this:
- (void) getDataInBackgroundThread
{
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
[self getData];
// force the table to redraw - UI operations must be on the main thread
[tableView performSelectorOnMainThread:#selector( reloadData )];
[pool drain];
}
In your main code, now instead of calling [self getData] call [self getDataInBackgroundThread];
2. getData is not blocking (asynchronous)
Even if getData is blocking, if it runs in the main thread it will still cause the UI to hang. Also, if it uses a lot of processor time it will slow down the UI and give the appearance of not running in the background.
To address this issue, you would need make sure the lengthy operation of getData really is not running in the main thread and also put in sleep() calls every so often to give some time for the UI to update.
You still haven't given enough info for people to really help, we're just guessing.
It is highly likely the delay is caused by getData. Try commenting that out or bracket it with NSLog statements to verify.
You should show us more code, specifically what is happening in getData and any delegate or notification handling implementations related to loading data.
You don't need to explicitly call [tableView reloadData] in viewDidLoad. The tableView automatically loads data the first time it is displayed.
As #dmatt said, if you are loading data asynchronously then getData would return immediately with no delay. You would typically would either respond to delegate messages or notifications (depending on how you are loading data) to reload the table when the data is finished loading and serializing.
There are lots of folks on SO who are happy to try and help you if given enough info. Especially when you offer a bounty.
Basically I want to make a login screen in my iPhone app before I show my TabBarController. I tried the following approach, adding first to the window subview my TabBarController and on top my LoginViewController. What am I doing wrong or should I do it completely different?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
NSMutableArray *tabItems = [[NSMutableArray alloc] initWithCapacity:2];
DefaultViewController *dvc = [[DefaultViewController alloc] init];
UINavigationController *dvc_nc = [[UINavigationController alloc] initWithRootViewController:dvc];
dvc_nc.tabBarItem.title = #"Home";
//dvc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Default" ofType:#"png"]];
[tabItems addObject:dvc_nc];
[dvc release];
[dvc_nc release];
OptionsViewController *ovc = [[OptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *ovc_nc = [[UINavigationController alloc] initWithRootViewController:ovc];
ovc_nc.tabBarItem.title = #"Option";
//ovc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Option" ofType:#"png"]];
[tabItems addObject:ovc_nc];
[ovc release];
[ovc_nc release];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = tabItems;
self.tabController = tbc;
[tabItems release];
[tbc release];
[self.window addSubview:self.tabController.view];
LoginViewController *lvc = [[OptionsViewController alloc] init];
UINavigationController *lvc_nc = [[UINavigationController alloc] initWithRootViewController:lvc];
[self.window addSubview:lvc_nc.view];
[lvc release];
[lvc_nc release];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
NSMutableArray *tabItems = [[NSMutableArray alloc] initWithCapacity:2];
DefaultViewController *dvc = [[DefaultViewController alloc] init];
UINavigationController *dvc_nc = [[UINavigationController alloc] initWithRootViewController:dvc];
dvc_nc.tabBarItem.title = #"Home";
//dvc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Default" ofType:#"png"]];
[tabItems addObject:dvc_nc];
[dvc release];
[dvc_nc release];
OptionsViewController *ovc = [[OptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *ovc_nc = [[UINavigationController alloc] initWithRootViewController:ovc];
ovc_nc.tabBarItem.title = #"Option";
//ovc_nc.tabBarItem.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Option" ofType:#"png"]];
[tabItems addObject:ovc_nc];
[ovc release];
[ovc_nc release];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = tabItems;
self.tabController = tbc;
[tabItems release];
[tbc release];
[self.window addSubview:self.tabController.view];
LoginViewController *lvc = [[OptionsViewController alloc] init];
UINavigationController *lvc_nc = [[UINavigationController alloc] initWithRootViewController:lvc];
[self.tabController presentModalViewController:lvc_nc animated:no];
[lvc release];
[lvc_nc release];
return YES;
}
I would use two different views. One will handle the login proccess and one is your "Logged in view" that provides the features of your app. When your app starts up, you add the login view, check username/password and when the login went fine you switch to your second view.
I am fetching XML data from server i want that when data is loading in progress i show a loading bar with default screen this is code in appDidFinishing
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
RootViewController * rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self.window addSubview:navigationController.view];
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(55, 67, 100, 100)];
[self.activityIndicator startAnimating];
[self.window addSubview:self.activityIndicator];
[self loadXMlTwo];
[self loadXMlMain];
[self performSelectorInBackground:#selector(loadXMlOne) withObject:nil];
[self.activityIndicator removeFromSuperview];
[window makeKeyAndVisible];
return YES;
}
-(void)loadXMlMain{
NSURL*url= [[NSURL alloc]initWithString:#"http://46.137.28.14/app/ipadApplic/working.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
-(void)loadXMlOne{
NSURL*url1=[[NSURL alloc] initWithString:#"http://46.137.28.14/app/ipadApplic/rowone.xml"];
NSXMLParser *xmlParserRow = [[NSXMLParser alloc] initWithContentsOfURL:url1];
//Initialize the delegate.
RowOneParser *parser1 = [[RowOneParser alloc] initXMLParser];
//Set delegate
[xmlParserRow setDelegate:parser1];
BOOL success1 = [xmlParserRow parse];
if(success1)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
-(void)loadXMlTwo{
NSURL*urlRowTwo=[[NSURL alloc] initWithString:#"http://46.137.28.14/app/ipadApplic/rowtwo.xml"];
NSXMLParser *xmlParserRowTwo = [[NSXMLParser alloc] initWithContentsOfURL:urlRowTwo];
//Initialize the delegate.
RowTwoParser *parserRowTwo = [[RowTwoParser alloc] initXMLParser];
//Set delegate
[xmlParserRowTwo setDelegate:parserRowTwo];
BOOL successRow = [xmlParserRowTwo parse];
if(successRow)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
What you need to do is unblock your main thread while you are doing background fetch of xml data. Easiest way to do that is add your fetch operations in NSOperationQueue. Set up delegates for the class which fetches the xml and handle the response.
So what I'm trying to do is when you click view on receiving a push notification when the app opens it has the presented view push a new controller with details regarding the notification. I'm using a UITabBarController with UINavigationControllers. Any help would be much appreciated, I've tried searching but I couldn't seem to find anything that pointed me in the right direction. Current code below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
tabBarController = [[UITabBarController alloc] init];
controller = [[controller alloc] init];
UINavigationController *controller1 = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
controller1.tabBarItem.image = [UIImage imageNamed:#"icon_news.png"];
[controller setTitle:#"View"];
[controller release];
controller = [[controller alloc] init];
UINavigationController *controller2 = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
controller2.tabBarItem.image = [UIImage imageNamed:#"icon_news.png"];
[controller setTitle:#"View"];
[controller release];
controller = [[controller alloc] init];
UINavigationController *controller3 = [[[UINavigationController alloc] initWithRootViewController:controller3] autorelease];
controller3.tabBarItem.image = [UIImage imageNamed:#"icon_news.png"];
[controller setTitle:#"View"];
[controller release];
controller = [[controller alloc] init];
UINavigationController *controller4 = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
controller4.tabBarItem.image = [UIImage imageNamed:#"icon_news.png"];
[controller setTitle:#"View"];
[controller release];
controller = [[controller alloc] init];
UINavigationController *controller5 = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
controller5.tabBarItem.image = [UIImage imageNamed:#"icon_news.png"];
[controller setTitle:#"View"];
[controller release];
tabBarController.viewControllers = [NSArray arrayWithObjects:controller1, controller2, controller3, controller4, controller5, nil];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
launchDefault = YES;
//[self performSelector:#selector(handlePostLaunch) withObject:nil afterDelay:0];
// Push Notification info
NSDictionary *apns = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSString *result = [[[apns valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"loc-args"];
NSString *playerID = [NSString stringWithFormat:#"%#", result];
playerID = [[playerID componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:#""];
playerID = [playerID stringByReplacingOccurrencesOfString:#" " withString:#""];
playerID = [playerID stringByReplacingOccurrencesOfString:#"(" withString:#""];
playerID = [playerID stringByReplacingOccurrencesOfString:#")" withString:#""];
NSLog(#"Player ID: %#", playerID);
if (![playerID isEqualToString:#"null"]) {
if (!detailViewController) {
detailViewController = [[PlayerDetailViewController alloc] init];
}
NSManagedObjectContext *moc = [[AppController sharedAppController] managedObjectContext];
NSFetchRequest *req = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Players"
inManagedObjectContext:moc];
[req setEntity:entity];
NSPredicate *pre = [NSPredicate predicateWithFormat:#"playerID=%#", playerID];
[req setPredicate:pre];
NSError *error;
NSArray *list = [moc executeFetchRequest:req error:&error];
[req release];
Players *player = [list lastObject];
[detailViewController setPlayer:player];
//Want to Push view here
[detailViewController release];
detailViewController = nil;
}
return YES;
}
If application is launched by a notification then it will be present in the application delegate's application:didFinishLaunchingWithOptions: launchOptions dictionary under the key UIApplicationLaunchOptionsRemoteNotificationKey, which has all the info the notification has (JSON converted to NSDictionary I believe).
EDIT:
Got the question wrong, I think what you're looking for is just the pointer to the currently selected navigation controller. You get that if you query [tabbarcontroller selectedViewController], which returns the visible navigation controller. Then simply push the newly created controller on top of the stack of that navigation controller.