Archive

Archive for the ‘IOS’ Category

Tardy Timer APP – Never be late for School Again

February 8, 2017 Leave a comment

Finally, got tired of the fragmented mobile market and decided to learn IONIC. In a month, here is my first app and it was a great learning experience.

Here is the link: https://itunes.apple.com/us/app/tardy-timer/id1199682959

 

Categories: IOS, Uncategorized Tags:

Upgraded Xcode and now it can’t find

February 14, 2013 Leave a comment

So, I upgraded XCode to 4.6 some time back and now it stops compiling my project. I am using Matt Gemmell’s twitter engine and it uses xmlreader.h. I checked my header search paths, then I checked my linker settings and found that libxml2.dylib was missing, so I removed it added it back again. But still no luck!

This is what fixed it for me finally.

  1. in XCODE go to Project–>Target–>Build Settings
  2. In the search box, type “header search paths”
  3. Either add or update libxml settings to $(SDKROOT)/usr/include/libxml2.

That should fix it!

Categories: IOS, XCode Tags:

Initial GPS fix always incorrect : Corelocation, CLLocationManager

June 28, 2011 7 comments

The Problem:

You use CLLocationManager.StartUpdatingLocation( ) to get an initial fix on the user’s location in your code. But you notice that the location is always wrong and way-off.

Analysis:

Take a look at Apple’s own documentation of CLLocationManager here : (link to documentation)

Because it can take several seconds to return an initial location, the location manager typically delivers the previously cached location data immediately and then delivers more up-to-date location data as it becomes available. Therefore it is always a good idea to check the timestamp of any location object before taking any actions. If both location services are enabled simultaneously, they deliver events using the same set of delegate methods.

Basically, IOS returns you previously cached information. This could also mean that if you used Corelocation in San Francisco today and then used the app in Dallas next, it will still report your location in San Francisco.

Solution:

In my code below, I have used two ways of making sure I have the correct location. One is to make sure horizontalAccuracy is < 100 meters and the next is the location timestamp is < 15 seconds ago. If it falls under any of these two conditions, the location is probably wrong and can be discarded. In this case I just wait for IOS to give me a fresher more accurate location fix.

Point to be noted here is that because of this, be prepared to wait for upto 10 seconds depending on how accurate the location info you want to get. More accurate = more delay especially after a cold start. Chances are, if you are not writing a GPS turn-by-turn navigation app, you don’t need pin-point location info. So, play around with it and relax the accuracy as much as possible depending on what fits your app’s scenario.

– (void) locationManager:(CLLocationManager*) manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
{
@try
{
if(newLocation.horizontalAccuracy > 100)
{
NSLog(@”Ignoring GPS location more than 100 meters inaccurate :%f”, newLocation.horizontalAccuracy);
return;
}

NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0)
{
NSLog(@”Ignoring GPS location more than 15 seconds old(cached) :%d”, abs(howRecent));
return;
}

[myLM stopUpdatingLocation];
}
@catch (NSException* ex)
{
[self debugMessage:ex.reason withTitle:@”Uncaught Error in didUpdateToLocation()”];
}
}

Downgrade from iOS5 to iOS 4.3.3

You are an iOS developer and obviously you downloaded and upgraded your iOS device to iOS5 beta the day Apple announced it on 6th June. At least I did. Really liking lot of the new features in iOS 5 now.

But if for any reason you want to go back to 4.3.3, Apple says you can’t do that. Not true! It is extremely easy :

  1. Download the iOS 4.3.3 IPSW file for your device from here
  2. Connect your device to iTunes on your computer
  3. In iTunes simply click (Mac) OPTION + Restore button. I believe on Windows it is Option = Shift or Alt.
  4. Browse to the IPSW file and and hit restore. Thats it !!!

How to detect /handle changes in network from 3G to Edge to Wifi in your IOS apps

June 21, 2011 2 comments

The Problem :

You want to detect in your iOS app if the user is on Wifi, 3G or Edge for some reason. Maybe your app downloads large amounts of data or streams media and you want to make sure that the appropriate signal is available for the operation

Also, you would like to detect any changes in the network as well. eg. when your app starts, the user is on wifi, which is awesome for your media rich app, but then he moves into 3G network and you want to take an action based on this change.

