JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Accessing the UIAccelerometer in Iphone and iPad

May 30, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iPhone and iPad in Action, published on August, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

Accessing the UIAccelerometer

Introduction

When you’re using the iPhone’s orientation notification, the frameworks are doing the work for you: they’re taking low-level acceleration reports and turning them into more meaningful events. It’s similar to the concept of iPhone actions, which turn low-level touch events into high-level control events.

Notifications aren’t going to be sufficient if you would prefer to program entire interfaces that effectively use the iPhone’s movement in three-dimensional space as a new user-input device. For that, you’ll need to access two iPhone classes: UIAccelerometer and UIAcceleration. We’ll talk about UIAccelerometer.

The UIAccelerometer is a class that you can use to receive acceleration-related data. It is a shared object, like UIApplication and UIDevice. The process of using it is shown in listing 1.

Listing 1 Accessing the UIAccelerometer takes just a few steps
[code]- (void)viewDidLoad {
UIAccelerometer *myAccel =
#1
[UIAccelerometer sharedAccelerometer]; #1
myAccel.updateInterval = .1; #2
myAccel.delegate = self; #3
[super viewDidLoad];
}
#1 Creates shared accelerometer
#2 Updates 10 times a second
#3 Delegates accelerometer protocol[/code]
The first step is to access the accelerometer, which is done with another call to a shared-object method (#1). Having this step on its own line is probably unnecessary, because you could perform the other two steps as nested calls, but we find this a lot more readable.

Next, you select your update interval (#2), which specifies how often you’ll receive information on acceleration. This is hardware limited, with a current default of 100 updates per second. That’s most likely just right if you’re creating a game using the accelerometer, but excessive for other purposes. We’ve opted for 10 updates per second, which is an updateInterval of 0.1. You should always set the lowest acceptable input to preserve power on the iPhone.

Finally, you must set a delegate for the accelerometer (#3), which is how you receive data on accelerometer changes. The delegate will need to respond to only one method, accelerometer:didAccelerate:, which sends a message containing a UIAcceleration object whenever acceleration occurs (to the limit of the updateInterval).

Summary

The iPhone’s accelerometers can give you access to a variety of information about where an iPhone exists in space. By measuring gravity, you can easily discover an iPhone’s precise orientation. By measuring movement, you can see how an iPhone is being guided through space. Finally, you can build more complex movements into three-dimensional gestures, such as the shake.

Accelerometers allow users to make simple adjustments to a program. We can imagine game controls and painting programs both built entirely around the accelerometers.

Filed Under: Apple Tagged With: iPad, iPhone

Adding a map to an application in iPhone and iPad

May 30, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iPhone and iPad in Action, published on August, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

Adding a map to an application

Introduction

Adding a map to any application is very similar to adding any other view. You can either do it through Interface Builder or programmatically. The choice is up to you depending on how you like to work with UI elements. We will show you both methods.

The view that displays a map is called MKMapView. This class contains quite a bit of functionality including how to display the map, annotations, and user location. We will first be discussing how to add an MKMapView through Interface Builder. Once we add the map to the view, we will connect it to an IBOutlet and set its delegate class.

Adding the map using Interface Builder

Before you start coding the MKMapView, you must first import MapKit.framework. This will provide you will all of the libraries needed to work with maps.

To add a map to your view, your must first create an MKMapView IBOutlet in the class that will be using the map. Listing 1 shows how to do this.

Listing 1 Declaring an IBOutlet for an MKMapView
[code]#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface SimpleMapViewController : UIViewController<MKMapViewDelegate> {
IBOutlet MKMapView * theMap;
}[/code]
@property (nonatomic, retain) IBOutlet MKMapView * theMap;
The first thing we want to point out is you must import the MapKit.h header file. This is included in MapKit.framework and is needed for all MapKit interaction. The second is, our class implements the MKMapViewDelegate interface. It will allow this class to become the delegate of the MKMapView and receive messages from it. In addition to making a property, you should also synthesize the map property in the .m file.

Now that the IBOutlet has been declared, you need to add the MKMapView to the view in the nib file. To do this open up the nib file associated with the class that contains your IBOutlet. Now, select MKMapView from the Library and drag it on to your view. Figure 1 shows what this object should look like.

Figure 1 Adding an MKMapView to your viewWhen you drag the map on to you view, you are able to move and resize it however you like. Now that it has been added, you must connect it to the IBOutlet. To do this, click on the File’s Owner object and open the Connections Inspector. Now, drag from the map outlet to the map view to make the connection.

The last thing that needs to be done is set the delegate of the MKMapView. To do this, right click on the map and drag to the File’s Owner object. It should pop up a bubble that reads, “delegate”. Click the word delegate to make the connection. Figure 2 shows what the Connection Inspector should look like after you have completed all of these steps.

Figure 2 Connection inspector for the MKMapView connectionsAs you can see, adding an MKMapView using Interface Building is about the same as adding UILabels, UITextFields, and other view elements. Now that you have seen how to add the map visually, we will show you how to add one programmatically.

Adding the map programmatically

As noted before, whether you add the map using Interface Builder or with code is up to you. It is completely dependent on your preferences and organization technique. Listing 2 demonstrates how to add an MKMapView to your view controller’s view using code.

Listing 2 Adding an MKMapView programmatically
[code]- (void)viewDidLoad {
[super viewDidLoad];
MKMapView * map = [[MKMapView alloc] initWithFrame:
CGRectMake(0, 0, 320, 480)];
Map.delegate = self;
[self.view addSubview:map];
}[/code]
This code is actually quite short. We create the map using a frame, set its delegate to our class, and add it to our class’ view. As with any other view, modifying the frame passed to the map will alter its size and position.

Controlling the map

By default, the map has gives the user a bit of control. Without any additional code, they have the ability to scroll all over the world by flicking the map. Also, the map comes with the ability to zoom in and out by using the pinch and pull gestures.

To navigate the map programmatically, you must specify a region. Doing this will allow you to move the map to a specified location. You will also have the ability to set the zoom level.

Let’s examine the region properties and methods for navigating the map. Table 1 discusses these properties and methods and their uses.

The code below shows you how to create an MKCoordinateRegion and move the map to display it on the screen. The method we created here fires when a user presses a button titled Apple. It will move the map from its current location to center on Apple’s headquarters in Cupertino.

Listing 3 moving the map to a given location
[code]- (IBAction) apple:(id) sender {
CLLocationCoordinate2D coords;
coords.latitude = 37.33188;
coords.longitude = -122.029497;
MKCoordinateSpan span = MKCoordinateSpanMake(0.002389, 0.005681);
MKCoordinateRegion region = MKCoordinateRegionMake(coords, span);
[theMap setRegion:region animated:YES];
}[/code]
The first thing we see here is a CLLocationCoordinate2D being created. This is simply a struct that holds two doubles for latitude and longitude. Next, we assign them to the coordinates of Apple using the WGS 84 reference frame.

Following the coordinates, we create a span using the MKCoordinateSpanMake method. An MKCoordinateSpan is a struct made of two doubles that represent a delta for latitude and longitude. The span represents the amount of area to view and is used when setting the zoom level. A larger number here tells the map to show a larger view area resulting in the map zooming out. Similarly, a smaller number tells the map to show less area and causes it to zoom in.

Once the coordinates and span have been initialized, we can create a region using the MKCoordinateRegionMake method. Finally, we set the region of the map to our newly created one and animate the transition. In addition to controlling the map’s location, you can also control how the user can interact with it. Table 2 details these properties.

As mentioned above, the mapType property allows you to display the map in three different ways. Most likely, you will want to make this configurable by the user, as preferences tend to vary about how the map should display. Figure 3 shows the difference between the map types.

Figure 3 mapTypes: (from left to right) MKMapTypeStandard, MKMapTypeSattelite, MKMapTypeHybridAs you can see, you have quite a bit of control over how the map looks. The standard map view looks very much like a road map that you would use for navigation. This is often the most useful of the map types.

The other two are quite similar. The only difference between them is the hybrid view contains the road names in addition to displaying the satellite photos.

Filed Under: Apple Tagged With: iPad

Preparing your application to use push notifications in iPhone and iPad

May 30, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iPhone and iPad in Action, published on August, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

Preparing your application to use push notifications

Introduction

Leave it to Apple to make the preparation more complex than the coding. You will find that more time is spent on creating an uploading the signing certificates than actually writing the code to receive the push notifications. We will explain how. Let’s begin by setting up the signing certificates.

Setting up your application certificate

The first thing to note is that you must have a valid Apple developer account to test push notifications. We will be showing you how to generate two items that are required. The first item we will be generating is a special provisioning profile. This profile will be used to sign the application when deploying it to your iPhone. The second is a client SSL certificate. The push provider will use this to establish a connection with Apple’s push notification servers.

Start by logging into your Apple developer account. Once you have logged in, open up the program portal and navigate to the App IDs tab. If you haven’t already done so, you will need to add your application bundle identifier to this list. The format for this should be reverse domain. An example of this might be com.rightsprite.pushtest. Make sure that you don’t use any wildcards because the system must be able to uniquely identify your application.

Once you have added your application, you must now configure it to receive push notifications. You have the option to configure the app for development as well as production. It is always good practice to use the development certificate when testing and switch to the production one when you are ready to submit to the app store. Figure 1 shows what this section should look like.

Figure 1 Configuring the app to receive push notificationsAfter pressing the Configure button, the following screen gives you the option to configure either the development or the production certificate. For this example, we will be configuring the debug certificate; however, the steps for both are exactly the same. Figure 2 shows what this process looks like.

Figure 2 The wizard for creating a push certificateClicking Configure will open up a wizard with steps that will guide you through the process. This process is very similar to creating any other provisioning profile. After completing this step, you need to download this certificate and install it in your keychain by double-clicking on it.

Setting up you provisioning profile

Now that we have created the signing certificate, we will need to create the provisioning profile to allow the application to be installed on your iPhone. Again, you don’t want to use your generic developer certificate. You must generate a new one that is specific to your app’s full bundle id.

Go to the Provisioning tab. Since we created a push certificate for debug, we must also create a debug provisioning profile. Had we created a production certificate, you would need to create an app store or adhoc certificate. Click on the New Profile button within the Development tab.

As you may have seen before, there are quite a few options that need to be set up. The first is the profile name. This can be anything you want; however, your best bet is to be very descriptive. Name it something like [Application Name] Debug. Next, you will select the certificate that the profile will be using.

If you are a single user, you should only see your certificate in the list. However, if you are on a team, you should see a certificate for every one of your team members. Just check the boxes of the teammates that will be testing the push notifications. Note that when creating a build for the app store, you will select your distribution certificate.

Following the certificate, you will need to select the app id that the profile will be used for. Finally, you must select the devices that the provisioning profile will work on. Figure 3 shows an example of what this form looks like completed.

Figure 3 Provisioning profile formAfter creating this profile, you will need to download and install it. That is about it for the certificate creation. We will now be discussing how to implement the methods in your client application to enable and receive push notifications.

The code for handling push notifications

As we mentioned earlier, the code to handle push notifications is quite simple. In fact, there are only three methods that need to be implemented. We will be walking through each of these methods and discussing their use.

The first method is the applicationDidFinishLaunching method. This method is already implemented for you in any application that you create. You simply need to add one line of code that will tell your application to register for push notifications. The following code shows you how to do this.
[code]- (void)applicationDidFinishLaunching:(UIApplication *)app {
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:( UIRemoteNotificationTypeAlert
|UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}[/code]
Your application will have other setup tasks in this method; we just wanted to show you the line of code that must be added to register for push notifications. The code above will tell the device that this application wants to receive push notifications in the form of alerts, badge numbers, and sounds. You can omit any of these properties if you choose not to send them.

One thing you might be wondering is why this must be done more than once. The reason for this is the token that gets generated when setting up push notifications is not guaranteed to be the same. So, we want to touch base with Apple every time the application launches to make sure everything is correct to receive notifications.

As you may have guessed, there are some delegate methods that must be implemented to react to events generated by this registration call. The code below shows a simple implementation of these methods.
[code]didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
[self sendProviderDeviceToken: devToken];
}
– (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Error in registration. Error: %@", err);
}[/code]
The first method fires upon successful registration for push notifications. When you register to receive push notifications, your application communicates with Apple and receives back a unique device token. This token is used in all push communication with your device.

Notice we call a method sendProviderDeviceToken in our class. This is a custom method you should create to send the device token to your push provider. You may do this via a web service interaction.

The method didFailToRegisterForRemoteNotificationsWithError is for error handling. It fires when you get an error registering for push notifications. Most likely, if this method gets called, your signing certificate is invalid or the device doesn’t have an Internet connection. Make sure you put some code in this method to notify the user that there was a problem registering for notifications and they will not receive any at this point.

Now that the application has registered to receive push notifications, the next step is to handle them when they come in. Apple gives us a few methods that will allow us to control what happens when the user presses the View button on the notification alert.

The first way of handling an incoming push notification is to simply implement the code in the applicationDidFinishLaunching method. You would want to go this route if the notification was just used to open the application and did not pass any additional data. The following code shows a simple way to respond.
[code]
– (void)applicationDidFinishLaunching:(UIApplication *)application {
application.applicationIconBadgeNumber = 0;
[self getUpdatedDataFromServer];
}[/code]
The first and most important thing you must do here is reset the badge number to 0. If you don’t do this, the badge count will stay at whatever number was sent by the push notification. After that, you should perform any updates that are needed. In the above code, we assume that some data has changed on the server and call a method to download the updated data.

If the notification contains a custom dictionary, you must use the application:didFinishLaunchingWithOptions: method. The options variable will be an NSDictionary containing the custom values passed in.

In the event that the user is currently running the application, you must implement the application:didReceiveRemoteNotification: method. It will be called automatically and passed a dictionary containing all of the standard information including badge number, message, sound, and any custom dictionaries that were sent to the device.

After implementing the aforementioned methods, your application should now be ready to receive push notifications. One final step in preparation is to format any audio files that will be played in response to a push notification.

Preparing audio files

As noted before, when a push notification is received, it can invoke the playback of an audio file included with your application. There are many interesting scenarios for when different audio files might be appropriate. One example might be during a chess match. If a player receives a notification informing them it’s their turn, the system might simply play the default audio file. However, if they receive a notification related to a piece being captured, the system might play some sort of battle sound effects. The more creative you get with this, the more value it may add to your application.

The first thing to note when considering the audio file to play is that the file must be stored in your application’s main bundle directory. This is just the root folder that your applications files are stored in. Your audio file must be in the format of aiff, wav, or caf and limited to 30 seconds. In order to convert the audio file to one of these formats, you must use the afconvert command on you Mac. To do this, open the Terminal and navigate to the directory of the audio file you wish to convert. Next, type the afconvert command followed by -f caff -d LEI16 {INPUT} {OUTPUT}. The following shows an example of using this command to convert the file track2.mp3 to track2.caf.
[code]/usr/bin/afconvert -f caff -d LEI16 track2.mp3 track2.caf[/code]
For corresponding display in the terminal, see figure 4.

Figure 4 Converting audio files in the terminalYou will need to do this for every sound file that you wish to invoke from a push notification.

Summary

As we have seen, push notifications offer a very simple solution to a complex problem. They give developers the ability to mimic the functionality of running their application in the background while conserving the system resources on the iPhone.

Apple has provided us with a very robust service that we are able to use free of charge. This service is the centerpiece of the entire push notification system and allows us to send simple messages from a provider to a specific iPhone with very little delay.

In order to receive the push notifications, applications must be prepared and signed with a special signing certificate generated on Apple’s website. You must create a signing certificate for use in development mode as well as debug mode when testing push notifications in your application. This certificate is used in conjunction with your private key to create the SSL certificate needed to communicate with Apple’s servers.

Filed Under: Apple Tagged With: iPad, iPhone

Using an alert view as a task loader in iPad

May 26, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iPad in Practice, to be published on Summer 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

Using an alert view as a task loader

Introduction

Some actions, like signing out of an account in an application, require a user to both confirm the action and to indicate the processing of the action. When you need to present this type of flow to a user, an interesting option is to present an alert with a confirm/cancel option and then to use the alert as a loader while the action is being processed.

Problem

Providing a loader during different types of operations can be a very valuable user interaction technique. One approach to doing so is by providing a loader as part of an alert view interaction.

Solution

Our app is going have one view with a button to fire the alert interaction. When the user taps the button, we display an alert that gives them the choice to sign out of the application. If they tap the action button, we display a loader and process the action. Once the action is completed, we display a second alert view that confirms the completion of the action.

Start by creating a new project. Call it AlertLoader and select a view-based project as the project type. Click on the AlerLoaderViewController.h header file as in listing 1 to start setting up the view controller.

Listing 1 AlertLoaderViewController.h header
[code]#import
@interface AlertLoaderViewController : UIViewController {
UIAlertView *alertView;
}
@property(nonatomic, retain) UIAlertView *alertView; #1
– (IBAction) signout; #2
– (void) runProcess; #2
– (void) showAlertLoader; #2
@end

#1 UIAlertView property
#2 Function and action declarations[/code]
In the header file, we define a single property (#1), which is a UIAlertView. This is the alert view we’ll be using to control our interaction and to display the loader. We also declare three functions (#2) on IBAction, which will be attached to our button to start the interaction. The other two we’ll review in the implementation of the controller. Edit your header file to implement the property and function declarations.

Now double-click on the AlertLoaderViewController.xib to modify the UI in the interface builder. Your view will be pretty much empty; all you need to do is drag a single UIButton on the view and give it the title Sign Out. Now, connect the button to the IBAction signout on the controller as shown in figure 1.

The core of the solution is in the implementation of the controller where we implement the alert interactions. Let’s take a look at that next in listing 2.

Listing 2 AlertLoaderViewController.m implementation
[code]#import "AlertLoaderViewController.h"
#define START_RUNNING_INDEX 1
#define PROCESS_LOADING_TAG 200
#define PROCESS_LABEL_TAG 201
@implementation AlertLoaderViewController
@synthesize alertView;
#pragma mark –
#pragma mark AlertView Delegate methods
(void)alertView:(UIAlertView *)alertView #1
clickedButtonAtIndex:(NSInteger)buttonIndex { #1
if(START_RUNNING_INDEX == buttonIndex) #1
[self runProcess]; #1
}
#pragma mark –
#pragma mark Sync now
– (IBAction) signout { #2
NSLog(@"sync now"); #2
self.alertView = [[[UIAlertView alloc] #2
initWithTitle:@"Sign Out" #2
message:@"Sign Out" #2
delegate:self #2
cancelButtonTitle:@"Cancel" #2
otherButtonTitles:@"Confirm", nil] autorelease]; #2
UIActivityIndicatorView *loading = #2
[[UIActivityIndicatorView alloc] #2
initWithActivityIndicatorStyle: #2
UIActivityIndicatorViewStyleWhiteLarge]; #2
loading.frame = CGRectMake(122.0, 40.0, #2
loading.frame.size.width, #2
loading.frame.size.width); #2
loading.tag = PROCESS_LOADING_TAG; #2
[loading stopAnimating]; #2
[alertView addSubview:loading]; #2
[loading release]; #2
[alertView show]; #2
} #2
– (void) showAlertLoader { #3
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; #3
[(UIActivityIndicatorView *) #3
[self.alertView viewWithTag:PROCESS_LOADING_TAG] #3
startAnimating]; #3
[(UILabel *)[self.alertView viewWithTag:PROCESS_LABEL_TAG] #3
setHidden:NO]; #3
self.alertView.title = @"Processing…"; #3
self.alertView.message = @""; #3
[pool release]; #3
} #3
#pragma mark –
– (void) runProcess { #4
[NSThread detachNewThreadSelector:@selector(showAlertLoader) #4
toTarget:self #4
withObject:nil]; #4
[NSThread sleepForTimeInterval:10]; #4
UIAlertView *alert = [[[UIAlertView alloc] #4
initWithTitle:@"Completed" #4
message:@"Sign out completed" #4
delegate:nil #4
cancelButtonTitle:@"OK" #4
otherButtonTitles:nil] autorelease]; #4
[alert show]; #4
} #4
– (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
– (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
– (void)dealloc {
[alertView release];
[super dealloc];
}
@end
#1 Alert view delegate function
#2 Display alert and init loader
#3 Display the loader
#4 runProcess our fake worker function[/code]
The AlertLoaderViewController first implements the UIAlertView delegate protocol at #1 by implementing alertView:clickedButtonAtIndex: function, which is called when an alert view button is tapped. In this case, we have a constant START_RUNNING_INDEX, which is used to match the action button index for our main alert view.

At #2, we implement the signout IBAction, which is responsible for displaying the choice alert view to our user. When we create the alert view we also create a UIActivityIndicatorView, which will be our loader, set its frame, and add it as a subview to the alert view. You’ll notice that we call stopAnimating on the activity indicator. The default behavior of the activity indicator is to hide itself when it is not animation. So, we call stopAnimating when we add it and then later call startAnimating to display it. When signout is called, we get the alert view pictured in figure 2.

The showAlertLoader (#3) and runProcess (#4) functions work together. runProcess is actually what is called by our alert view delegate function when the user taps Confirm in the Sign Out alert. The runProcess function first fires off a call to showAlertLoader in the background using detachNewThreadSelector:toTarget:withObject:, which modifies the displayed loader to show our activity indicator, as depicted in figure 3.

Finally, in #4, after the loader has been displayed, we do our fake work. In this case, we just call sleepForTimeInterval: to pause the thread for 10 seconds as a simulation of doing some other work. Once the sleep completes, we create and show a new alert view to inform the user that the process has completed.

Discussion

Looking at this technique, we can see that it’s fairly simple; all it really does is add a subview to an alert view as a means of smoothing out some user interaction flow. It’s worth noting that this isn’t something to take too lightly. Adding a subview to a system view is accepted by Apple and I’ve used this approach in a few different applications in cases where it made sense. However, you need to be aware that trying to use private properties or views of a system view is a different story. I’ve heard it directly from Apple engineers that they not only frown upon trying to access and manipulate private components but that they are going to be checking for this and rejecting apps based on it. This particular technique doesn’t try to use or change the original UIAlertView other than clearing the text of the detail label, but going any farther may be walking a fine line with the app review team.

As shown in figure 4, after our loader has completed we show a confirmation loader, this is an optional extra piece of information you can show the user.

Summary

Alerts are a simple view, which was carried over from the iPhone SDK they give you a way to notify users of changes in state. You should try to use Alerts only in cases where it is really necessary to notify the user of a change that will impact their use of the application. Alerts views are extremely simple but can be very effective so it is a good idea to be familiar with how to use them.

We showed you how to set up one view with a button to fire the alert interaction so that, when the user taps the button, we display an alert that gives them the choice to sign out of the application. Tapping on the action button displayed a loader and processed the action at the same time. Once the action was completed, we displayed a second alert view that confirmed the completion of the action.

Filed Under: Apple Tagged With: iPad

Debug Logging in iPad

May 26, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iPad in Practice, to be published on Summer 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

Debug Logging

Introduction

In Cocoa, the default logging function NSLog can be useful for adding some log information to your application but, unfortunately, it runs in all build configurations. On the Mac, that may not be a big deal but, on the iPhone, you can and will notice a performance impact when NSLog calls are being made in a processor-intensive situation. You should use NSLog sparingly; in fact, I prefer not to use it at all and use a debug logging approach like the one outlined in this technique for all my log output.

Problem

Using NSLog for debug output seems like a perfectly good solution until you realize that NSLOg will run in all build configurations, even in release and distribution builds where you get very little benefit from it. On the iPhone, NSLog calls can impact the performance of your code by adding unneeded overhead, so it’s important to have a way to provide logging that will only run in debug or test build configurations.

Solution

In order to support logging for debug build configurations only, we’re going to implement a simple varargs macro that you can place in the *_Prefix.pch precompiled header file of your projects (see listing 1).

Listing 1 AppName_Prefix.pch
[code]// Debug logging function
#ifdef DEBUG
# define DLog(…) NSLog(__VA_ARGS__)
#else
# define DLog(…) while(0)
#endif[/code]
The DLog function is very simple. It uses an ifdef to determine if it should be enabled or not. If the debug flag is set, then it defines DLog to run NSLog so you’ll get the same logging behavior you’re used to with NSLog. If the debug flag is not set, it simply runs an empty false while loop, which will return immediately.

Now that the DLog function has been defined, you can enable it for your debug configurations by editing the Project Configuration.

Select Project > Edit Project Settings, choose the Debug configuration in the Configuration dropdown. Now search for Other C Flags (found in the GCC 4.2 section of the build settings). Then, add a new entry, -DDEBUG=1, to enable the DEBUG flag.

Figure 1 Setting Debug flag

Discussion

By implementing a debug logging function as a macro and using the OTHER_C_FLAGS compiler setting, we can easily manage the build configurations in which our logging will actually be included. The DLog function is a very simple macro that makes any calls to DLog return immediately if the DEBUG flag is not enabled for the current build configuration. This approach to logging means you will not have to worry about your logging impacting the performance of your final product.

Summary

We discussed the technique for adding Debug logging to give you a nice alternative to using NSLog.

Filed Under: Logging Tagged With: iPad

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved