Archive for the ‘iOS Development’ Category

I’ve recently been playing around with delegates and protocols and figured, it might be a good idea to create a simple example. The following article will show you, how you could implement a custom delegate into your own XCode project.

First, why would you want to do this? Well, there are a number of reasons. For instance, picture this: You have a class, that takes care of some calculations. Depending on how complicated these are, they can take up more or less time. Once the calculations are done, you want to send a feedback message to the class, that triggered the process. Using a custom delegate will allow you to receive that message without implementing the calling class into your calculations class. The big advantage is, that you will be able to use your calculations class in any class, send feedback message through the delegate and keep your code nice and clean.

Let’s get started, shall we?

In my sample project, I start off with a “View-based Application” template. It will give me the basic view hierarchy I need and I can get right to the fun part :)

I create a new “Objective-C” class (subclass of NSObject), name it “DelegateClass” and add it to my project. I now got two new files: DelegateClass.h and DelegateClass.m. Now I can start creating my delegate right away.

First, I want to add a protocol for my delegate. The protocol will contain the feedback method:

@protocol MyCustomDelegate <NSObject>

- (void)delegateSentFeedback;

@end

Now, I create an instance of my delegate inside @interface:

@interface DelegateClass : NSObject {
    id<MyCustomDelegate>    delegate; //create instance
}

I also need a method, that will do something. Therefore I name it “doSomething”:

- (void)doSomething;

Finally, I add @property for the delegate, so it can be assigned from any class:

@property (assign) id<MyCustomDelegate> delegate; //@property, so delegate can be assigned from any class #importing "MyCustomDelegate.h"

Inside DelegateClass.m I need to do two things:
Synthesize the delegate:

@synthesize delegate;

and add the doSomething method:

- (void)doSomething {
    if (delegate != nil && [delegate respondsToSelector:@selector(delegateSentFeedback)]) { //only trigger method IF delegate has been assigned and the method has been implemented into the target class

        //do something and then send callback message
        for (int i = 0; i < 10000; i++) {
            printf("I'm busy, I'm doing something");
        }
        [delegate performSelector:@selector(delegateSentFeedback)];
    }
}

The IF-Statement will make sure, that the delegate has been assigned from the calling class and that the calling class will implement the feedback method, named “delegateSentFeedback”.
Now, I move over to my viewController. I add a UIButton to start some process upon “TouchUpInside”. I connect it to an IBAction and end up with something like this:

- (IBAction)startProcessAction:(id)sender {
    DelegateClass *class = [[DelegateClass alloc] init];
    class.delegate = self; //IMPORTANT: if you don't assign the delegate, the feedback method will NOT be triggered!
    [class doSomething]; //start process
    [class release];
}

Btw, let’s not forget to #import “DelegateClass.h” into our ViewController’s .h file!
Last, but not least I implement the delegate feedback method, defined inside DelegateClass.h

- (void)delegateSentFeedback {
    //the process is done. let's show a simple UIAlertView
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"The process is done! Delegate has successfully sent feedback" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
}

The feedback method will show an UIAlertView, once “doSomething” method inside DelegateClass.m has reached the bottom.
Piece of cake, right?


Feel welcome to grab the sample project here, play with it, add new feedback methods and most importantly HAVE FUN! :)









I’ve recently been working on an app for the iPad and ran into some strange issue, when using a modalViewController. In my case, I wanted the modalViewController to show up right after the app finished launching. I also had a pretty basic viewController setup, similar to the one you get when using the “View-based Application” template.

Inside my rootViewController I wanted to call some other viewController as modalViewController right after start up. It looked pretty much like this:

- (void)viewDidLoad {
    [super viewDidLoad];

    //instantiate otherViewController and call it as modalViewController
    OtherViewController *viewController = [[OtherViewController alloc] initWithNibName:@"OtherWindow" bundle:nil];
    self.otherViewController = viewController;
    [viewController release];

    [self presentModalViewController:otherViewController animated:YES];
}

Unfortunately, when I tested my app nothing happened. The reason why no errors or warnings were shown was simple: The code was fine.
So, what was the problem then? After doing some investigation I found out, that the modalViewController didn’t like being called directly from viewDidLoad. Instead I had to call it with just a tiny bit of a delay.

So, I added a new method to my class:

 