The Solution :

Apple has been nice enough to create a complete sample for us. It is called Reachability (Apple link). Here is the gist of it :

in .h file:

// declare Reachability, you no longer have a singleton but manage instances 
Reachability* reachability; 

in .m file:

[[NSNotificationCenter defaultCenter] addObserver:self selector:(handleNetworkChange:) name:kReachabilityChangedNotification object:nil]; 
reachability = [Reachability reachabilityForInternetConnection]; 
[reachability startNotifier]; 
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus]; 
if(remoteHostStatus == NotReachable) 
{
NSLog(@"no");
} 
else if (remoteHostStatus == ReachableViaWiFiNetwork) 
{
NSLog(@"wifi"); 
} 
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) 
{
NSLog(@"cell"); 
} 
..... 

- (void) handleNetworkChange:(NSNotification *)notice 
{   
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];   
if(remoteHostStatus == NotReachable) 
{
NSLog(@"no");
}   
else if (remoteHostStatus == ReachableViaWiFiNetwork) 
{
NSLog(@"wifi"); 
}   
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) 
{
NSLog(@"cell"); 
} 
} 

How to add an iPAD UIPopoverController style floating menu to your iPhone/iPod app

June 16, 2011 1 comment

The Problem :

You love that cool UIPopoverController class that Apple has added to the iPad. But wait a minute, why is it not there on an iPhone or iPod ????

I have no freakin idea!! But the developer community comes to rescue at times like this.

The Solution :

Enter WEPopover (github link) by Werner Altewischer. I believe he is from Netherlands. His simple yet effective implmentation will give you an almost UIPopoverController replica. Check out the github link for source code and example project. Have fun and Thanks Werner !

How to check for Network Connection in your IOS apps

June 16, 2011 4 comments

The Problem :

IOS apps need to handle network connectivity very carefully. An iOS user may travel from a Wifi connection to a 3G connection to a dead spot all while using your app. For this reason, Apple is extremely strict about developers handling network connectivity problems elegantly. They will outright reject your app if it errors out due to no network.

Why doesn’t Apple do it for me? 

Since this is such a common requirement, you must be wondering why IOS (even IOS5) doesn’t handle this for the app. All Apple has to do is allow developers to add a .plist setting called “NetworkRequired=1” and iOS should handle the error for you. Since, all network calls will go through iOS SDK stack, it should be able to catch the errors right?

The most obvious reason that comes to my mind about why they want you to handle the issue is – Only your App knows what to do when a network failure occurs.

  • Maybe the network failure is something which you don’t care about and the app can continue working.
  • Maybe it is a critical error and you need to notify the user about it.
  • Maybe your app can afford to retry the operation based on the nature of the network API call.

So, it makes sense for your app to handle the network issues.

The Solution :

So, the solution is very simple. First make sure that you have a helper class that you use to make every single network/API call. This way the network/API code is in one place. Easier to maintain and easier to add error handling.

In Loqly (iTunes Link), we use the below two functions to check for internet.

  • (BOOL) connectedToNetwork  is used when we just want to check for a network connection and not notify the user if an error occurs.
  • (BOOL) checkInternet is the same but automatically shows user an error message to notify him if no internet connection is present.

There is no rocket science here. In fact this code is available in one of Apple’s own samples and we have just used it in our app.

- (BOOL) connectedToNetwork
{
	Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
	NetworkStatus internetStatus = [r currentReachabilityStatus];
	BOOL internet;
	if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN)) {
		internet = NO;
	} else {
		internet = YES;
	}
	return internet;
} 

-(BOOL) checkInternet
{
	//Make sure we have internet connectivity
	if([self connectedToNetwork] != YES)
	{
		[self showMessage: @"No network connection found. An Internet connection is required for this application to work"
				withTitle:@"No Network Connectivity!"];
		return NO;
	}
	else {
		return YES;
	}
}

Someone has answered this question in great detail on Stackexchange as well
WARNING: As must be obvious from the above,  don’t use the IP address of a user to uniquely identify him for any purpose. Since the user could travel from wifi to 3G to edge to another wifi in minutes, his IP is likely to keep changing. UDID is a good option for this.