applicationWillEnterForeground + reload

Discussion in 'iOS Programming' started by Dwain87, Jan 25, 2011.

  1. macrumors newbie

    Joined:
    Jan 25, 2011
    #1
    Hello,

    My app uses 5 arrays and a webview content.
    I would like to reload these contents as soon as the app is called from the background.
    I'm still using a refresh button, it reloads all the information i need.
    But now i want to let the app reload all information automatically.
    I suppose, that i have to set up the "applicationwillenterforeground" method, but i don't really know how to do it.

    These are my classes:

    Code:
    testAppDelegate.h
    #import 
    
    
    @class testViewController;
    
    
    @interface testAppDelegate : NSObject {
    UIWindow *window;
    testViewController *viewController;
    
    
    }
    
    
    @property (nonatomic, retain) IBOutlet UIWindow *window;
    @property (nonatomic, retain) IBOutlet testViewController *viewController;
    
    
    @end
    

    Code:
    testAppDelegate.m
    #import "testAppDelegate.h"
    #import "testViewController.h"
    
    
    @implementation testAppDelegate
    
    
    @synthesize window;
    @synthesize viewController;
    
    
    
    
    #pragma mark -
    #pragma mark Application lifecycle
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    
    // Override point for customization after application launch.
    
    
    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];
    
    
    return YES;
    }
    
    
    
    
    - (void)applicationWillResignActive:(UIApplication *)application {
    /*
    Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    */
    }
    
    
    
    
    - (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
    Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
    */
    }
    
    
    
    
    - (void)applicationWillEnterForeground:(UIApplication *)application {
    /*
    Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
    */
    }
    
    
    
    
    - (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
    Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    */
    }
    
    
    
    
    - (void)applicationWillTerminate:(UIApplication *)application {
    /*
    Called when the application is about to terminate.
    See also applicationDidEnterBackground:.
    */
    }
    
    
    
    
    #pragma mark -
    #pragma mark Memory management
    
    
    - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
    Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
    */
    }
    
    
    
    
    - (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
    }
    
    
    
    
    @end
    Code:
    testViewController.h
    #import 
    
    
    @interface testViewController : UIViewController {
    IBOutlet UIWebView *webView;
    IBOutlet UITextField *addressBar;
    IBOutlet UIActivityIndicatorView *activityIndicator;
    IBOutlet UILabel *myField2;
    IBOutlet UILabel *myField3;
    IBOutlet UILabel *myField4;
    IBOutlet UILabel *myField5;
    IBOutlet UILabel *myField6;
    
    
    
    
    
    
    }
    
    
    @property(nonatomic,retain) UIWebView *webView;
    @property(nonatomic,retain) UITextField *addressBar;
    @property(nonatomic,retain) UIActivityIndicatorView *activityIndicator;
    
    
    -(IBAction) gotoAddress:(id)sender;
    -(IBAction) goBack:(id)sender;
    -(IBAction) goForward:(id)sender;
    -(IBAction) goxxx:(id)sender;
    -(IBAction) goxxxx:(id)sender;
    -(IBAction) refresh:(id)sender;
    
    
    @end
    

    Code:
    testViewController.m#import "testViewController.h"
    
    
    @implementation testViewController
    
    
    @synthesize webView, addressBar, activityIndicator;
    
    
    /*
    // The designated initializer. Override to perform setup that is required before the view is loaded.
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    // Custom initialization
    }
    return self;
    }
    */
    
    
    - (void)viewDidLoad {
    [super viewDidLoad];
    NSString *urlAddress = @"http://www.xxxx.de/iphone.html";
    
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"hgb-iphone2-1.gif"]];
    [webView loadRequest:requestObj];
    [addressBar setText:urlAddress];
    
    NSString *siteString = @"http://www.xxxx.de/test.txt";	
    NSURL *siteURL	= [NSURL URLWithString:siteString];
    myField2.text = [NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil];	
    NSArray *myArray = [[NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString: @":"];
    [myField2 setText: [myArray objectAtIndex: 0]];
    [myField3 setText: [myArray objectAtIndex: 1]];	
    [myField4 setText: [myArray objectAtIndex: 2]];
    [myField5 setText: [myArray objectAtIndex: 3]];
    [myField6 setText: [myArray objectAtIndex: 4]];
    
    
    
    
    
    
    }
    
    
    - (void)applicationWillEnterForeground:(UIApplication *)viewDidLoad {
    }
    
    
    
    
    
    
    -(IBAction)gotoAddress:(id) sender {
    NSURL *url = [NSURL URLWithString:[addressBar text]];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    
    //Load the request in the UIWebView.
    [webView loadRequest:requestObj];
    [addressBar resignFirstResponder];
    }
    
    
    -(IBAction)goxxx:(id) sender {
    NSString *urlAddress = @"http://www.xxx.de/iphone.html";
    
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [webView loadRequest:requestObj];
    [addressBar resignFirstResponder];
    
    }
    
    
    -(IBAction)goxxxx:(id) sender {
    NSString *urlAddress = @"http://www.xxxx.de/iphone.html";
    
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [webView loadRequest:requestObj];
    [addressBar resignFirstResponder];
    }
    -(IBAction)refresh:(id) sender {
    
    NSString *urlAddress = @"http://www.xxxx.de/iphone.html";
    
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"hgb-iphone2-1.gif"]];
    [webView loadRequest:requestObj];
    [addressBar setText:urlAddress];
    
    NSString *siteString = @"http://www.xxxxx.de/test.txt";	
    NSURL *siteURL	= [NSURL URLWithString:siteString];
    myField2.text = [NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil];	
    NSArray *myArray = [[NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString: @":"];
    [myField2 setText: [myArray objectAtIndex: 0]];
    [myField3 setText: [myArray objectAtIndex: 1]];	
    [myField4 setText: [myArray objectAtIndex: 2]];
    [myField5 setText: [myArray objectAtIndex: 3]];
    [myField6 setText: [myArray objectAtIndex: 4]];
    
    }
    -(IBAction) goBack:(id)sender {
    [webView goBack];
    }
    
    
    -(IBAction) goForward:(id)sender {
    [webView goForward];
    }
    
    
    - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
    //CAPTURE USER LINK-CLICK.
    if (navigationType == UIWebViewNavigationTypeLinkClicked) {
    NSURL *URL = [request URL];	
    if ([[URL scheme] isEqualToString:@"http"]) {
    [addressBar setText:[URL absoluteString]];
    [self gotoAddress:nil];
    }	
    return NO;
    }	
    return YES; 
    }
    
    
    - (void)webViewDidStartLoad:(UIWebView *)webView {
    [activityIndicator startAnimating];
    }
    
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
    }
    
    
    /*
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
    [super viewDidLoad];
    }
    */
    
    
    
    
    /*
    // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    */
    
    
    
    
    - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
    }
    
    
    
    
    - (void)dealloc {
    [super dealloc];
    }
    
    
    @end
    
    Can anyone help me?
     
  2. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    Yes, but you will need to use the applicationWillEnterForeground: method that resides in your app delegate and not within your view controller. Inside it, you should call your view controller's refresh: method.
     
  3. thread starter macrumors newbie

    Joined:
    Jan 25, 2011
    #3
    Hum how would that look like?

    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application {
    		NSLog(@"%@", @"WillEnterForeground called");
    		NSString *urlAddress = @"http://www.xxx.de/iphone.php";
    
    		[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlAddress]]];
    
    
    that doesn't work

    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application {
    		NSLog(@"%@", @"WillEnterForeground called");
    		NSString *urlAddress = @"http://www.txx.de/iphone.php";
    
    		[webView refresh]]];
    
    
    doesn't work either :(


    Both are in testAppDelegate.m
     
  4. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    testAppDelegate doesn't know about webView. But it does know about an instance of testViewController, for which you've publicly declared a refresh: instance method.

    P.S. The common convention is to name classes starting with upper-case, so as to not confuse them with variables, which normally start with lower-case. So, I would suggest testAppDelegate become TestAppDelegate and testViewController become TestViewController.
     
  5. Dwain87, Jan 25, 2011
    Last edited: Jan 25, 2011

    thread starter macrumors newbie

    Joined:
    Jan 25, 2011
    #5
    well tried again and it still doesn't work, okay, i tried to refresh the TestViewController like this:

    Code:
    	- (void)applicationWillEnterForeground:(UIApplication *)application {
    		
    
    		[TestViewController refresh];
    }
    
    
    Now i got a warning:


    TestViewController' may not respond to '+refresh'

    and it still doesn't work, where is the mistake?

    e:

    What do u mean by "instance of Testviewcontroller" ?
     
  6. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    Your error is caused by trying to call a refresh class method, that is not defined, on the class TestViewController.

    As for the upper-case-starting of TestViewController, perhaps I wasn't clear: you can't simply change it where you use it; you need to refactor the entire class if you want to name it TestViewController instead of the old testViewController.

    Do you know what an instance variable is, and how you define the class type for it? If you answer no to either of these questions, I'd suggest it's time to step back from the real coding and go (re)learn the fundamentals of Objective-C programming. Understanding the basics is key to learning to walk before you run.

    P.S. Please don't be careless with the case of your variable/class names. Objective-C is case-sensitive and TestViewController, testViewController, and Testviewcontroller are all different things in its eyes. Yes, you may just be putting these into a forum post and not in actual code but it can be confusing to us readers as well when you're not accurate.
     
  7. thread starter macrumors newbie

    Joined:
    Jan 25, 2011
    #7
    Yeah i know that objective-c is case sensitive like Java.
    I renamed these files before I posted them in here, but i didn't take care of it, sorry.
    But there is another problem, i still have that warning, that the TestViewController may not respond to refresh method.

    Well, but actually it does work, at least a part of it.

    I switch the application to the background.
    I call it to the foreground, but it instantly switches to the background again.
    As soon as i call it from the background again, it refreshes the content.

    But i don't really want it to switch to the background without any orders.

    Any ideas why this happens?

    Mousover shows some additional information:


    (Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments)
     
  8. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    Hmm, can we see the new code for your applicationWillEnterForeground: as well as the .h for your TestViewController class? Thanks.
     
  9. macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    It's possible for a view controller, or any object, to register to recieve the UIApplicationWillEnterForegroundNotification notification. Sometimes that makes more sense than depending on the app delegate callback.
     
  10. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    Ah, I didn't know that. Thanks!
     
  11. thread starter macrumors newbie

    Joined:
    Jan 25, 2011
    #11
    Code:
    - (void)applicationDidEnterBackground:(UIApplication *)application {
    	
    	[TestViewController refresh];
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application {
    	
    	[TestViewController refresh];
    }
    
    
    looks wierd, but it does work, but i don't know, wether apple will accept it or not.


    TestViewController.h :

    Code:
    
    #import <UIKit/UIKit.h>
    #import <iAd/iAd.h>
    
    @interface TestViewController : UIViewController<UIWebViewDelegate, ADBannerViewDelegate> {
    	IBOutlet UIWebView *webView;
    	IBOutlet UITextField *addressBar;
    	IBOutlet UIActivityIndicatorView *activityIndicator;
    	IBOutlet UILabel *myField2;
    	IBOutlet UILabel *myField3;
    	IBOutlet UILabel *myField4;
    	IBOutlet UILabel *myField5;
    	IBOutlet UILabel *myField6;
    	ADBannerView *adView;
    	BOOL bannerIsVisible;
    	IBOutlet UILabel *goImpressum;
    
    
    }
    
    
    
    @property(nonatomic,retain) UIWebView *webView;
    @property(nonatomic,retain) UITextField *addressBar;
    @property(nonatomic,retain) UIActivityIndicatorView *activityIndicator;
    @property(nonatomic,assign) BOOL bannerIsVisible;
    
    
    
    -(IBAction) gotoAddress:(id)sender;
    -(IBAction) goBack:(id)sender;
    -(IBAction) goForward:(id)sender;
    -(IBAction) goXX:(id)sender;
    -(IBAction) goXXX:(id)sender;
    -(IBAction) refresh:(id)sender;
    -(IBAction) goImpressum:(id)sender;
    
    @end
    

    I got another problem, my app recieves a string and splits the string into arrays. These arrays are used to fill several labels.
    Today I had the problem, that my string was incomplete, the server made some mistakes, actually there was no input for one part of the string.
    My app wasn't able to seperate the string any more and my app broke down for these 20 minutes.
    My code:

    Code:
    - (void)viewDidLoad {
    	self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"hgb-iphone2-1.gif"]];
    	
    	
    	
    	NSString *urlAddress = @"http://xxx.de/iphone.php";
    	
    	NSURL *url = [NSURL URLWithString:urlAddress];
    	NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    	[webView loadRequest:requestObj];
    	[addressBar setText:urlAddress];
    	
    	NSString *siteString = @"http://www.xxx.de/output/iphone.txt";	
    	NSURL *siteURL	= [NSURL URLWithString:siteString];
    	myField2.text = [NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil];	
    	NSArray *myArray = [[NSString stringWithContentsOfURL:siteURL encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString: @":  "];
    	[myField2 setText: [myArray objectAtIndex: 0]];
    	[myField3 setText: [myArray objectAtIndex: 1]];	
    	[myField4 setText: [myArray objectAtIndex: 2]];
    	[myField5 setText: [myArray objectAtIndex: 3]];
    	[myField6 setText: [myArray objectAtIndex: 4]];
    	
    	
    	
    	
    	
    	adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
    	adView.frame = CGRectOffset(adView.frame, 350, -50);
    	adView.requiredContentSizeIdentifiers = [NSSet setWithObjects:
    											 ADBannerContentSizeIdentifierPortrait,
    											 ADBannerContentSizeIdentifierLandscape,
    											 nil];
    	adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    	adView.delegate = self;
    	
    	adView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | 
    	UIViewAutoresizingFlexibleRightMargin;	[self.view addSubview:adView];
    	CGRect bannerFrame =adView.frame;
    	bannerFrame.origin.y = self.view.frame.size.height;
    	adView.frame = bannerFrame;
    	adView.delegate=self;
    	self.bannerIsVisible=NO;
    	[super viewDidLoad];
    
    
    	
    	
    }
    
    
    Is there any simple way to let my app fill these labels with some content like "unable to load" in case that the string doesn't work?
     
  12. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #12
    I would probably consider using a try-catch block.
     
  13. macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #13
    In brief: this code will cause your app to crash sometimes.

    You can't use synchronous networking on the main thread. It will time out in a time that is longer than the watchdog's kill time, sometimes.

    What you need to do is set the text field's text to some placeholder text and use asynchronous networking to get the text from the server. Once that text is available you update the UI.

    See LazyTableImages for an example.
     
  14. thread starter macrumors newbie

    Joined:
    Jan 25, 2011
    #14
    Okay, I'm going to take a look at this, thanks a lot.
    But any ideas why there still are warnings about the "applicationwillenterforeground" method?
     
  15. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #15
    If your method is still:
    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application {
    	
    	[TestViewController refresh];
    }
    
    then you are still going to get a warning. You should go back and review my post from earlier. If you want to call the refresh: instance method for TestViewController, first you must give it an object instance of TestViewController (TestViewController is a class not an object) and second, you should call the properly-named method (there's a difference between refresh and refresh:).
     

Share This Page