- (void)callOtherViewController {
    if (otherViewController == nil) { //only allocate, if it has not been allocated yet
        //instantiate otherViewController and call it as modalViewController
        OtherViewController *viewController = [[OtherViewController alloc] initWithNibName:@"OtherWindow" bundle:nil];
        self.otherViewController = viewController;
        [viewController release];
    }

    [self presentModalViewController:otherViewController animated:YES];
}

Finally, I only had to call this method from viewDidLoad with the delay mentioned above, like this:

- (void)viewDidLoad {
    [self performSelector:@selector(callOtherViewController) withObject:nil afterDelay:0.1f];
}

That did the trick!









UITableViews are awesome. They allow you to display a variety of information, can be customized extensively, take care of memory management and much much more. Since they only remember what’s currently on screen, getting a basic ToDo list up and running can be quite the challenging task for a rookie coder. In this post I’d like to show you how this can be achieved in just a few steps.

First, let’s get all the ingredients ready…

Basically, we need 3 things:

  1. UITableView to display stuff
  2. Data source array, that contains the stuff we want to display
  3. Dictionary, to keep track of what is checked / unchecked

On top of that, we also need:

  1. UITableViewCell to put inside our UITableView
  2. UILabel inside our UITableViewCell to display some text
  3. UIButton inside our UITableViewCell to check / uncheck this cell
Inside the .h file of the ViewController, containing my UITableView, I add the following code:
@interface TableViewCellDemoViewController : UIViewController {

IBOutlet UITableView *tableView;

NSArray *dataSourceArray;

NSMutableDictionary *checkedDictionary;

}

- (void)checkButtonTapped:(id)sender forCellWithLabel:(NSString *)text;

@property (nonatomic, retain) IBOutlet UITableView *tableView;

@property (nonatomic, retain) NSArray *dataSourceArray;

@property (nonatomic, retain) NSMutableDictionary *checkedDictionary;

@end

Inside the .m file I need to properly create the cells…

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	BaseCell *cell = (BaseCell *)[_tableView dequeueReusableCellWithIdentifier:@"BaseCell"];

	if (!cell) {
		cell = [[[NSBundle mainBundle] loadNibNamed:@"BaseCell" owner:self options:nil] lastObject];
	}

	cell.selectionStyle = UITableViewCellSelectionStyleNone;

	cell.cellLabel.backgroundColor = [UIColor clearColor];
	cell.cellLabel.font = [UIFont fontWithName:@"Helvetica" size:17];

	cell.cellLabel.text = [dataSourceArray objectAtIndex:indexPath.row];
	cell.parentViewController = self;

    //let's use the cellLabel.text as key inside our checkedDictionary. IMPORTANT: This only works, if information inside cellLabel.text is unique for every row. If you have the same text twice in your datasourceArray, this will cause to some unexpected behavior.

    NSString *key = cell.cellLabel.text;

    BOOL checked = [[checkedDictionary objectForKey:key]boolValue];

    [cell.checkButton setBackgroundImage:(checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];

	return (UITableViewCell *)cell;
}

…and add a method, that will get called, if I tap on the check / uncheck button

