Permalink
Browse files

Add graphic for Demo button.

Show/hide demo button only when needed
  • Loading branch information...
1 parent 85176fc commit cfc6b0035d78d53f994c0cd274416ad0d245150c torin committed Dec 7, 2011
View
8 NeTV.xcodeproj/project.pbxproj
@@ -89,6 +89,8 @@
42823754147E143700BBBB27 /* btn_forward@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4282374B147E143600BBBB27 /* btn_forward@2x.png */; };
42823755147E143700BBBB27 /* btn_go@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4282374C147E143600BBBB27 /* btn_go@2x.png */; };
42823756147E143700BBBB27 /* bottombar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4282374D147E143600BBBB27 /* bottombar@2x.png */; };
+ 42823759148F1B1300BBBB27 /* btn_demo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 42823757148F1B1300BBBB27 /* btn_demo@2x.png */; };
+ 4282375A148F1B1300BBBB27 /* btn_demo.png in Resources */ = {isa = PBXBuildFile; fileRef = 42823758148F1B1300BBBB27 /* btn_demo.png */; };
42AD80481470D2F4003763F7 /* UIImage+Alpha.m in Sources */ = {isa = PBXBuildFile; fileRef = 42AD80221470D2F4003763F7 /* UIImage+Alpha.m */; };
42AD80491470D2F4003763F7 /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = 42AD80241470D2F4003763F7 /* UIImage+Resize.m */; };
42AD804A1470D2F4003763F7 /* UIImage+RoundedCorner.m in Sources */ = {isa = PBXBuildFile; fileRef = 42AD80261470D2F4003763F7 /* UIImage+RoundedCorner.m */; };
@@ -229,6 +231,8 @@
4282374B147E143600BBBB27 /* btn_forward@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_forward@2x.png"; sourceTree = "<group>"; };
4282374C147E143600BBBB27 /* btn_go@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_go@2x.png"; sourceTree = "<group>"; };
4282374D147E143600BBBB27 /* bottombar@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bottombar@2x.png"; sourceTree = "<group>"; };
+ 42823757148F1B1300BBBB27 /* btn_demo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_demo@2x.png"; sourceTree = "<group>"; };
+ 42823758148F1B1300BBBB27 /* btn_demo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = btn_demo.png; sourceTree = "<group>"; };
42AD80211470D2F4003763F7 /* UIImage+Alpha.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Alpha.h"; sourceTree = "<group>"; };
42AD80221470D2F4003763F7 /* UIImage+Alpha.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Alpha.m"; sourceTree = "<group>"; };
42AD80231470D2F4003763F7 /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Resize.h"; sourceTree = "<group>"; };
@@ -324,6 +328,8 @@
4207DC89143D9A9F00FAD4AA /* Images */ = {
isa = PBXGroup;
children = (
+ 42823757148F1B1300BBBB27 /* btn_demo@2x.png */,
+ 42823758148F1B1300BBBB27 /* btn_demo.png */,
42823745147E143600BBBB27 /* bottombar.png */,
42823746147E143600BBBB27 /* btn_backward.png */,
42823747147E143600BBBB27 /* btn_forward.png */,
@@ -622,6 +628,8 @@
42823754147E143700BBBB27 /* btn_forward@2x.png in Resources */,
42823755147E143700BBBB27 /* btn_go@2x.png in Resources */,
42823756147E143700BBBB27 /* bottombar@2x.png in Resources */,
+ 42823759148F1B1300BBBB27 /* btn_demo@2x.png in Resources */,
+ 4282375A148F1B1300BBBB27 /* btn_demo.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
BIN NeTV/Images/btn_demo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN NeTV/Images/btn_demo@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
161 NeTV/NeTVViewController.h
@@ -1,81 +1,80 @@
-/*
-
- File: NeTVViewController.h
- Abstract: This is the Splash screen UI, starting point of the app. Handles device discovery and device selection list
-
- For full documentation and source code, please visit: http://wiki.chumby.com/index.php/NeTV_developer_info
- */
-
-#import <Foundation/NSNetServices.h>
-#import "BaseController.h"
-#import "ChooseIPController.h"
-
-@interface NeTVViewController : BaseController <NSNetServiceBrowserDelegate, NSNetServiceDelegate, ChooseIPControllerDelegate>
-{
- //UI
- IBOutlet UILabel *lblVersion;
- IBOutlet UILabel *lblStatus;
- IBOutlet UILabel *lblInstruction;
- IBOutlet UIImageView *imgLogo;
- IBOutlet UIImageView *imgNavbar;
- IBOutlet UIImageView *imgLoading;
- IBOutlet UIButton *btnNavbarBack;
-
- IBOutlet UIView *viewStatusBar;
- IBOutlet UILabel *lblStatusFull;
- IBOutlet UIImageView *imgStatusBar;
- UIAlertView *alertView;
- ChooseIPController *chooseIPController;
-
- //Bonjour stuff
- NSMutableArray *_services;
- NSNetServiceBrowser *_netServiceBrowser;
- NSNetService *_currentResolve;
-
- //Flag
- int _retryCounter;
- time_t _startDiscoveryTime;
- BOOL _checkedReachability;
- BOOL _sentHandshake;
- BOOL _receiveHandshake;
- BOOL _hasMoreHandshake;
-
- //Multiple device
- NSMutableDictionary *_deviceList;
-}
-
-//UI Events
-
-
-//Helpers
-- (void)showDeviceList;
-- (void)hideDeviceList;
-- (void)clearDeviceList;
-- (void)setStatusText:(NSString*)text;
-- (void)showStatusBar:(NSString*)text;
-- (void)showStatusBarError:(NSString*)text;
-- (void)showStatusBarInfo:(NSString*)text;
-- (void)hideStatusBar;
-- (void)showLoadingIcon;
-- (void)hideLoadingIcon;
-- (BOOL)isDeviceListVisible;
-- (BOOL)isStatusBarVisible;
-- (void)showSimpleMessageDialog:(NSString*)message;
-- (void)showSimpleMessageDialog:(NSString*)message withButton:(NSString*)btnName;
-
-//Bonjour helper functions
-- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain;
-
-//Application logic
-- (void)reset;
-- (void)restartInitSequenceWithDelay:(float)second;
-- (int)numberOfDevices;
-- (void)gotoRemoteControlSingleDevice;
-- (void)gotoRemoteControl:(NSMutableDictionary*)deviceData;
-- (void)gotoRemoteControlDemo;
-- (void)initializeSequence;
-
-//Enter the Demo Mode
-- (IBAction)enterDemoMode:(id)sender;
-
-@end
+/*
+
+ File: NeTVViewController.h
+ Abstract: This is the Splash screen UI, starting point of the app. Handles device discovery and device selection list
+
+ For full documentation and source code, please visit: http://wiki.chumby.com/index.php/NeTV_developer_info
+ */
+
+#import <Foundation/NSNetServices.h>
+#import "BaseController.h"
+#import "ChooseIPController.h"
+
+@interface NeTVViewController : BaseController <NSNetServiceBrowserDelegate, NSNetServiceDelegate, ChooseIPControllerDelegate>
+{
+ //UI
+ IBOutlet UILabel *lblVersion;
+ IBOutlet UILabel *lblStatus;
+ IBOutlet UILabel *lblInstruction;
+ IBOutlet UIImageView *imgLogo;
+ IBOutlet UIImageView *imgNavbar;
+ IBOutlet UIImageView *imgLoading;
+ IBOutlet UIButton *btnNavbarBack;
+ IBOutlet UIButton *btnDemo;
+
+ IBOutlet UIView *viewStatusBar;
+ IBOutlet UILabel *lblStatusFull;
+ IBOutlet UIImageView *imgStatusBar;
+ UIAlertView *alertView;
+ ChooseIPController *chooseIPController;
+
+ //Bonjour stuff
+ NSMutableArray *_services;
+ NSNetServiceBrowser *_netServiceBrowser;
+ NSNetService *_currentResolve;
+
+ //Flag
+ int _retryCounter;
+ time_t _startDiscoveryTime;
+ BOOL _checkedReachability;
+ BOOL _sentHandshake;
+ BOOL _receiveHandshake;
+ BOOL _hasMoreHandshake;
+
+ //Multiple device
+ NSMutableDictionary *_deviceList;
+}
+
+//UI Events
+- (IBAction)enterDemoMode:(id)sender;
+
+//Helpers
+- (void)showDeviceList;
+- (void)hideDeviceList;
+- (void)clearDeviceList;
+- (void)setStatusText:(NSString*)text;
+- (void)showStatusBar:(NSString*)text;
+- (void)showStatusBarError:(NSString*)text;
+- (void)showStatusBarError:(NSString*)text showDemoBtn:(BOOL)showDemoBtn;
+- (void)showStatusBarInfo:(NSString*)text;
+- (void)hideStatusBar;
+- (void)showLoadingIcon;
+- (void)hideLoadingIcon;
+- (BOOL)isDeviceListVisible;
+- (BOOL)isStatusBarVisible;
+- (void)showSimpleMessageDialog:(NSString*)message;
+- (void)showSimpleMessageDialog:(NSString*)message withButton:(NSString*)btnName;
+
+//Bonjour helper functions
+- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain;
+
+//Application logic
+- (void)reset;
+- (void)restartInitSequenceWithDelay:(float)second;
+- (int)numberOfDevices;
+- (void)gotoRemoteControlSingleDevice;
+- (void)gotoRemoteControl:(NSMutableDictionary*)deviceData;
+- (void)gotoRemoteControlDemo;
+- (void)initializeSequence;
+
+@end
View
1,370 NeTV/NeTVViewController.m
@@ -1,677 +1,693 @@
-//
-// NeTVViewController.m
-// NeTV
-//
-
-#import "NeTVViewController.h"
-#import "RemoteController.h"
-#import <QuartzCore/QuartzCore.h>
-#import <sys/socket.h>
-#import <netinet/in.h>
-#import <arpa/inet.h>
-#import <sys/ioctl.h>
-#import <net/if.h>
-#import <netdb.h>
-
-#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)
-
-// Private extension
-@interface NeTVViewController()
-- (NSString *)addressHost4:(struct sockaddr_in *)pSockaddr4;
-- (NSString *)addressHost6:(struct sockaddr_in6 *)pSockaddr6;
-- (NSString *)addressHost:(struct sockaddr *)pSockaddr;
-@end
-
-@implementation NeTVViewController
-
-#pragma mark - Standard Initialization
-
-- (void)didReceiveMemoryWarning
-{
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
-}
-
-- (void)viewDidLoad
-{
- [super viewDidLoad];
-
- //Show app version number
- NSLog(@"Version %@", self.appVersion);
- lblVersion.text = self.appVersion;
-
- //Hide the custom navbar back button
- btnNavbarBack.alpha = 0;
-
- //Setup custom bottom bar
- CGRect statusBarRect;
- statusBarRect.origin.x = 0;
- statusBarRect.origin.y = self.view.frame.size.height;
- statusBarRect.size.width = self.view.frame.size.width;
- statusBarRect.size.height = viewStatusBar.frame.size.height;
- [self.view insertSubview:viewStatusBar aboveSubview:lblStatus];
- viewStatusBar.frame = statusBarRect;
-
- //Setup SearchResultTableView
- if (chooseIPController == nil)
- {
- CGRect chooseIPRect;
- chooseIPRect.origin.x = 0;
- chooseIPRect.origin.y = - self.view.frame.size.height;
- chooseIPRect.size.width = self.view.frame.size.width;
- chooseIPRect.size.height = self.view.frame.size.height - imgNavbar.frame.size.height;
-
- //Add to current view, hidden away
- chooseIPController = [[ChooseIPController alloc] initWithNibName:@"ChooseIPController" bundle:[NSBundle mainBundle]];
- [chooseIPController.view setFrame:chooseIPRect];
- [self.view insertSubview:chooseIPController.view belowSubview:imgNavbar];
- chooseIPController.delegate = self;
- }
-
- //Hide loading icon initially
- imgLoading.alpha = 0;
-}
-
-- (void)viewDidUnload
-{
- [super viewDidUnload];
-}
-
-- (void)viewWillAppear:(BOOL)animated
-{
- [super viewWillAppear:animated];
-
- //Bonjour stuff
- if (_services == nil)
- _services = [[NSMutableArray alloc] init];
- [self searchForServicesOfType:@"_netv._tcp." inDomain:@""];
-
- //Rescan
- [self reset];
-}
-
-- (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
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- } else {
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
- }
-}
-
-
-
-#pragma mark - UI Events
-
--(IBAction)onNavbarBack:(id)sender
-{
- [self hideDeviceList];
- [self reset];
-}
-
-
-
-#pragma mark - Helpers
-
-- (void)showDeviceList
-{
- [chooseIPController setData:_deviceList];
-
- CGRect chooseIPRect;
- chooseIPRect.origin.x = 0;
- chooseIPRect.origin.y = imgNavbar.frame.size.height;
- chooseIPRect.size.width = self.view.frame.size.width;
- chooseIPRect.size.height = self.view.frame.size.height - imgNavbar.frame.size.height;
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.6];
- lblInstruction.alpha = 0;
- lblVersion.alpha = 0;
- lblStatus.alpha = 0;
- imgLogo.alpha = 0;
- imgLoading.alpha = 0;
- [UIView commitAnimations];
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDelay:0.2];
- [UIView setAnimationDuration:0.6];
- btnNavbarBack.alpha = 1;
- chooseIPController.view.frame = chooseIPRect;
- [UIView commitAnimations];
-}
-
-- (void)hideDeviceList
-{
- CGRect chooseIPRect;
- chooseIPRect.origin.x = 0;
- chooseIPRect.origin.y = - self.view.frame.size.height;
- chooseIPRect.size.width = self.view.frame.size.width;
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.6];
- btnNavbarBack.alpha = 0;
- chooseIPController.view.frame = chooseIPRect;
- [UIView commitAnimations];
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.6];
- [UIView setAnimationDelay:0.2];
- [UIView setAnimationDidStopSelector: @selector(clearDeviceList)];
- lblInstruction.alpha = 1;
- lblVersion.alpha = 1;
- lblStatus.alpha = 1;
- imgLogo.alpha = 1;
- [UIView commitAnimations];
-}
-
-- (void)clearDeviceList
-{
- [chooseIPController clearData];
-}
-
-- (void)setStatusText:(NSString *)text
-{
- lblStatus.text = text;
- lblStatusFull.text = text;
-}
-
-- (void)showStatusBar:(NSString*)text
-{
- if (text != nil)
- [self setStatusText:text];
-
- CGRect statusBarRect;
- statusBarRect.origin.x = 0;
- statusBarRect.origin.y = self.view.frame.size.height - viewStatusBar.frame.size.height;
- statusBarRect.size.width = self.view.frame.size.width;
- statusBarRect.size.height = viewStatusBar.frame.size.height;
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.3];
- viewStatusBar.frame = statusBarRect;
- [UIView commitAnimations];
-}
-
-- (void)showStatusBarError:(NSString*)text
-{
- [imgStatusBar setImage:[UIImage imageNamed:@"bottombar_error.png"]];
- [self showStatusBar:text];
-}
-
-- (void)showStatusBarInfo:(NSString*)text
-{
- [imgStatusBar setImage:[UIImage imageNamed:@"bottombar_info.png"]];
- [self showStatusBar:text];
-}
-
-- (void)hideStatusBar
-{
- CGRect statusBarRect;
- statusBarRect.origin.x = 0;
- statusBarRect.origin.y = self.view.frame.size.height + 5;
- statusBarRect.size.width = self.view.frame.size.width;
- statusBarRect.size.height = viewStatusBar.frame.size.height;
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.3];
- viewStatusBar.frame = statusBarRect;
- [UIView commitAnimations];
-}
-
-- (void)showLoadingIcon
-{
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.7];
- [UIView setAnimationDelay:0.5];
- imgLoading.alpha = 0.5;
- [UIView commitAnimations];
-
- //Setup spining loading icon
- CATransform3D rotationTransform = CATransform3DMakeRotation(0.9999f * M_PI, 0, 0, 1.0);
- CABasicAnimation* rotationAnimation;
- rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
- rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
- rotationAnimation.duration = 1.25f;
- rotationAnimation.cumulative = YES;
- rotationAnimation.repeatCount = 999;
- [imgLoading.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
-}
-
-- (void)hideLoadingIcon
-{
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.5];
- imgLoading.alpha = 0;
- [UIView commitAnimations];
-}
-
-- (BOOL)isDeviceListVisible
-{
- return (chooseIPController.view.frame.origin.y + chooseIPController.view.frame.size.height > 10) ? YES : NO;
-}
-
-- (BOOL)isStatusBarVisible
-{
- return (viewStatusBar.frame.origin.y < self.view.frame.size.height) ? YES : NO;
-}
-
-- (void)showSimpleMessageDialog:(NSString*)message
-{
- [self showSimpleMessageDialog:message withButton:nil];
-}
-
-- (void)showSimpleMessageDialog:(NSString*)message withButton:(NSString*)btnName
-{
- if (alertView != nil)
- [alertView release];
- alertView = nil;
-
- alertView = [[UIAlertView alloc] initWithTitle:@"" message:message delegate:nil cancelButtonTitle:btnName otherButtonTitles:@"", nil];
- [alertView show];
-}
-
-
-#pragma mark - Bonjour helper functions
-
-// Creates an NSNetServiceBrowser that searches for services of a particular type in a particular domain.
-// If a service is currently being resolved, stop resolving it and stop the service browser from
-// discovering other services.
-- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain
-{
- [_netServiceBrowser stop];
- [_services removeAllObjects];
-
- if (_netServiceBrowser != nil)
- [_netServiceBrowser release];
-
- _netServiceBrowser = [[NSNetServiceBrowser alloc] init];
- if(!_netServiceBrowser)
- return NO;
-
- _netServiceBrowser.delegate = self;
- [_netServiceBrowser searchForServicesOfType:type inDomain:domain];
- return YES;
-}
-
-- (NSString *)addressHost4:(struct sockaddr_in *)pSockaddr4
-{
- char addrBuf[INET_ADDRSTRLEN];
-
- if(inet_ntop(AF_INET, &pSockaddr4->sin_addr, addrBuf, sizeof(addrBuf)) == NULL)
- {
- [NSException raise:NSInternalInconsistencyException format:@"Cannot convert address to string."];
- }
-
- return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
-}
-
-- (NSString *)addressHost6:(struct sockaddr_in6 *)pSockaddr6
-{
- char addrBuf[INET6_ADDRSTRLEN];
-
- if(inet_ntop(AF_INET6, &pSockaddr6->sin6_addr, addrBuf, sizeof(addrBuf)) == NULL)
- {
- [NSException raise:NSInternalInconsistencyException format:@"Cannot convert address to string."];
- }
-
- return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
-}
-
-- (NSString *)addressHost:(struct sockaddr *)pSockaddr
-{
- if(pSockaddr->sa_family == AF_INET)
- {
- return [self addressHost4:(struct sockaddr_in *)pSockaddr];
- }
- else
- {
- return [self addressHost6:(struct sockaddr_in6 *)pSockaddr];
- }
-}
-
-#pragma mark - AsyncUdpSocket delegate
-
-//Received data while listening
-- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)addressString port:(UInt16)port
-{
- //Convert the UDP data to an NSString
- NSString *udpDataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
- NSDictionary* tempParsedDict = [XMLReader dictionaryForXMLString:udpDataString error:nil];
-
- //Ignore loopback (restart receiving & return)
- addressString = [addressString stringByReplacingOccurrencesOfString:@"::ffff:" withString:@""];
- NSString* myIP = [CommService getLocalIPAddress];
- if (myIP != nil && myIP.length > 5 && [myIP isEqualToString:addressString])
- return [sock receiveWithTimeout:-1 tag:1];
-
- //Sanity check (restart receiving & return)
- if ([tempParsedDict objectForKey:@"xml"] == nil)
- return [sock receiveWithTimeout:-1 tag:1];;
- if ( ! [[tempParsedDict objectForKey:@"xml"] isKindOfClass:[NSDictionary class]])
- return [sock receiveWithTimeout:-1 tag:1];
- NSDictionary* rootDictionary = (NSDictionary*)[tempParsedDict objectForKey:@"xml"];
- if ([rootDictionary objectForKey:@"cmd"] == nil)
- return [sock receiveWithTimeout:-1 tag:1];
- NSString *commandString = [[rootDictionary objectForKey:@"cmd"] objectForKey:@"text"];
- if (commandString == nil)
- return [sock receiveWithTimeout:-1 tag:1];
- commandString = [commandString uppercaseString];
-
- //------------------------------------------------------
-
- if ([commandString isEqualToString:@"HELLO"])
- {
- _hasMoreHandshake = YES;
- _receiveHandshake = YES;
-
- //Status text on UI
- NSString *statusString = [NSString stringWithFormat:@"%d device(s) found", [_deviceList count]];
- [self setStatusText:statusString];
-
- if ([_deviceList objectForKey:addressString] == nil)
- {
- //Clean up received data into a nice dictionary
- NSMutableDictionary * dict = [[NSMutableDictionary alloc] initWithCapacity:10];
- for (NSString *key in [rootDictionary objectForKey:@"data"])
- {
- id value = [[rootDictionary objectForKey:@"data"] objectForKey:key];
- if (![value isKindOfClass:[NSDictionary class]])
- continue;
- id text = [(NSDictionary*)value objectForKey:@"text"];
- if (text == nil)
- continue;
- [dict setObject:text forKey:key];
- }
-
- //Check valid Hello return data
- NSString *guid = [dict objectForKey:@"guid"];
- if (guid != nil && [guid length] > 10)
- {
- //Get device name (from Internet)
- NSString * deviceName = [self getGUIDDeviceName:guid];
- if (deviceName != nil)
- [dict setObject:deviceName forKey:@"devicename"];
- [_deviceList setObject:dict forKey:addressString];
-
- [self hideStatusBar];
- NSLog(@"Found %@ %@, %@", addressString, deviceName, guid);
- }
- }
- }
- /*
- else if ([commandString isEqualToString:@"WIFISCAN"])
- {
- NSMutableArray *homeNetworkArray = [[NSMutableArray alloc] init];
- for (NSDictionary *eachNetwork in [[[tempParsedDict objectForKey:@"xml"] objectForKey:@"data"] objectForKey:@"wifi"]){
- [homeNetworkArray addObject:eachNetwork];
- }
-
- if (homeNetworkArray.count > 0){
- NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
- [ud setObject:homeNetworkArray forKey:@"homeNetworkArray"];
- ChooseHomeNetworkController *chnc = [[ChooseHomeNetworkController alloc] init];
- chnc.delegate = self;
- [self presentModalViewController:chnc animated:YES];
- }
- else{
- UIAlertView *noHomeNetworks = [[UIAlertView alloc] initWithTitle:@"Error" message:@"No home networks detected" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
- [noHomeNetworks show];
- }
- }
- */
- else
- {
- NSLog(@"Unknown command received");
- }
-
- //Listen for the next UDP packet to arrive...which will call this method again in turn
- [sock receiveWithTimeout:-1 tag:1];
-
- //Signal that we didn't ignore the packet
- return YES;
-}
-
-- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error
-{
-
-}
-
-- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
-{
-
-}
-
-
-
-#pragma mark - ChooseIPController delegate
-
-- (void) chooseIPController:(ChooseIPController *)chooseIPController didSelect:(NSMutableDictionary*)selectedData
-{
- [self gotoRemoteControl:selectedData];
-}
-
-
-
-#pragma mark - NSNetServiceBrowser delegate
-
-- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing
-{
- //if (_currentResolve && [service isEqual:_currentResolve])
- // [self stopCurrentResolve];
- [service setDelegate:nil];
- [_services removeObject:service];
-
- //if (moreComing)
- // _hasMoreHandshake = YES;
-}
-
-- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing
-{
- [_services addObject:service];
- [service setDelegate: self];
- [service resolveWithTimeout: 5];
-
- if (!moreComing)
- _hasMoreHandshake = YES;
-}
-
-
-#pragma mark - NSNetService delegate
-
-- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
-{
-
-}
-
-- (void)netServiceDidResolveAddress:(NSNetService *)service
-{
- NSArray *addresses = [service addresses];
- if ([addresses count] <= 0) {
- [_services removeObject:service];
- return;
- }
- for (id object in addresses)
- {
- /*
- NSString * address = [self addressHost:object];
- if (address == nil)
- continue;
- NSLog(@"Bonjour a device: %@", address);
- */
- }
-
- //NSLog(@"Bonjour a device: %@", [service addresses]);
-}
-
-
-
-#pragma mark - Application Logic
-
-- (void)reset
-{
- NSLog(@"NeTVViewController reseting...");
- _retryCounter = 0;
- _checkedReachability = NO;
- _startDiscoveryTime = (time_t)[[NSDate date] timeIntervalSince1970];
- _sentHandshake = NO;
- _receiveHandshake = NO;
- _hasMoreHandshake = NO;
-
- //UI
- if (_deviceList == nil)
- _deviceList = [[NSMutableDictionary alloc] initWithCapacity:10];
- [_deviceList removeAllObjects];
- [self hideStatusBar];
- [self showLoadingIcon];
-
- [self restartInitSequenceWithDelay:0.4];
-}
-
-- (void)restartInitSequenceWithDelay:(float)second
-{
- [self performSelector:@selector(initializeSequence) withObject:nil afterDelay:second];
-}
-
-- (int)numberOfDevices
-{
- if (_deviceList == nil)
- return 0;
- return [_deviceList count];
-}
-
-- (void)gotoRemoteControlSingleDevice
-{
- NSMutableDictionary *deviceData = [[_deviceList allValues] objectAtIndex:0];
- NSLog(@"%@", deviceData);
- [self gotoRemoteControl:deviceData];
-}
-
-- (void)gotoRemoteControl:(NSMutableDictionary*)deviceData
-{
- NSString *ipString = [deviceData objectForKey:@"ip"];
- if (ipString == nil || [ipString length] < 7)
- return;
-
- //Not sure why there is a leading space character (due to XML parser?)
- ipString = [ipString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- [self setDeviceIP:ipString];
-
- [self hideDeviceList];
-
- RemoteController *remoteController = [[RemoteController alloc] initWithIP:ipString];
- [self.navigationController pushViewController:remoteController animated:YES];
-}
-
-- (void)gotoRemoteControlDemo
-{
- NSString *ipString = @"127.0.0.2";
- [self setDeviceIP:ipString];
-
- RemoteController *remoteController = [[RemoteController alloc] initWithIP:ipString];
- [self.navigationController pushViewController:remoteController animated:YES];
-}
-
-- (void)initializeSequence
-{
- //Stage 1
- //If Wifi is disabled, show a message and stop here
- if (!_checkedReachability)
- {
- _checkedReachability = YES;
- if (![self isReachableWifi])
- {
- [self showStatusBarError:@"Please turn on WiFi"];
- return;
- }
- }
-
- //Stage 2
- //Send handshake and wait to receive all handshakes
- if (!_sentHandshake)
- {
-
- [self sendHandshake];
- [self sendHandshake];
- [self sendHandshake];
- _sentHandshake = YES;
- [self setStatusText:@"Searching for NeTV..."];
- [self restartInitSequenceWithDelay: 2.0];
- return;
- }
-
- //Stage 3
- //Wait for more handshake messages to arrive
- if (_hasMoreHandshake)
- {
- _hasMoreHandshake = NO;
- [self restartInitSequenceWithDelay:1.0];
- return;
- }
-
- //Stage 4
- //If received some handshake messages already
- if (_receiveHandshake)
- {
- //Hide the current prompt (if any)
- if (alertView != nil)
- [alertView dismissWithClickedButtonIndex:0 animated:YES];
-
- //Found only 1 device
- if ([self numberOfDevices] == 1)
- {
- NSMutableDictionary *deviceData = [[_deviceList allValues] objectAtIndex:0];
- NSString * ipString = [deviceData objectForKey:@"ip"];
- ipString = [ipString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- [self showStatusBarInfo:ipString];
- [self hideLoadingIcon];
-
- [self performSelector:@selector(gotoRemoteControlSingleDevice) withObject:nil afterDelay:1.2];
- return;
- }
-
- //Display a list, stop device discovery
- [self showDeviceList];
- [self hideStatusBar];
- return;
- }
-
- //If too long without a response
- time_t secondLapsed = (time_t)[[NSDate date] timeIntervalSince1970] - _startDiscoveryTime;
- if (secondLapsed > 8 && secondLapsed < 11)
- [self showStatusBarError:@"No device found.\nPlease ensure your NeTV is powered up."];
-
- [self sendHandshake];
- [self restartInitSequenceWithDelay: 1.0];
-}
-
-#pragma mark - Demo Mode
-- (IBAction)enterDemoMode:(id)sender
-{
- [self gotoRemoteControlDemo];
-}
-
-@end
+//
+// NeTVViewController.m
+// NeTV
+//
+
+#import "NeTVViewController.h"
+#import "RemoteController.h"
+#import <QuartzCore/QuartzCore.h>
+#import <sys/socket.h>
+#import <netinet/in.h>
+#import <arpa/inet.h>
+#import <sys/ioctl.h>
+#import <net/if.h>
+#import <netdb.h>
+
+#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)
+
+// Private extension
+@interface NeTVViewController()
+- (NSString *)addressHost4:(struct sockaddr_in *)pSockaddr4;
+- (NSString *)addressHost6:(struct sockaddr_in6 *)pSockaddr6;
+- (NSString *)addressHost:(struct sockaddr *)pSockaddr;
+@end
+
+@implementation NeTVViewController
+
+#pragma mark - Standard Initialization
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ //Show app version number
+ NSLog(@"Version %@", self.appVersion);
+ lblVersion.text = self.appVersion;
+
+ //Hide the custom navbar back button
+ btnNavbarBack.alpha = 0;
+
+ //Setup custom bottom bar
+ CGRect statusBarRect;
+ statusBarRect.origin.x = 0;
+ statusBarRect.origin.y = self.view.frame.size.height;
+ statusBarRect.size.width = self.view.frame.size.width;
+ statusBarRect.size.height = viewStatusBar.frame.size.height;
+ [self.view insertSubview:viewStatusBar aboveSubview:lblStatus];
+ viewStatusBar.frame = statusBarRect;
+
+ //Setup SearchResultTableView
+ if (chooseIPController == nil)
+ {
+ CGRect chooseIPRect;
+ chooseIPRect.origin.x = 0;
+ chooseIPRect.origin.y = - self.view.frame.size.height;
+ chooseIPRect.size.width = self.view.frame.size.width;
+ chooseIPRect.size.height = self.view.frame.size.height - imgNavbar.frame.size.height;
+
+ //Add to current view, hidden away
+ chooseIPController = [[ChooseIPController alloc] initWithNibName:@"ChooseIPController" bundle:[NSBundle mainBundle]];
+ [chooseIPController.view setFrame:chooseIPRect];
+ [self.view insertSubview:chooseIPController.view belowSubview:imgNavbar];
+ chooseIPController.delegate = self;
+ }
+
+ //Hide loading icon initially
+ imgLoading.alpha = 0;
+}
+
+- (void)viewDidUnload
+{
+ [super viewDidUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ //Bonjour stuff
+ if (_services == nil)
+ _services = [[NSMutableArray alloc] init];
+ [self searchForServicesOfType:@"_netv._tcp." inDomain:@""];
+
+ //Rescan
+ [self reset];
+}
+
+- (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
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+ } else {
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+ }
+}
+
+
+
+#pragma mark - UI Events
+
+-(IBAction)onNavbarBack:(id)sender
+{
+ [self hideDeviceList];
+ [self reset];
+}
+
+- (IBAction)enterDemoMode:(id)sender
+{
+ [self gotoRemoteControlDemo];
+}
+
+
+
+#pragma mark - Helpers
+
+- (void)showDeviceList
+{
+ [chooseIPController setData:_deviceList];
+
+ CGRect chooseIPRect;
+ chooseIPRect.origin.x = 0;
+ chooseIPRect.origin.y = imgNavbar.frame.size.height;
+ chooseIPRect.size.width = self.view.frame.size.width;
+ chooseIPRect.size.height = self.view.frame.size.height - imgNavbar.frame.size.height;
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.6];
+ lblInstruction.alpha = 0;
+ lblVersion.alpha = 0;
+ lblStatus.alpha = 0;
+ imgLogo.alpha = 0;
+ imgLoading.alpha = 0;
+ [UIView commitAnimations];
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDelay:0.2];
+ [UIView setAnimationDuration:0.6];
+ btnNavbarBack.alpha = 1;
+ chooseIPController.view.frame = chooseIPRect;
+ [UIView commitAnimations];
+}
+
+- (void)hideDeviceList
+{
+ CGRect chooseIPRect;
+ chooseIPRect.origin.x = 0;
+ chooseIPRect.origin.y = - self.view.frame.size.height;
+ chooseIPRect.size.width = self.view.frame.size.width;
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.6];
+ btnNavbarBack.alpha = 0;
+ chooseIPController.view.frame = chooseIPRect;
+ [UIView commitAnimations];
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.6];
+ [UIView setAnimationDelay:0.2];
+ [UIView setAnimationDidStopSelector: @selector(clearDeviceList)];
+ lblInstruction.alpha = 1;
+ lblVersion.alpha = 1;
+ lblStatus.alpha = 1;
+ imgLogo.alpha = 1;
+ [UIView commitAnimations];
+}
+
+- (void)clearDeviceList
+{
+ [chooseIPController clearData];
+}
+
+- (void)setStatusText:(NSString *)text
+{
+ lblStatus.text = text;
+ lblStatusFull.text = text;
+}
+
+- (void)showStatusBar:(NSString*)text
+{
+ if (text != nil)
+ [self setStatusText:text];
+
+ CGRect statusBarRect;
+ statusBarRect.origin.x = 0;
+ statusBarRect.origin.y = self.view.frame.size.height - viewStatusBar.frame.size.height;
+ statusBarRect.size.width = self.view.frame.size.width;
+ statusBarRect.size.height = viewStatusBar.frame.size.height;
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.3];
+ viewStatusBar.frame = statusBarRect;
+ [UIView commitAnimations];
+}
+
+- (void)showStatusBarError:(NSString*)text
+{
+ [self showStatusBarError:text showDemoBtn:NO];
+}
+
+- (void)showStatusBarError:(NSString*)text showDemoBtn:(BOOL)showDemoBtn
+{
+ CGRect text_frame = lblStatusFull.frame;
+
+ btnDemo.hidden = !showDemoBtn;
+ if (showDemoBtn) text_frame.size.width = self.view.frame.size.width - btnDemo.frame.size.width;
+ else text_frame.size.width = self.view.frame.size.width;
+ lblStatusFull.frame = text_frame;
+
+ [imgStatusBar setImage:[UIImage imageNamed:@"bottombar_error.png"]];
+ [self showStatusBar:text];
+}
+
+- (void)showStatusBarInfo:(NSString*)text
+{
+ btnDemo.hidden = YES;
+ CGRect text_frame = lblStatusFull.frame;
+ text_frame.size.width = self.view.frame.size.width;
+ lblStatusFull.frame = text_frame;
+
+ [imgStatusBar setImage:[UIImage imageNamed:@"bottombar_info.png"]];
+ [self showStatusBar:text];
+}
+
+- (void)hideStatusBar
+{
+ CGRect statusBarRect;
+ statusBarRect.origin.x = 0;
+ statusBarRect.origin.y = self.view.frame.size.height + 5;
+ statusBarRect.size.width = self.view.frame.size.width;
+ statusBarRect.size.height = viewStatusBar.frame.size.height;
+
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.3];
+ viewStatusBar.frame = statusBarRect;
+ [UIView commitAnimations];
+}
+
+- (void)showLoadingIcon
+{
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.7];
+ [UIView setAnimationDelay:0.5];
+ imgLoading.alpha = 0.5;
+ [UIView commitAnimations];
+
+ //Setup spining loading icon
+ CATransform3D rotationTransform = CATransform3DMakeRotation(0.9999f * M_PI, 0, 0, 1.0);
+ CABasicAnimation* rotationAnimation;
+ rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
+ rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
+ rotationAnimation.duration = 1.25f;
+ rotationAnimation.cumulative = YES;
+ rotationAnimation.repeatCount = 999;
+ [imgLoading.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
+}
+
+- (void)hideLoadingIcon
+{
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ [UIView setAnimationDuration:0.5];
+ imgLoading.alpha = 0;
+ [UIView commitAnimations];
+}
+
+- (BOOL)isDeviceListVisible
+{
+ return (chooseIPController.view.frame.origin.y + chooseIPController.view.frame.size.height > 10) ? YES : NO;
+}
+
+- (BOOL)isStatusBarVisible
+{
+ return (viewStatusBar.frame.origin.y < self.view.frame.size.height) ? YES : NO;
+}
+
+- (void)showSimpleMessageDialog:(NSString*)message
+{
+ [self showSimpleMessageDialog:message withButton:nil];
+}
+
+- (void)showSimpleMessageDialog:(NSString*)message withButton:(NSString*)btnName
+{
+ if (alertView != nil)
+ [alertView release];
+ alertView = nil;
+
+ alertView = [[UIAlertView alloc] initWithTitle:@"" message:message delegate:nil cancelButtonTitle:btnName otherButtonTitles:@"", nil];
+ [alertView show];
+}
+
+
+#pragma mark - Bonjour helper functions
+
+// Creates an NSNetServiceBrowser that searches for services of a particular type in a particular domain.
+// If a service is currently being resolved, stop resolving it and stop the service browser from
+// discovering other services.
+- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain
+{
+ [_netServiceBrowser stop];
+ [_services removeAllObjects];
+
+ if (_netServiceBrowser != nil)
+ [_netServiceBrowser release];
+
+ _netServiceBrowser = [[NSNetServiceBrowser alloc] init];
+ if(!_netServiceBrowser)
+ return NO;
+
+ _netServiceBrowser.delegate = self;
+ [_netServiceBrowser searchForServicesOfType:type inDomain:domain];
+ return YES;
+}
+
+- (NSString *)addressHost4:(struct sockaddr_in *)pSockaddr4
+{
+ char addrBuf[INET_ADDRSTRLEN];
+
+ if(inet_ntop(AF_INET, &pSockaddr4->sin_addr, addrBuf, sizeof(addrBuf)) == NULL)
+ {
+ [NSException raise:NSInternalInconsistencyException format:@"Cannot convert address to string."];
+ }
+
+ return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
+}
+
+- (NSString *)addressHost6:(struct sockaddr_in6 *)pSockaddr6
+{
+ char addrBuf[INET6_ADDRSTRLEN];
+
+ if(inet_ntop(AF_INET6, &pSockaddr6->sin6_addr, addrBuf, sizeof(addrBuf)) == NULL)
+ {
+ [NSException raise:NSInternalInconsistencyException format:@"Cannot convert address to string."];
+ }
+
+ return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
+}
+
+- (NSString *)addressHost:(struct sockaddr *)pSockaddr
+{
+ if(pSockaddr->sa_family == AF_INET)
+ {
+ return [self addressHost4:(struct sockaddr_in *)pSockaddr];
+ }
+ else
+ {
+ return [self addressHost6:(struct sockaddr_in6 *)pSockaddr];
+ }
+}
+
+#pragma mark - AsyncUdpSocket delegate
+
+//Received data while listening
+- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)addressString port:(UInt16)port
+{
+ //Convert the UDP data to an NSString
+ NSString *udpDataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
+ NSDictionary* tempParsedDict = [XMLReader dictionaryForXMLString:udpDataString error:nil];
+
+ //Ignore loopback (restart receiving & return)
+ addressString = [addressString stringByReplacingOccurrencesOfString:@"::ffff:" withString:@""];
+ NSString* myIP = [CommService getLocalIPAddress];
+ if (myIP != nil && myIP.length > 5 && [myIP isEqualToString:addressString])
+ return [sock receiveWithTimeout:-1 tag:1];
+
+ //Sanity check (restart receiving & return)
+ if ([tempParsedDict objectForKey:@"xml"] == nil)
+ return [sock receiveWithTimeout:-1 tag:1];;
+ if ( ! [[tempParsedDict objectForKey:@"xml"] isKindOfClass:[NSDictionary class]])
+ return [sock receiveWithTimeout:-1 tag:1];
+ NSDictionary* rootDictionary = (NSDictionary*)[tempParsedDict objectForKey:@"xml"];
+ if ([rootDictionary objectForKey:@"cmd"] == nil)
+ return [sock receiveWithTimeout:-1 tag:1];
+ NSString *commandString = [[rootDictionary objectForKey:@"cmd"] objectForKey:@"text"];
+ if (commandString == nil)
+ return [sock receiveWithTimeout:-1 tag:1];
+ commandString = [commandString uppercaseString];
+
+ //------------------------------------------------------
+
+ if ([commandString isEqualToString:@"HELLO"])
+ {
+ _hasMoreHandshake = YES;
+ _receiveHandshake = YES;
+
+ //Status text on UI
+ NSString *statusString = [NSString stringWithFormat:@"%d device(s) found", [_deviceList count]];
+ [self setStatusText:statusString];
+
+ if ([_deviceList objectForKey:addressString] == nil)
+ {
+ //Clean up received data into a nice dictionary
+ NSMutableDictionary * dict = [[NSMutableDictionary alloc] initWithCapacity:10];
+ for (NSString *key in [rootDictionary objectForKey:@"data"])
+ {
+ id value = [[rootDictionary objectForKey:@"data"] objectForKey:key];
+ if (![value isKindOfClass:[NSDictionary class]])
+ continue;
+ id text = [(NSDictionary*)value objectForKey:@"text"];
+ if (text == nil)
+ continue;
+ [dict setObject:text forKey:key];
+ }
+
+ //Check valid Hello return data
+ NSString *guid = [dict objectForKey:@"guid"];
+ if (guid != nil && [guid length] > 10)
+ {
+ //Get device name (from Internet)
+ NSString * deviceName = [self getGUIDDeviceName:guid];
+ if (deviceName != nil)
+ [dict setObject:deviceName forKey:@"devicename"];
+ [_deviceList setObject:dict forKey:addressString];
+
+ [self hideStatusBar];
+ NSLog(@"Found %@ %@, %@", addressString, deviceName, guid);
+ }
+ }
+ }
+ /*
+ else if ([commandString isEqualToString:@"WIFISCAN"])
+ {
+ NSMutableArray *homeNetworkArray = [[NSMutableArray alloc] init];
+ for (NSDictionary *eachNetwork in [[[tempParsedDict objectForKey:@"xml"] objectForKey:@"data"] objectForKey:@"wifi"]){
+ [homeNetworkArray addObject:eachNetwork];
+ }
+
+ if (homeNetworkArray.count > 0){
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ [ud setObject:homeNetworkArray forKey:@"homeNetworkArray"];
+ ChooseHomeNetworkController *chnc = [[ChooseHomeNetworkController alloc] init];
+ chnc.delegate = self;
+ [self presentModalViewController:chnc animated:YES];
+ }
+ else{
+ UIAlertView *noHomeNetworks = [[UIAlertView alloc] initWithTitle:@"Error" message:@"No home networks detected" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
+ [noHomeNetworks show];
+ }
+ }
+ */
+ else
+ {
+ NSLog(@"Unknown command received");
+ }
+
+ //Listen for the next UDP packet to arrive...which will call this method again in turn
+ [sock receiveWithTimeout:-1 tag:1];
+
+ //Signal that we didn't ignore the packet
+ return YES;
+}
+
+- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error
+{
+
+}
+
+- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
+{
+
+}
+
+
+
+#pragma mark - ChooseIPController delegate
+
+- (void) chooseIPController:(ChooseIPController *)chooseIPController didSelect:(NSMutableDictionary*)selectedData
+{
+ [self gotoRemoteControl:selectedData];
+}
+
+
+
+#pragma mark - NSNetServiceBrowser delegate
+
+- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing
+{
+ //if (_currentResolve && [service isEqual:_currentResolve])
+ // [self stopCurrentResolve];
+ [service setDelegate:nil];
+ [_services removeObject:service];
+
+ //if (moreComing)
+ // _hasMoreHandshake = YES;
+}
+
+- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing
+{
+ [_services addObject:service];
+ [service setDelegate: self];
+ [service resolveWithTimeout: 5];
+
+ if (!moreComing)
+ _hasMoreHandshake = YES;
+}
+
+
+#pragma mark - NSNetService delegate
+
+- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
+{
+
+}
+
+- (void)netServiceDidResolveAddress:(NSNetService *)service
+{
+ NSArray *addresses = [service addresses];
+ if ([addresses count] <= 0) {
+ [_services removeObject:service];
+ return;
+ }
+ for (id object in addresses)
+ {
+ /*
+ NSString * address = [self addressHost:object];
+ if (address == nil)
+ continue;
+ NSLog(@"Bonjour a device: %@", address);
+ */
+ }
+
+ //NSLog(@"Bonjour a device: %@", [service addresses]);
+}
+
+
+
+#pragma mark - Application Logic
+
+- (void)reset
+{
+ NSLog(@"NeTVViewController reseting...");
+ _retryCounter = 0;
+ _checkedReachability = NO;
+ _startDiscoveryTime = (time_t)[[NSDate date] timeIntervalSince1970];
+ _sentHandshake = NO;
+ _receiveHandshake = NO;
+ _hasMoreHandshake = NO;
+
+ //UI
+ if (_deviceList == nil)
+ _deviceList = [[NSMutableDictionary alloc] initWithCapacity:10];
+ [_deviceList removeAllObjects];
+ [self hideStatusBar];
+ [self showLoadingIcon];
+
+ [self restartInitSequenceWithDelay:0.4];
+}
+
+- (void)restartInitSequenceWithDelay:(float)second
+{
+ [self performSelector:@selector(initializeSequence) withObject:nil afterDelay:second];
+}
+
+- (int)numberOfDevices
+{
+ if (_deviceList == nil)
+ return 0;
+ return [_deviceList count];
+}
+
+- (void)gotoRemoteControlSingleDevice
+{
+ NSMutableDictionary *deviceData = [[_deviceList allValues] objectAtIndex:0];
+ NSLog(@"%@", deviceData);
+ [self gotoRemoteControl:deviceData];
+}
+
+- (void)gotoRemoteControl:(NSMutableDictionary*)deviceData
+{
+ NSString *ipString = [deviceData objectForKey:@"ip"];
+ if (ipString == nil || [ipString length] < 7)
+ return;
+
+ //Not sure why there is a leading space character (due to XML parser?)
+ ipString = [ipString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ [self setDeviceIP:ipString];
+
+ [self hideDeviceList];
+
+ RemoteController *remoteController = [[RemoteController alloc] initWithIP:ipString];
+ [self.navigationController pushViewController:remoteController animated:YES];
+}
+
+- (void)gotoRemoteControlDemo
+{
+ NSString *ipString = @"127.0.0.2";
+ [self setDeviceIP:ipString];
+
+ RemoteController *remoteController = [[RemoteController alloc] initWithIP:ipString];
+ [self.navigationController pushViewController:remoteController animated:YES];
+}
+
+- (void)initializeSequence
+{
+ //Stage 1
+ //If Wifi is disabled, show a message and stop here
+ if (!_checkedReachability)
+ {
+ _checkedReachability = YES;
+ if (![self isReachableWifi])
+ {
+ [self showStatusBarError:@"Please turn on WiFi"];
+ return;
+ }
+ }
+
+ //Stage 2
+ //Send handshake and wait to receive all handshakes
+ if (!_sentHandshake)
+ {
+
+ [self sendHandshake];
+ [self sendHandshake];
+ [self sendHandshake];
+ _sentHandshake = YES;
+ [self setStatusText:@"Searching for NeTV..."];
+ [self restartInitSequenceWithDelay: 2.0];
+ return;
+ }
+
+ //Stage 3
+ //Wait for more handshake messages to arrive
+ if (_hasMoreHandshake)
+ {
+ _hasMoreHandshake = NO;
+ [self restartInitSequenceWithDelay:1.0];
+ return;
+ }
+
+ //Stage 4
+ //If received some handshake messages already
+ if (_receiveHandshake)
+ {
+ //Hide the current prompt (if any)
+ if (alertView != nil)
+ [alertView dismissWithClickedButtonIndex:0 animated:YES];
+
+ //Found only 1 device
+ if ([self numberOfDevices] == 1)
+ {
+ NSMutableDictionary *deviceData = [[_deviceList allValues] objectAtIndex:0];
+ NSString * ipString = [deviceData objectForKey:@"ip"];
+ ipString = [ipString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ [self showStatusBarInfo:ipString];
+ [self hideLoadingIcon];
+
+ [self performSelector:@selector(gotoRemoteControlSingleDevice) withObject:nil afterDelay:1.2];
+ return;
+ }
+
+ //Display a list, stop device discovery
+ [self showDeviceList];
+ [self hideStatusBar];
+ return;
+ }
+
+ //If too long without a response
+ time_t secondLapsed = (time_t)[[NSDate date] timeIntervalSince1970] - _startDiscoveryTime;
+ if (secondLapsed > 8 && secondLapsed < 11)
+ [self showStatusBarError:@"No device found.\nPlease ensure your NeTV is powered up." showDemoBtn:YES];
+
+ [self sendHandshake];
+ [self restartInitSequenceWithDelay: 1.0];
+}
+
+@end
View
179 NeTV/NeTVViewController_iPhone.xib
@@ -46,6 +46,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{51, 49}, {218, 44}}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="325274760"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
@@ -80,6 +81,8 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, 432}, {320, 21}}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<object class="NSColor" key="IBUIBackgroundColor" id="757653164">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
@@ -113,6 +116,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, 275}, {320, 21}}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="76141685"/>
<reference key="IBUIBackgroundColor" ref="757653164"/>
<bool key="IBUIOpaque">NO</bool>
@@ -143,6 +147,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, 192}, {320, 75}}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="637917365"/>
<int key="IBUIContentMode">1</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
@@ -157,6 +162,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="761539309"/>
<string key="NSReuseIdentifierKey">_NS:541</string>
<reference key="IBUIBackgroundColor" ref="757653164"/>
@@ -176,6 +182,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{68, 39}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="10037274"/>
<string key="NSReuseIdentifierKey">_NS:222</string>
<bool key="IBUIOpaque">NO</bool>
@@ -209,6 +216,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{287, 7}, {24, 24}}</string>
<reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="185886049"/>
<string key="NSReuseIdentifierKey">_NS:541</string>
<reference key="IBUIBackgroundColor" ref="757653164"/>
@@ -227,6 +235,7 @@
</object>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="311808379"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
@@ -248,6 +257,7 @@
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 42}</string>
<reference key="NSSuperview" ref="665197606"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="297006914"/>
<string key="NSReuseIdentifierKey">_NS:541</string>
<reference key="IBUIBackgroundColor" ref="757653164"/>
@@ -264,6 +274,8 @@
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 42}</string>
<reference key="NSSuperview" ref="665197606"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="851084506"/>
<string key="NSReuseIdentifierKey">_NS:311</string>
<reference key="IBUIBackgroundColor" ref="757653164"/>
<bool key="IBUIOpaque">NO</bool>
@@ -286,21 +298,26 @@
<object class="IBUIButton" id="851084506">
<reference key="NSNextResponder" ref="665197606"/>
<int key="NSvFlags">292</int>
- <string key="NSFrame">{{245, 7}, {55, 28}}</string>
+ <string key="NSFrame">{{267, 0}, {53, 39}}</string>
<reference key="NSSuperview" ref="665197606"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:225</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <int key="IBUIContentHorizontalAlignment">0</int>
- <int key="IBUIContentVerticalAlignment">0</int>
- <int key="IBUIButtonType">1</int>
+ <int key="IBUIContentHorizontalAlignment">2</int>
+ <int key="IBUIContentVerticalAlignment">2</int>
<string key="IBUINormalTitle">Demo</string>
<reference key="IBUIHighlightedTitleColor" ref="208312599"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="68326816"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">btn_demo.png</string>
+ </object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
@@ -310,6 +327,7 @@
</object>
<string key="NSFrameSize">{320, 42}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="679803044"/>
<string key="NSReuseIdentifierKey">_NS:180</string>
<reference key="IBUIBackgroundColor" ref="757653164"/>
@@ -408,6 +426,14 @@
<int key="connectionID">51</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">btnDemo</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="851084506"/>
+ </object>
+ <int key="connectionID">54</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">onNavbarBack:</string>
<reference key="source" ref="761539309"/>
@@ -545,6 +571,7 @@
<string>42.IBPluginDependency</string>
<string>50.IBPluginDependency</string>
<string>52.IBPluginDependency</string>
+ <string>52.IBUIButtonInspectorSelectedStateConfigurationMetadataKey</string>
<string>6.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
@@ -564,6 +591,7 @@
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <real value="0.0"/>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
@@ -579,9 +607,146 @@
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
- <int key="maxID">53</int>
+ <int key="maxID">54</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">BaseController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">onNavbarBack:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">onNavbarBack:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">onNavbarBack:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/BaseController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NeTVViewController</string>
+ <string key="superclassName">BaseController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">enterDemoMode:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">enterDemoMode:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">enterDemoMode:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>btnDemo</string>
+ <string>btnNavbarBack</string>
+ <string>imgLoading</string>
+ <string>imgLogo</string>
+ <string>imgNavbar</string>
+ <string>imgStatusBar</string>
+ <string>lblInstruction</string>
+ <string>lblStatus</string>
+ <string>lblStatusFull</string>
+ <string>lblVersion</string>
+ <string>viewStatusBar</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIButton</string>
+ <string>UIButton</string>
+ <string>UIImageView</string>
+ <string>UIImageView</string>
+ <string>UIImageView</string>
+ <string>UIImageView</string>
+ <string>UILabel</string>
+ <string>UILabel</string>
+ <string>UILabel</string>
+ <string>UILabel</string>
+ <string>UIView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>btnDemo</string>
+ <string>btnNavbarBack</string>
+ <string>imgLoading</string>
+ <string>imgLogo</string>
+ <string>imgNavbar</string>
+ <string>imgStatusBar</string>
+ <string>lblInstruction</string>
+ <string>lblStatus</string>
+ <string>lblStatusFull</string>
+ <string>lblVersion</string>
+ <string>viewStatusBar</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">btnDemo</string>
+ <string key="candidateClassName">UIButton</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">btnNavbarBack</string>
+ <string key="candidateClassName">UIButton</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">imgLoading</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">imgLogo</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">imgNavbar</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">imgStatusBar</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">lblInstruction</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">lblStatus</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">lblStatusFull</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">lblVersion</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">viewStatusBar</string>
+ <string key="candidateClassName">UIView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/NeTVViewController.h</string>
+ </object>
+ </object>
+ </object>
</object>
- <object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
@@ -595,6 +760,7 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>bottombar_error.png</string>
+ <string>btn_demo.png</string>
<string>chumby.png</string>
<string>loading_icon.png</string>
<string>navbar_back.png</string>
@@ -603,6 +769,7 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>{320, 42}</string>
+ <string>{53, 39}</string>
<string>{320, 94}</string>
<string>{32, 32}</string>
<string>{68, 39}</string>
View
592 NeTV/NeTVWebViewController.m
@@ -1,295 +1,297 @@
-//
-// NeTVWebViewController.m
-// NeTV
-//
-
-#import "NeTVWebViewController.h"
-#import <QuartzCore/QuartzCore.h>
-
-@interface NeTVWebViewController() <UIWebViewDelegate, UIScrollViewDelegate>
- - (UIScrollView*) getScrollView;
- - (void)showLoadingIcon;
- - (void)hideLoadingIcon;
- - (void)updateWebButtons;
- - (void)updateAddress:(NSURLRequest*)request;
- - (void)showError:(NSError*)error;
- - (void)netvLoadURL:(NSString*)url;
- @property (nonatomic, retain) UIScrollView* scrollView;
- @property (nonatomic, copy) NSString *theMainIP;
-@end
-
-@implementation NeTVWebViewController
-
-@synthesize webView;
-@synthesize backward;
-@synthesize forward;
-@synthesize addressField;
-@synthesize loadingBar;
-@synthesize lblStatus;
-@synthesize imgLoading;
-
-@synthesize scrollView;
-@synthesize theMainIP;
-
-#define DEFAULT_URL @"http://www.chumby.com"
-
-- (void)didReceiveMemoryWarning
-{
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
-}
-
-#pragma mark - View lifecycle
-
-- (void)viewDidLoad
-{
- [super viewDidLoad];
-
- NSAssert(self.backward, @"Unconnected IBOutlet 'backward'.");
- NSAssert(self.forward, @"Unconnected IBOutlet 'forward'.");
- NSAssert(self.webView, @"Unconnected IBOutlet 'webView'.");
- NSAssert(self.addressField, @"Unconnected IBOutlet addressField");
- NSAssert(self.lblStatus, @"Unconnected IBOutlet lblStatus");
- NSAssert(self.imgLoading, @"Unconnected IBOutlet imgLoading");
-
- self.scrollView = [self getScrollView];
- self.theMainIP = [self getDeviceIP];
- self.addressField.text = DEFAULT_URL;
-
- NSURL* url = [NSURL URLWithString:DEFAULT_URL];
- [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
- [self updateWebButtons];
-
- //[self netvLoadURL:DEFAULT_URL];
- // No need to send url to netv here
- // Sending url to netv all using the function updateAddress
- // This also make the forward and backward work.
-}
-
-- (void)dealloc
-{
- [super dealloc];
-}
-
-- (void)viewDidUnload
-{
- self.webView = nil;
- self.backward = nil;
- self.forward = nil;
- self.addressField = nil;
- self.lblStatus = nil;
-
- self.theMainIP = nil;
- self.scrollView = nil;
-
- [super viewDidUnload];
-}
-
-- (void)viewWillAppear:(BOOL)animated
-{
- [super viewWillAppear:animated];
-
- //UI
- if (self.theMainIP != nil)
- lblStatus.text = [NSString stringWithFormat:@"Controlling %@", self.theMainIP];
- else
- lblStatus.text = @"";
-
- //Hide loading icon initially
- imgLoading.alpha = 0;
-}
-
-- (void)viewDidAppear:(BOOL)animated
-{
- [super viewDidAppear:animated];
-}
-
-- (void)viewWillDisappear:(BOOL)animated
-{
- NSLog(@"hahaha!");
-
- [self sendMultitabCloseAll:self.theMainIP];
-
- [super viewWillDisappear:animated];
-}
-
-- (void)viewDidDisappear:(BOOL)animated
-{
-
- [super viewDidDisappear:animated];
-}
-
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
- // Return YES for supported orientations
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- } else {
- return YES;
- }
-}
-
-- (void)applicationDidEnterBackground:(NSNotification *)notification
-{
- [self sendMultitabCloseAll:(self.theMainIP)];
-}
-
-
-#pragma mark - UIWebViewDelegate protocols
-
-- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
-{
- return YES;
-}
-
-- (void)webViewDidStartLoad:(UIWebView *)webview
-{
- [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
- //[self updateAddress:[webview request]];
- [self updateWebButtons];
- [self showLoadingIcon];
-}
-
-- (void)webViewDidFinishLoad:(UIWebView *)webview
-{
- [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
- [self updateAddress:[webview request]];
- [self updateWebButtons];
- [self hideLoadingIcon];
-
- // The following code determine the height of a web page.
- CGSize fittingSize = [self.webView sizeThatFits:CGSizeZero];
- pageLength = fittingSize.height;
-}
-
-- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
-{
- [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
- [self updateWebButtons];
- [self hideLoadingIcon];
- [self showError:error];
-}
-
-
-
-#pragma mark - UIScrollViewDelegate protocols
-
-- (void)scrollViewDidScroll:(UIScrollView *)scrollview
-{
- float offset = scrollview.contentOffset.y /pageLength;
- [self sendMultitabScrollF:self.theMainIP tabIndex:1 scrollfX:0.0 scrollfY:offset];
-}
-
-
-
-#pragma mark - UI Events
-
-- (IBAction)loadAddress:(id)sender
-{
- NSString* urlString = self.addressField.text;
- NSURL* url = [NSURL URLWithString:urlString];
-
- if (!url.scheme)
- {
- NSString* modifiedURLString = [NSString stringWithFormat:@"http://%@", urlString];
- urlString = modifiedURLString;
- url = [NSURL URLWithString:modifiedURLString];
- }
-
- [self netvLoadURL:urlString];
- [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
- self.addressField.text = urlString;
-}
-
-- (IBAction)goBackward:(id)sender
-{
- [self.webView goBack];
-}
-- (IBAction)goForward:(id)sender
-{
- [self.webView goForward];
-}
-
-
-
-#pragma mark - Helpers
-
-// This function get the scrollView out of the UIWebView
-- (UIScrollView*) getScrollView
-{
- UIScrollView* currentScrollView;
- for (UIView* subView in self.webView.subviews) {
- if ([subView isKindOfClass:[UIScrollView class]]) {
- currentScrollView = (UIScrollView*)subView;
- currentScrollView.delegate = self;
- }
- }
- return currentScrollView;
-}
-
-- (void)showLoadingIcon
-{
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.7];
- [UIView setAnimationDelay:0.5];
- imgLoading.alpha = 0.5;
- [UIView commitAnimations];
-
- //Setup spining loading icon
- CATransform3D rotationTransform = CATransform3DMakeRotation(0.9999f * M_PI, 0, 0, 1.0);
- CABasicAnimation* rotationAnimation;
- rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
- rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
- rotationAnimation.duration = 1.25f;
- rotationAnimation.cumulative = YES;
- rotationAnimation.repeatCount = 999;
- [imgLoading.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
-}
-
-- (void)hideLoadingIcon
-{
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationBeginsFromCurrentState:YES];
- [UIView setAnimationDuration:0.5];
- imgLoading.alpha = 0;
- [UIView commitAnimations];
-}
-
-- (void)updateWebButtons
-{
- self.forward.enabled = self.webView.canGoForward;
- self.forward.alpha = self.webView.canGoForward ? 1.0 : 0.2;
- self.backward.enabled = self.webView.canGoBack;
- self.backward.alpha = self.webView.canGoBack ? 1.0 : 0.2;
-}
-
-- (void)updateAddress:(NSURLRequest *)request
-{
- NSURL* url = [request mainDocumentURL];
- NSString* absoluteString = [url absoluteString];
- if ([absoluteString length] < 3)
- return;
- self.addressField.text = absoluteString;
- [self netvLoadURL:absoluteString];
-}
-
-- (void)showError:(NSError*)error
-{
- NSString* localizedDescription = [error localizedDescription];
- UIAlertView* alertView = [[UIAlertView alloc]
- initWithTitle:@"Error"
- message:localizedDescription
- delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles: nil];
- [alertView show];
- [alertView release];
-}
-
-- (void)netvLoadURL:(NSString*)url
-{
- [self sendMultitabCommand:self.theMainIP tabIndex:1 options:@"load" param:url];
-}
-
-@end
+//
+// NeTVWebViewController.m
+// NeTV
+//
+
+#import "NeTVWebViewController.h"
+#import <QuartzCore/QuartzCore.h>
+
+@interface NeTVWebViewController() <UIWebViewDelegate, UIScrollViewDelegate>
+ - (UIScrollView*) getScrollView;
+ - (void)showLoadingIcon;
+ - (void)hideLoadingIcon;
+ - (void)updateWebButtons;
+ - (void)updateAddress:(NSURLRequest*)request;
+ - (void)showError:(NSError*)error;
+ - (void)netvLoadURL:(NSString*)url;
+ @property (nonatomic, retain) UIScrollView* scrollView;
+ @property (nonatomic, copy) NSString *theMainIP;
+@end
+
+@implementation NeTVWebViewController
+
+@synthesize webView;
+@synthesize backward;
+@synthesize forward;
+@synthesize addressField;
+@synthesize loadingBar;
+@synthesize lblStatus;
+@synthesize imgLoading;
+
+@synthesize scrollView;
+@synthesize theMainIP;
+
+#define DEFAULT_URL @"http://www.chumby.com"
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Release any cached data, images, etc that aren't in use.
+}
+
+#pragma mark - View lifecycle
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ NSAssert(self.backward, @"Unconnected IBOutlet 'backward'.");
+ NSAssert(self.forward, @"Unconnected IBOutlet 'forward'.");
+ NSAssert(self.webView, @"Unconnected IBOutlet 'webView'.");
+ NSAssert(self.addressField, @"Unconnected IBOutlet addressField");
+ NSAssert(self.lblStatus, @"Unconnected IBOutlet lblStatus");
+ NSAssert(self.imgLoading, @"Unconnected IBOutlet imgLoading");
+
+ self.scrollView = [self getScrollView];
+ self.theMainIP = [self getDeviceIP];
+ self.addressField.text = DEFAULT_URL;
+
+ NSURL* url = [NSURL URLWithString:DEFAULT_URL];
+ [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
+ [self updateWebButtons];
+
+ //[self netvLoadURL:DEFAULT_URL];
+ // No need to send url to netv here
+ // Sending url to netv all using the function updateAddress
+ // This also make the forward and backward work.
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+- (void)viewDidUnload
+{
+ self.webView = nil;
+ self.backward = nil;
+ self.forward = nil;
+ self.addressField = nil;
+ self.lblStatus = nil;
+
+ self.theMainIP = nil;
+ self.scrollView = nil;
+
+ [super viewDidUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ //UI
+ if (self.theMainIP != nil && [self.theMainIP isEqualToString:@"127.0.0.2"])
+ lblStatus.text = @"Demo Mode";
+ if (self.theMainIP != nil)
+ lblStatus.text = [NSString stringWithFormat:@"Controlling %@", self.theMainIP];
+ else
+ lblStatus.text = @"";
+
+ //Hide loading icon initially
+ imgLoading.alpha = 0;
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+ NSLog(@"hahaha!");
+
+ [self sendMultitabCloseAll:self.theMainIP];
+
+ [super viewWillDisappear:animated];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+
+ [super viewDidDisappear:animated];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ // Return YES for supported orientations
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+ } else {
+ return YES;
+ }
+}
+
+- (void)applicationDidEnterBackground:(NSNotification *)notification
+{
+ [self sendMultitabCloseAll:(self.theMainIP)];
+}