Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

celebi23

macrumors regular
Original poster
May 31, 2004
219
4
CT
I'm working on a simple UIWebView app for myself and a few friends. It's just a wrapper of the mobile site for Google Music. By including it in a UIWebView app, it fixes the missing background audio feature that stopped working in iOS 5. I've got it checking if there's an internet connection but, it only does that when the app is first launched (or quit and relaunched). Is there a way for Reachability to keep checking for an internet connection and show an error message every time the app is opened? I was also wondering if there was any way to reload the UIWebView when the device has been connected to the internet again? Here's my ViewController.m file.
Code:
//
//  ViewController.m
//  playmusic
//
//  Created by celebi23 on 4/16/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "ViewController.h"

#import "Reachability.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize webView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *fullURL = @"https://music.google.com"; NSURL *url = [NSURL URLWithString:fullURL]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; [webView loadRequest:requestObj];
	// Do any additional setup after loading the view, typically from a nib.
    
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
	
	NetworkStatus internetStatus = [r currentReachabilityStatus];
	
	if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
	{
		UIAlertView *myAlert = [[[UIAlertView alloc] initWithTitle:@"No Internet Connection" message:@"Play Music requires an internet connection via WiFi or cellular network to work." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] autorelease];
		[myAlert show];
        [myAlert release];
		
    }
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}

@end

Here's the source code for the entire app:
http://dl.dropbox.com/u/17689746/playmusic.zip

I've tried about 10 different ideas and none seem to really work the way that I'd like it to. Any help would be greatly appreciated. Thanks!
 

celebi23

macrumors regular
Original poster
May 31, 2004
219
4
CT

Carob

macrumors newbie
Apr 19, 2012
11
0
Thank you for the suggestion. How exactly would I do that? It's been awhile since I've coded an iOS app and I'm a little bit rusty.

1.) Download the example I linked.
2.) Copy Reachability.m and Reachability.h into your project, and import them into your appdelegate header.
3.) Like the example, add an observer into your applicationDidFinishLaunching method that will call a reachabilityChanged: method whenever the status changes
Code:
    // Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the
    // method "reachabilityChanged" will be called. 
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];
4.) Like the example, start a notifier for reaching your host. Instead of "updateInterfaceWithReachability:", call your own method (see below) for what to do when the network status changes (e.g. either reload your webview if the connection changes to up or put up an error message if is changes to down)
Code:
    //Change the host name here to change the server your monitoring
	hostReach = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
	[hostReach startNotifier];
	[self replacementForUpdateInterfaceWithReachability: hostReach];
5.) Write your replacement for updateInterfaceWithReachability:.
Code:
- (void) replacementForUpdateInterfaceWithReachability: (Reachability*) curReach{
        NetworkStatus netStatus = [curReach currentReachabilityStatus];
        if (netStatus == NotReachable){
            //put up error message
        } else {
           // reload your webview
           [webview reload];
        }
}

This is untested code only meant as an example starting point. Hope it helps.
 
Last edited:

celebi23

macrumors regular
Original poster
May 31, 2004
219
4
CT
Thank you for your help. I'm getting a bunch of errors in the AppDelegate.m file.
QV6FH.png


Here's the AppDelegate.h file
Code:
//
//  AppDelegate.h
//  playmusic
//
//  Created by celebi23 on 4/16/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;

@property (strong, nonatomic) UIWebView *webView;

@end

and my AppDelegate.m file
Code:
//
//  AppDelegate.m
//  playmusic
//
//  Created by celebi23 on 4/16/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "AppDelegate.h"

#import "ViewController.h"

#import "Reachability.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;

@synthesize WebView = webView;

- (void)dealloc
{
    [_window release];
    [_viewController release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease];
    } else {
        self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
    
    // Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the
    // method "reachabilityChanged" will be called. 
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];
    

    //Change the host name here to change the server your monitoring
	hostReach = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
	[hostReach startNotifier];
	[self replacementForUpdateInterfaceWithReachability: hostReach];
}

- (void) replacementForUpdateInterfaceWithReachability: (Reachability*) curReach{
    NetworkStatus netStatus = [curReach currentReachabilityStatus];
    if (netStatus == NotReachable){
        //put up error message
    } else {
        // reload your webview
        [webView reload];
    }
}

- (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, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the 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. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

And here's the newest version of the source code:
http://dl.dropbox.com/u/17689746/playmusic.zip

I feel like I'm missing something kinda small/easy but, I can't put my finger on it. Thanks again for your help!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.