- (void)checkButtonTapped:(id)sender forCellWithLabel:(NSString *)text {
    UIButton *button = (UIButton  *)sender;

    //like above, we're using the information inside the label (text) as unique identifier = key
    NSString *key = text;

    BOOL checked = [[checkedDictionary objectForKey:key]boolValue];

    //depending on whether the row has been checked before or not, we write YES / NO to our checkedDictionary
    if (checked) {
       [checkedDictionary setValue:@"NO" forKey:text];
        checked = NO;
    }
    else {
        [checkedDictionary setValue:@"YES" forKey:text];
        checked = YES;
    }

    //finally set the new button background image
    [button setBackgroundImage:(checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
}

Finally, I create an empty user interface for Interface Builder and add a UITableViewCell object to it. I also create a new class, named “BaseCell” and set it as custom class for my UITableViewCell.
After adding a UILabel and UIButton object to my cell, I properly link everything and my BaseCell.h file will look like this:

#import <UIKit/UIKit.h>

@interface BaseCell : UITableViewCell {

    IBOutlet UILabel *cellLabel;
    IBOutlet UIButton *checkButton;
    UIViewController *parentViewController;
}

- (IBAction)checkButtonAction:(id)sender;

@property (assign) IBOutlet UILabel *cellLabel;
@property (assign) IBOutlet UIButton *checkButton;
@property (assign) UIViewController *parentViewController;
@end

Last but not least, the .m file will make a call to “checkButtonTapped” method inside my UITableViewController’s class like this:

- (IBAction)checkButtonAction:(id)sender {
    if (self.parentViewController) { //call method inside TableViewCellDemoViewController and submit the sender object (= button) and the text inside the label. We will use the text as unique identifier (=key) inside our checkedDictionary (also part of TableViewCellDemoViewController class)
        [self.parentViewController performSelector:@selector(checkButtonTapped: forCellWithLabel:) withObject:sender withObject:[self.cellLabel text]];
    }
}

If we break down the steps, our app will basically perform the following tasks:

  1. Set up custom UITableView cells, containing a UILabel and UIButton

  2. If user taps on the button, make a call from BaseCell class to TableViewCellDemoViewController class and submit both the sender button and text inside the UILabel

  3. Use the UILabel text to look up a matching key inside our “checkedDictionary” object

  4. Change background image of the UIButton, depending on whether (3) exists and whether it is YES or NO.

That’s it! In case you haven’t done this before, I’m sure you will be confused now. That’s why I created a demo project, so you can explore the code in more detail. Feel welcome to grab the source here.
Have fun and don’t hesitate to leave a comment :)







We’ve just finished designing / coding the new codingsessions website. Besides the new look, you’ll also find an updated list of available sessions. We’d really like to thank all our customers out there for turning this service into a success.

Those of you, who’ve never heard about Codingsessions: It’s a service for junior iOS developers to quickly develop some basic skills and use that knowledge to write their own applications.

If you have any questions about www.codingsessions.com, please feel welcome to contact us any time.

Thank you very much!

Once you’ve spent several weeks or months on developing your latest and greatest app and finally submitted it to the AppStore, the real hard work is just about to begin. Lots of developers new to the iOS business think, that it’s enough to create a solid product, but as a matter of fact it’s not. You have to understand, that once your app goes live, it’s competing against half a million apps and counting. The market became real tight and especially small teams and “one man bands” are feeling this now more than ever.

I’ve developed and released more than 40 apps in the past 3 years and therefore had my fair share of success and failure. When doing research on app marketing, I read lots of posts on various forums and talked to other developers. I soon discovered an unpleasant pattern.

Let’s assume, developer A released a product named XY and let’s also assume, that we are not talking about some useless product, like those infamous farting apps. The first day, after his product went live, our developer A checked his daily revenue report on iTunesConnect. He has sold 50 copies (which is actually quite good these days) on the first day. The next day he sold 33, then 17, then 5, then 0. Now let’s do the math: 50 + 33 + 17 + 5 = 105. Since he charged $0.99 per app, he made around 50 bucks. That’s quite bad, because he can’t even take his girlfriend out to dinner, let alone pay any bills he most certainly has.

So, what did our poor developer A make wrong? He certainly didn’t make a bad product. However, since his app got out of possible customers’ sight, it soon drowned in a sea of other great, good, ok, mediocre and bad products.

Visibility!

We need to learn from his mistake, so we’re not doomed to repeat it. It’s all about VISIBILITY. Let me say it again: VISIBILITY. Now you repeat it: VISIBILITY! That’s the key to success these days. Our product has to be visible. If not, the game is over, before it really started. It’s a well known fact, that most of the time, people make the decision whether they want to buy an app or not within milliseconds. They see it – they want it – they buy it. Since we have no control over our dear customers’ wills, the only thing we can do, is SHOW them our product. One last time: That’s VISIBILITY.

We need to draw attention to our product!

The first step towards visibility is to draw attention to our product. If we get mentioned by a blog and readers find our app interesting, they might turn into customers. In case they really like what we’ve created, they will probably tell their friends about it and those people will tell their friends and so on. In our time and age, social networks such as Facebook, Twitter, LinkedIn and similar services have become very important. We can easily connect with other people and share comments, suggestions and interests with just a single click.

It’s also a good idea to implement social features directly into your app. For example, allow people to recommend your app to friends via email or tweet about it.

Be socially active!

No matter, whether you’re developing apps as an individual or a group / company, make sure that you’re socially active. Connect with as many people as possible and maintain a clean and professional online profile. Share interesting news and updates, but avoid mixing them with the latest impressions on heavy partying. The more people you get to follow you online, the more potential customers you will find in the long run. It will also help you to find new interesting projects and make progress both personally and professionally.

Make your product stand out!

In case you do not have the money for hiring some big shot marketing company to do the heavy lifting for you, there are several things you can do, that will only require little or no investment at all:

  1. Have a meaningful and typo free product description on iTunes.

  2. Create a website for your app: You most likely already have a site, showing general information about your company and your recent portfolio. However, if you believe in your product and that’s what you really should do, a dedicated website is the way to go. In case you’re not too familiar with web development in general, you can buy a good looking web template (google iPhone web template) and modify it to fit your needs without too much hassle.

  3. If you blog about your app, post links, tweet about it, etc… make sure to link to your app website (1) and avoid sending users directly to iTunes. You have a lot more control over product placement on your own website, than on the default iTunes page. People find it more interesting to browse a unique and great looking website. They will eventually click the link on this website to open iTunes, if they like your app.

  4. Create a meaningful press release (check out PrMac)

  5. Create a video of your app and post it on YouTube or similar sites.

  6. Try to get your app reviewed: Google “iPhone app review sites” and send requests to sites, that might be interested in taking a look at your product. From experience I can tell, that most of the time you’re probably gonna get ignored. Don’t take that personally. Most big review sites receive way too many requests and so it’s like playing the lottery. Maybe you’re gonna luck out. So, giving it a shot won’t hurt. However, I can not recommend paying for reviews. Smaller sites will sometimes get back to you and offer  a review for 20 or 30 dollars. Their traffic is usually low and so you’re most likely burning your money, instead of making a useful investment. In this case stick to the press release (3).

  7. Share promo codes. Apple gives you 50 promo codes per app (version of that app) you release. USE THEM! Redeemed promo codes are treated like purchases on the AppStore. They might help you improve the ranking (VISIBILITY) of your app and also spread the word.

Keep your product alive!

Make sure to test your product as thoroughly as possible. Get family, friends or whoever you can find to use your app. Check out TestFlight – it’s an amazing service for tasks like this. If you or someone else discovers a bug, fix it! If your app is missing a feature and you can afford to implement it in a reasonable amount of time, do it! Users love a well maintained app. Product and customer care automatically generate happy users and therefore returning customers. Something, that will eventually improve the reputation and value of your company and future products.

I hope, this little insight will be helpful to fellow developers out there. Feel welcome to add comments / suggestions below, as I’m sure there is a lot more to consider. I’m looking forward to update / improve this article over time.



I’ve recently been playing around with iADs and tried to build a quick demo project, that supported both portrait and landscape orientation.

Now, getting your viewController to auto rotate to any orientation is quite simple. You implement the following method and you’re good to go:


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

// Return YES for supported orientations

return YES;

}

