Posts Tagged Development
iPhone Network Connectivity Test Example
Posted by Chris Danielson in iPhone Development on July 22nd, 2009
Every iPhone developer that has integrated a network connection based application has had to follow the Apple HID (Human Interface Design) rules. This means, that in order to get the Apple reviewers to sign-off on your application, you have to pass the network connectivity test. Basically, in the case of a catastrophic network disconnect issue with 3G and WiFi does your application properly alert the user that it will not perform properly without the usage of the network? I’ve seen a lot of workaround techniques where users attempt to do an HTTP GET on say Google or some other website. Clearly, this kind of technique will work sporadically in an unknown environment common to the mobile device. I mean, imagine causing your application users to sit through a 5-30 second web request timeout. The end-user will probably believe that the application is hung. The ideal solution happens to be handed to us in the API Framework SCNetworkReachability. (Make sure your codebase is linked properly with the “SystemConfiguration” Framework).
It’s worked for me and I recommend it for doing a simple network connectivity test.
#import <sys/socket.h> #import <netinet/in.h> #import <arpa/inet.h> #import <netdb.h> #import <SystemConfiguration/SCNetworkReachability.h> //Snip, you know we're in the implementation... - (BOOL) connectedToNetwork { // Create zero addy struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; // Recover reachability flags SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); SCNetworkReachabilityFlags flags; BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); CFRelease(defaultRouteReachability); if (!didRetrieveFlags) { return NO; } BOOL isReachable = flags & kSCNetworkFlagsReachable; BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired; return (isReachable && !needsConnection) ? YES : NO; } //call like: -(void) start { if (![self connectedToNetwork]) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network Connection Error" message:@"You need to be connected to the internet to use this feature." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } else { //do something } } |
This code can also be found on this forum post.
.Net C Sharp Date Range Check Method
Posted by Chris Danielson in .Net Development on July 21st, 2009
This function is a trivial example of how to do a basic date range check in .Net. I do a few silly conversions from string to timestamp only to serve as an example.
/* Assumes the local culture. Does a check to see if the current time is within the range of 7 AM and 1 PM. If so, returns true. */ if (IsCurrentDateInRange("7:00", "13:00")) { //The current date is in range. } else { //The current date is out of range. } |
using System; /* startTime should be in the format HH:mm such as 09:45 endTime should be in the format HH:mm such as 18:45 The culture is assumed to be the local one which can be troubling in applications that extend themselves internationally. */ public bool IsCurrentDateInRange(string startTime, string endTime) { DateTime dtNow = DateTime.Now; DateTime dtStart, dtEnd; int hour = 0, minute = 0; string[] strDt = startTime.Split(new char[] { ':' }); if (strDt.Length > 1) { Int32.TryParse(strDt[0], out hour); Int32.TryParse(strDt[1], out minute); dtStart = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, hour, minute, 0); } else { //TODO: log an error in formatting. return false; } strDt = endTime.Split(new char[] { ':' }); if (strDt.Length > 1) { hour = minute = 0; Int32.TryParse(strDt[0], out hour); Int32.TryParse(strDt[1], out minute); dtEnd = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, hour, minute, 0); } else { //TODO: log an error in formatting. return false; } TimeSpan tsEndDiff = dtEnd - dtNow; TimeSpan tsStartDiff = dtNow - dtStart; if (tsStartDiff.TotalSeconds >= 0 && tsEndDiff.TotalSeconds >= 0) { return true; } else return false; } |
iPhone (SIGBUS) Issue
Posted by Chris Danielson in iPhone Development on July 20th, 2009
If you’ve ever done any iPhone development, you’ve probably had an accident with the (nonatomic, retain) methods. These methods are difficult to use in the case where you’re working with multiple threads. Our application does not do this, but we do utilize the OpenGL ES 1.1 framework. Have a look at the following console log from the other night when my brother was beta testing our application with some friends at a bar.
Process: myExampleApp [800] Path: /var/mobile/Applications/5D234CF0-1234-4E2F-9A7F-14175F39A0B6/myExampleApp.app/myExampleApp Identifier: myExampleApp Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2009-07-19 23:20:40.285 -0700 OS Version: iPhone OS 3.0 (7A341) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Codes: KERN_PROTECTION_FAILURE at 0x00000008 Crashed Thread: 0 Thread 0 Crashed: 0 libobjc.A.dylib 0x30011940 objc_msgSend + 20 1 libobjc.A.dylib 0x3001313c objc_setProperty + 160 2 myExampleApp 0x000126e6 -[GameUIView setBasicObj:] (GameUIView.m:36) 3 myExampleApp 0x0000f694 -[GameUIView setupView] (GameUIView.m:404) 4 myExampleApp 0x0000ec42 -[GameUIView start] (GameUIView.m:173) 5 myExampleApp 0x00002816 -[CoreViewController playGame] (CoreViewController.m:79) 6 myExampleApp 0x00005e80 -[SplashGLUIView touchesEnded:withEvent:] (SplashGLUIView.m:606) 7 UIKit 0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520 8 UIKit 0x309a5464 -[UIWindow sendEvent:] + 108 9 UIKit 0x30936e3c -[UIApplication sendEvent:] + 400 10 UIKit 0x30936874 _UIApplicationHandleEvent + 4336 11 GraphicsServices 0x32046964 PurpleEventCallback + 1028 12 CoreFoundation 0x30254a70 CFRunLoopRunSpecific + 2296 13 CoreFoundation 0x30254164 CFRunLoopRunInMode + 44 14 GraphicsServices 0x3204529c GSEventRunModal + 188 15 UIKit 0x308f0374 -[UIApplication _run] + 552 16 UIKit 0x308eea8c UIApplicationMain + 960 17 myExampleApp 0x000020b6 main (main.m:14) 18 myExampleApp 0x0000202c start + 44 |
The core method here that is the issue is implemented as:
//in the .h file. @property (nonatomic, retain) NSObject *basicObj; //in the .m file. @synthesize basicObj; - (void)setupView { if (self.basicObj != nil) { [self.basicObj release]; self.basicObj = nil; //line 404, this is where the error is located. } } |
As you can see, the issue appears to be based on how we access the basicObj object. The definition of a SIGBUS error, is pretty straight forward. We are generically having some sort of memory issue.
As of this writing, I’m still doing extensive testing and I’ll update this post if I find a better solution. Here is what I’ve found to work. I’m beginning to wonder if there is a funny timing issue with the “release” methodology. I’ll make sure to post back here if I find there to still be an issue or I find a better solution. Comments are appreciated.
- (void)setupView { if (self.basicObj != nil) { [basicObj release]; basicObj = nil; } |
I'm a software developer focused on all facets of enterprise solutions and technologies. Currently, I'm enjoying developing iPhone applications at night while spending much of my day working on Java, .Net and database implementations.