After that, I could rotate my iDevice and the viewController rotated along just as expected. One thing that didn’t follow the rules, was my ADBannerView, which I had previously implemented using interface builder.

Instead, console triggered the following warning: “WARNING A banner view (0x6400dd0) has an ad but may be obscured. This message is only printed once per banner view“.

I know, I was missing something here and had to dig a little deeper. After a couple minutes, I found out, that in order to get an iAD to rotate correctly, it was crucial to set its “CurrentContentSizeIdentifier”.

So, I first had to detect the current device orientation and then set the CurrentContentSizeIdentifier of my iAD to that same orientation.

In my case, I’ve been using a rootViewController and on top of that another viewController, displaying my iAD.

I added the following method to my rootViewController:


- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {

isLandscape = NO; //boolean value defined in RootViewController.h

}

else {

isLandscape = YES;

}

[_iADDemoViewController resizeIAD];

}

Finally, I added this method to my other viewController:


- (void)resizeIAD {

[iAD setCurrentContentSizeIdentifier:(mainDelegate.rootViewController.isLandscape) ? ADBannerContentSizeIdentifierLandscape : ADBannerContentSizeIdentifierPortrait];

}

Voilà, that did the trick! :)

Feel welcome to grab the demo project here.

One more thing: If you test your iADs in landscape mode (tap on the banner), you will notice that those ADs will only be displayed in portrait orientation. When you exit them, your view will be completely messed up. According to this information, that only happens in test mode and “real” iADs will get displayed correctly in landscape mode as well.

In case you’ve ever played around with a sectioned UITableView and tried to delete rows from it, you’ve most likely experienced a crash once in a while.

When you read the console log, most of the time you find an entry similar to this one:

*** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (0) must be equal to the number of sections contained in the table view before the update (1), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).’

Usually, your code for deleting stuff from your UITableView will look like this:


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) { //let's delete something from our table
//IMPORTANT - modify data source BEFORE deleting rows from the table
[mySourceArray removeObjectAtIndex:indexPath.row]; //we assume, that mySourceArray is a NSMutableArray we use as our data source

[tableView beginUpdates];

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

[tableView endUpdates];

}

Now, things can get a bit more complicated when using a sectioned UITableView. In my case, I’ve been using a NSMutableArray (filled with NSDictionaries) as data source.
It looked like this:

NSMutableArray ->

……….-> NSDictionary:

………………..-> “headerTitle”: “A”

………………..-> “rowValue”: “RowValue1″, “RowValue2″, etc…

………..-> NSDictionary:

…………………-> “headerTitle”: “B”

…………………-> “rowValue”: “RowValue1″, “RowValue2″, etc…

etc,…

As you can see, a datasource like that is just a bit more complex than values directly inside a NSMutableArray.

In order to avoid the crash mentioned above, I had to make sure, that I only deleted rows from my table, when there were still OTHER rows left inside the same section. In case the row I wanted to remove was the last one within a section, I had to remove the entire section. Btw, that’s exactly what the crash log said :)

Here is my method again, this time with the needed modification:


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) { //let's delete something from our tableNSDictionary *dict = [mySourceArray objectAtIndex:indexPath.section];

NSArray *array = [dict objectForKey:@"rowValue"];

int arrayCount = [array count]; //get the current count of the array
if(arrayCount == 1){ //we are removing the last item from this section - remove the ENTIRE section!

[tableView beginUpdates];

[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
    [tableView endUpdates];
}
else { //just delete the row, since we've got more rows left inside this section
    [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [tableView endUpdates];}

}

Hope, you find this helpful. Feel welcome to leave a comment.

Cheers.



Hello everyone,

I’ve recently checked out a new (currently free) service, named “TestFlight“. It easily allows you to send out beta builds to your testers, who can then install your apps WITHOUT iTunes. Sounds just awesome! Before I started to distribute via Testflightapp.com, I used Dropbox. Way before that, I used my MobileMe iDisk. Now, I still put builds into my Dropbox, because syncing has never been easier and you can share an entire folder or just a single file with only a couple clicks.

However, TestFlight fits my needs way better. They allow me to upload a signed .ipa archive of my app, add release notes and then share it with my beta testers. Their server automatically detects, if people who are on my list have already signed up with TestFlight or not. In case they already got an account, I can see their names and simply select those, I want to include in testing a specific build. It’s really cool.

Of course there are always a couple things that can be improved and I’m sure the guys over at TestFlight are already on it. According to their website, they are about to release some sort of SDK in the near future and they are also working on a desktop application. So, lots of good things seem to come our way :)

When I created my TestFlight account, I wanted to do a quick test with one of my apps and see, how it performed. Both uploading and sending out information to my testers worked like a charm. However, when my testers tried to download and install the app “on the fly” (without iTunes), they ran into issues. Once the download had been completed, a dialog popped up and said “App could not be installed”. Bummer, what went wrong? Well, first it was not TestFlight’s fault. As usual, there had been an issue with code-signing.

If you have been developing for iOS for quite some time, we probably share the same experience about code-signing. It’s not very straight forward and it can be quite painful sometimes to actually get it to work.

Here are a few things I’d like to bring to your attention, in case you run into the same or similar issue when using TestFlight:

  1. FOLLOW their tutorials on creating a code-signed .ipa archive: XCode3, XCode4
  2. The tutorial above tells you to create a new AdHoc profile. DO IT :) Even if you already got a similar profile. DO IT!
  3. If you add a new member to your device list on Apple’s provisioning portal and then download a new certificate, I recommend to repeat the steps above. Simply delete your existing AdHoc profile and set up a new one.
  4. Always restart XCode after importing a new certificate into iTunes.

Paying attention to these little things finally helped me to get TestFlight up and running. It now works great and my testers just love it!

In case you run into (similar) issues and the above does not work for you, feel welcome to visit TestFlight’s support website and join the discussion.

One more thing…”on the fly” installation only works on iOS 4.x (and hopefully above)

Sometimes it’s crucial in your app, that you know whether your users are connected to a wireless network (EDGE, 3G, WiFi) or not.
I’ve been using the following snippet quite a lot in the past and thought, maybe someone might find it useful too.

In order to get this to work, you need to follow these steps:

1) Import the “SystemConfiguration.framework” framework into your app.

2) Add the following lines into the .m file of the class, you want to make the calls from (right below your #import lines):

#include <netinet/in.h>
#import <SystemConfiguration/SCNetworkReachability.h>

3) Finally add a new method to your class:

- (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)
	{
		NSLog(@"Error. Could not recover network reachability flags");
		return 0;
	}
	BOOL isReachable = flags & kSCNetworkFlagsReachable;
	BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
	return (isReachable && !needsConnection) ? YES : NO;
}

3a) Same method, but with updated code as suggested by Ariel in comments below

<pre>- (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)
	{
		NSLog(@"Error. Could not recover network reachability flags");
		return 0;
	}
	BOOL isReachable = flags & kSCNetworkFlagsReachable;
	BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
//below suggested by Ariel
	BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
        NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"]; //comment by friendlydeveloper: maybe use www.google.com
        NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
        //NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:nil]; //suggested by Ariel
        NSURLConnection *testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest delegate:nil] autorelease]; //modified by friendlydeveloper
        return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;</pre>
}

Now, you can easily check, if there is a network connection or not, like:

if ([self connectedToNetwork]) {
//yes we're connected
}
else {
//no we're not connected
}

Hope, you enjoy it.
Feedback always welcome…

Hello everyone,

I’ve recently been playing with UILocalNotifications and really love them. When Apple first introduced Remote notifications (aka. push notifications), they were a real treat to both developers and users. Applications could receive information, even though they were not running at that time. However, it was (still is) a bit painful to implement them. You need to create certificates, run your own server or sign up with some company, that does the message forwarding for you.

Now, in case you only want to remind your users of something or allow them to schedule an event inside your app, UILocalNotifications are what you’ve been looking for. They are quite easy to set up and you don’t have to hassle with certificates, etc…

I’ve decided to release a little class, that easily allows you to schedule an event, delete a specific event or simply delete all events.

Ok, here we go:

My UILocalNotificaionsWrapper class consists of 3 different methods:


+ (void)addLocalNotification:(int)year:(int)month:(int)day:(int)hours:(int)minutes:(int)seconds:(NSString*)alertSoundName:(NSString*)alertBody:(NSString*)actionButtonTitle:(NSString*)notificationID;

+ (void)cancelLocalNotification:(NSString*)notificationID;

+ (void)cancelAllLocalNotifications;

The first method is the most complex one and allows you to submit several different values to customize your notification event:

  • year (integer) – e.g. 2011
  • month (integer) – e.g. 4 (April)
  • day (integer) – e.g. 29
  • hours (integer) – e.g 10 (= 10 am) – use 22 (military time) for 10 pm
  • seconds (integer) – e.g. 0
  • alertSoundName (NSString) – . e.g. nil to use custom sound name or @”NameOfTheSoundInsideYourAppBundle.wav”
  • alertBody (NSString) – e.g. @”This is a LocalNotification”
  • actionButtonTitle (NSString) – e.g. @”view” – This will appear on the button, when your local notification fires
  • notificationID (NSString) – e.g. @”12345″  (has to be unique. you could keep track of your IDs inside an array, dictionary or SQLite database

Now you can simply make a call like this to schedule a new event:


[UILocalNotificationWrapper addLocalNotification:2011 :4 :4 :19 :17 :0 :nil :@"This is a LocalNotification!":@"View":@"12345"];

In order to delete the notification you just scheduled, you could make a call like this:


[UILocalNotificationWrapper  cancelLocalNotification:@"12345"];

Finally, to delete all scheduled notifications:


[UILocalNotificationWrapper cancelAllLocalNotifications];

One more thing…

Don’t forget to add #import “UILocalNotificationWrapper.h” inside the class you are making the calls from and always test on your device (UILocalNotifications don’t work on the simulator)

Grab the source file here and enjoy :)

Feedback always welcome.

 

An App, you might like:
We recommend…
You might also like…
Get Adobe Flash playerPlugin by wpburn.com wordpress themes