Native versus HTML 5

As a developer who primarily writes natively for mobile platforms, I frequently get asked about native code versus HTML 5. Obviously, this happens most when people want to hit multiple platforms. They speak to developers who advise them that they’ll need to hit say at least iOS and Android, and then they’ll respond with something along the lines of “well, I’ve heard HTML5 runs on all devices, so I’ll just do that since it’ll be cheaper and then just work on everything”.

This issue has been reported in the mainstream media yesterday, as Mark Zuckerberg has publicly stated that using HTML5 on mobile devices was ‘the biggest strategic mistake we’ve ever made’, and that ‘it was really painful, we were never able to get the quality we wanted’. If Facebook had asked me 2 years ago when they started developing their mobile app, I couldn’t have more strongly advised against using HTML5. In some sense I can understand why Zuckerberg would make the choice he did though. He wrote Facebook initially using HTML, PHP and Javascript, that’s where he logged all of his coding hours. His experience of coding has all been web-based, and that is what he understands and is comfortable with.

As a developer who understands mobile platforms, it often grates on me when people view HTML5 as a viable solution in that space simply because they hear that it ‘works everywhere’ and flashing lights go off in their head as they suddenly see cost savings. There are a plethora of problems and issues that arise when mobile solutions are attempted with HTML5. Unfortunately, most non-techies, who are making the decisions, simply don’t understand the repercussions.

Note that when I talk about an ‘HTML5 app’ I mean an app that has a native shell that provides a standard web view, and then the majority of the app works inside that web view.

Firstly, HTML5 will always result in a slower and clunkier interface than native. For one, the app has to hit some server online that is hosting the HTML so there is the initial overhead of retrieving this. Whilst this may seem fast for one off operations, let’s say as an example one second, you have to remember that any serious use of your app is going to involve hundreds or thousands of these requests.  Waiting one second once is okay, waiting one second a thousand times is not. Note that in computing terms 1 second may as well be eternity, most native operations will be measured in pico or nano seconds. Once the HTML data has been received from the server, it still has to be decoded, interpreted and then the web browser has to conduct the appropriate work to update the display. All of these tasks are out of your control, you are relying on the browser to do this efficiently. Indeed, all of this assumes the user has a good Internet connection and the servers are working 100% of the time. If either of these aren’t true then an HTML5 app can fail in horrible ways, displaying blank or 404 pages.

Another issue is that an HTML5 app will never be able to make full use of the a mobile device’s capabilities; they are stuck with what HTML supports. Mobile devices are evolving from one month to the next, with better cameras, accelerometers, GPS, NFC… a never-ending multitude of sensors and capabilities, all of which are immediately supported natively.  However, HTML apps can’t access most of these, and if they can then they can only do so when support is eventually added and even then only in very specific and inflexible ways. For example, even though GPS hardware has been around for a long time and is in nearly every mobile device now, with HTML you might be able to get a location from the GPS, but you have to ask for it in a specific way. You can’t get rapid location updates, and you can pretty much forget about retrieving any other interesting information the GPS and location hardware can provide, such as altitude, speed, heading. Even forgetting the hardware and its sensors, HTML 5 apps can’t make full use of the excellent native APIs that most platforms provide. For example, on the iPhone there are APIs for sharing items via email, Twitter and Facebook. Users see these standard sharing items everywhere, and become familiar and efficient with them. These standard widgets are designed by the device manufacturers to be beautiful, and present information clearly in an easily understandable.  Yet HTML 5 apps are unable to use these, and will instead fall back to embedding features like sharing in the web view they operate within, the text will likely be small, and users will be forced to slowly figure out this new method whilst becoming increasingly frustrated as they strain to read the small text.

HTML5 apps also tend to really stick out, in a bad way, because they are unable to conform to the HIG (Human Interface Guidelines) of the device. Nearly all devices come with a set of guidelines about how developers should design and implement apps. These include things like how big buttons should be, how tables should be laid out, how information should be presented using standard widgets, etc.  Again, HTML5 apps can’t access these standard widgets that all other apps can.  They may try to duplicate them, but the duplication never quite looks right, and even if it is a good visual facsimile, when the user interacts with them they will be slow or jerky.  Basically, just as some human-looking robots fall into the uncanny valley and end up making people feel nauseous, these HTML attempts to copy end up doing the same for graphical widgets. Users look at them and expect one thing, and then become annoyed and frustrated when they behave oddly.

A final issue with HTML5 apps is that the primary claim of them working everywhere, across all devices, is just plain lies. Every device and operating system interprets HTML slightly differently.  You just have to try any HTML compliance tester (e.g. http://html5test.com) from multiple browsers to see for yourself how different the same HTML can be from one device or browser to another. The standard mobile browsers provided in Android, iOS and Windows Phone are all wildly different, and you can never be sure that the design you are supplying will always look or work the way you intended.  Add in screen size differences (tablet versus phone) and you end up with so many combinations that you can be certain that your HTML5 won’t be looking and working as you expected on at least some devices.

So, my list of HTML5 app problems are:

  • Always going to be slower than native
  • App may fail if servers go down, or connection is not available
  • Unable to use the full features of the device/OS
  • Unable to conform to the UX/UI guidelines of the platform
  • Actually not as compatible as you may think

In short, if you know for sure that you’ll never want to use any of the unique features and functionality that is currently available on mobile devices or that may come along in the future; don’t mind a slow, ugly, non-standard app; and truly believe that by some unknown magic HTML5 looks the same on all platforms and screen sizes; then sure, maybe HTML5 is a good solution for you.

Seriously though, don’t be fooled by the one claim that HTML5 relies on… that it just ‘works everywhere’.  It doesn’t.  Apps represent your company and your brand, they are a direct channel to customers. HTML is an ugly, slow and hacked together solution; don’t force that on your customers.

How to disable smooth-scrolling in Mountain Lion

Up until Mountain Lion, in OS X there was always an option to switch smooth scrolling on and off.  I think it was a checkbox called ‘Use Smooth Scrolling’ in the Appearance section of System Preferences.  An example of smooth scrolling is in Safari, where if you are viewing a web page and hit space then without it the page just immediately jumps to the next section, whereas if you have it on you see it very quickly scroll down to the next section. However, in Mountain Lion this option no longer exist and smooth scrolling seems stuck on.

If this annoys you then you can still turn if off by opening Terminal.app and entering:

defaults write -g NSScrollAnimationEnabled -bool NO

How to turn off shared calendar alerts in iOS 6 and above

iOS 6 has a new feature where if you are using a shared calendar and someone else makes any change – creates a new event, moves and event, changes length of event, etc – then you will get an alert on your iPhone or iPad. Personally, I find this very annoying as often the people I share calendars with add or edit tens of events at a time and my iPhone just keeps beeping away like crazy.

I eventually figured out how to turn this alert off. Just go to the Settings app, scroll down and select “Mail, Contacts, Calendars”, then scroll down again until you see the “Shared Calendar Alerts” setting and just flick it off. Now your phone won’t have a fit when other people add or edit calendars.

Shared calendar alerts off switch

SBGetScreenLockStatus (iPhone / iPad / iOS)

I figured out the parameters for the iOS SpringBoard SBGetScreenLockStatus method.  At first I was sure it would only be setting one bool to say if it was locked or not, but actually it turns out that it sets two.  The second just tells you whether or a passcode is enabled.  I’m calling it via the SpringBoardServices so it’s simply…

bool locked;
bool passcode;
void* (*SBGetScreenLockStatus)(mach_port_t* port, bool *lockStatus, bool *passcodeEnabled) = dlsym(sbserv, "SBGetScreenLockStatus");
SBGetScreenLockStatus(sbPort, &locked, &passcode);

Update: Stripping NSLog output for Xcode release builds

I previously posted a solution for stripping NSLog entries from Xcode release builds. However, that method no longer works in Xcode 4, since the variable it relied on (__OPTIMIZE__) is no longer defined by default. There is an alternative now though, since DEBUG is always defined. I’ve copied the bulk of my reasoning from the old post below, and put the new solution at the end, hope this helps…

I’ve had to move my webpage and looking at my incoming site stats it seems one of the most visited pages from my old site was the info on how to easily remove NSLog output from release builds for Xcode so here it is again for those that need it…

Objective-C developers frequently use NSLog to output strings to the console, particularly for debugging purposes. However, when you build a release version you don’t usually want any console output. This is especially true if you are building iPhone applications, where console output is more costly than on desktop OS X and can slow your app down. I’ve seen a few versions of tricks to help you remove NSLog output on release builds (for example, this one), but they all have two problems in common. Firstly, in most you have to edit your project settings and manually define a DEBUG constant. I find this rather annoying, as it just becomes a hassle to remember to go in and edit the project settings every time you start a new application. Secondly, they normally result in defining an alternative output method, such as DLog instead of NSLog, so you have to remember to start using the new version instead, and would have to go back and replace NSLogs in all your old code.

I came up with this small amendment that you put in your app’s prefix header, which I believe is a little neater than the other solutions I’ve seen…

#ifndef DEBUG
#define NSLog(...) {}
#endif

As DEBUG is normally defined for debug builds, you no longer have to go into your project settings and add any new definitions every time you create a new app. Furthermore, by overriding NSLog rather than providing an alternative definition, you can keep using NSLog normally instead of having to use an alternatively named alias. Therefore, I think this is the best solution, as all you have to do is copy and paste the above into your prefix header

How to spoof a MAC address on OS X Lion 10.7 (and probably Leopard)

It used to be a little easier to do before Leopard (10.5), but you can still spoof a MAC address rather easily in OS X Lion. If you don’t know why you’d want to spoof a MAC address then you probably don’t want to be doing it, but there are plenty valid reasons why you’d want to do so. Here are some steps on how to fake your address to the example MAC address of fa:ca:dd:fa:ca:dd, and there’s a more detailed description of each step below if you’re interested. Stuff marked like this should by typed into Terminal.

1. Decide which network interface you want to spoof, this is probably en0 or en1, remember which one you pick. I’ll assume you are using en1 for the remaining steps.
2. ifconfig Take a note of your current MAC address for your interface (en0 or en1) in case you want to revert later (but don’t worry if you forget, a reboot will always revert it to the real MAC address anyway).
3 (Wi-Fi only). sudo /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -z
4 (Wi-Fi only). Wait about 10 seconds
5. sudo ifconfig en1 ether fa:ca:dd:fa:ca:dd

* Note if you want to know the MAC addresses of other devices already on the network you can view the arp table by doing…

arp -a

More detail on the steps for those who like to know what’s going on…

(1) Firstly, identify which network interface you want to change, the wired connection or the Wi-Fi. If you have both then they are most likely en0 for wired and en1 for Wi-Fi. If you only have one, such as the MacBook Air that only has Wi-Fi, then it’s probably en0. You can see a list of your network interfaces by typing ifconfig into Terminal. Alternatively, launch the Network Utility app in the Application/Utilities and you’ll see them in the drop-down list there.

(2) Regardless of whether you use ifconfig or Network Utility you’ll see the MAC address listed so take a note of it so that you can revert back later. By the way, if you forget it your machine will always revert to the true MAC address when you reboot anyway so don’t worry.

(3) The next step is to use the airport command to disassociate completely. This is necessary because if you try to set it to fake a MAC address and you are already connected to a network then the change probably won’t take affect. The command you use to do this is /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport. If you are going to be doing this a lot though then you may want to create a symbolic link to the command so you don’t have to keep typing the full path. To do that type in…

sudo ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport /usr/sbin/airport

After that you you can just type ‘airport’ from then on instead of typing the full path. So now to disassociate you just type…

sudo airport -z

(4) Even if your Wi-Fi icon goes grey immediately you should still wait 5-10 seconds to make sure it is fully disconnected before proceeding.

(5) This command is the one that tells OS X to pretend that the interface has a different MAC address.  At this point you probably want to check that the change has actually worked.  The easiest way to do this is to type the following and check that one of the results is the fake MAC you just set…

ifconfig | grep ether

How to handle ‘No previous prototype for function’ warnings in Xcode

When compiling code in Xcode 4 you may be seeing warnings saying ‘No previous prototype for function…’.  This is probably happening if you are using a library that has at least some parts written in C/C++.  This warning may even be appearing in code that previously compiled fine in Xcode 3 without any warnings.  This is because Xcode 4’s default compiler warns about this when Xcode 3’s did not.

Anyway, the warning is simply saying that a function implementation exists but no matching function declaration was found.  If you are used to Objective-C only this is like saying that you have the implemented code in the .m file but you don’t have the function listed in the .h.  It’s easy to fix, just write the method declaration in anywhere before the actual method; you can write it in the .m or .h, it won’t matter as long as it’s before the actual function.

For example, if you have a method such as…

float doSimpleMaths(float a, float b) {
   return (a*a)*(b*b);
}

Then to get rid of the warning just add in the method declaration before the method…

float doSimpleMaths(float a, float b);
float doSimpleMaths(float a, float b) {
   return (a*a)*(b*b);
}

Is OS X Lion a bad operating system?

I’ve been using OS X Lion for a while now, and over half a year after its initial release, I continue to have a niggly feeling that it is a bit poor overall. Now, before I go any further I feel I have to preface this post with some clear points. Firstly, I think OS X is currently the best operating system on the market, and I personally love it. Secondly, whilst I appreciate that Windows 7 is a good OS, and that Linux is superb on servers, I believe OS X is far better than either of these when it comes to consumer OSs. Finally, whilst I have issues with OS X that I’m going to describe here, overall I think it is great and I’m not going to stop using it anytime soon. So, hopefully you know that I am writing this article as someone who does indeed love OS X.

So why do I have a bad feeling about Lion? There are several specific issues I have, and also some much larger overall points. Let’s start with some of the specifics, as they are easier to describe. I hope you don’t feel I am being overly picky as I list these issues. I believe they are symptomatic of the larger issues, and so they are useful illustrations.

 

Exposé

Exposé is undoubtedly one of the best features of any OS. When it was introduced I was blown away by how easily it made viewing and navigating all the open application windows at once. When Spaces (the ability to have multiple desktops) was introduced later in 10.5 (Leopard) Apple made sure that you could still view and navigate all application windows at once even if you had many spaces. You just activated Spaces, and then hit the Exposé key, and you could see all windows on all Spaces splay out. There were no overlapping windows so you could see the entirety of every single window. You could also navigate to any window you wanted using either the mouse or keys. Both in usability design and aesthetic appeal it was bliss; regardless if you were using one desktop or many. For me, Lion destroys the usability of Exposé. Firstly, if you have multiple Spaces there is now no way whatsoever to see all your open application windows. If you activate Exposé it only applies to the current Space/desktop, and although you can see the other Spaces the windows on them have not moved into the Exposé mode.

 

 

Windows are now also grouped by application, and each application’s windows are overlapped. For example, if you have five Safari windows open they will be grouped into one element in Exposé and overlap. In the first screenshot above I have five Safari sites with Wikipedia, Ars Technica, Engadget, Mac Rumors, and AppleInsider. However, in Exposé it is almost impossible to tell how many Safari windows there are nevermind the content of each. In the second screenshot, when activating Exposé from my second Space (Desktop 2), you can barely even tell that there are any Safari windows open at all.

Indeed, this grouping problem applies even if you only have one Space/desktop. The windows of each application group together and overlap, and often you can only see the content of the top window. Selecting a particular window in such a group using the mouse is challenging. Another big problem is that selecting using the keys doesn’t work at all. I believe since Exposé was first available right up until Lion you could always use the cursor keys to navigate the windows and then press space to pick one. In Lion you can’t use keys to navigate through Exposé at all. I actually filed this as a bug report with Apple some time ago, but they haven’t responded to it yet. I find the lack of keyboard navigation extremely vexing. I imagine that this could be a much more severe issue for disabled users.

 

Spaces

With Spaces itself there has also been some loss of functionality in Lion. Previously, Spaces allowed you to set up multiple desktops both horizontally or vertically. So you could, for example, have a 2×2 grid, or a single vertical row, or a single horizontal row. I preferred a grid (I used a 2×2 grid), and I found this very useful as every desktop was one switch away (you could move diagonally so you could quickly jump the diagonal on the grid). With Lion Spaces only supports a single horizontal row. By default it also changes the order of desktops based on when they were last used, which I find infuriating as I assign specific tasks to each desktop number (e.g., desktop 1 = web browsing, desktop 2 = mail, desktop 3 = music, etc). Since Lion moves these around by default it completely breaks this mental model. Luckily, you can disable that (it’s the ‘Automatically rearrange spaces…’ checkbox in the Mission Control Preferences).

 

Launchpad

Launchpad seems to be an attempt to use the iOS app layout for desktop applications. I honestly wonder if anyone uses this. I certainly don’t, and the many non-expert users I know don’t use it either. If anyone is actually using it I would love to hear about it. Interestingly, at some point during development Apple must have realised that nobody uses this feature either as in the early Lion betas its dock icon was locked in place and couldn’t be deleted but this was changed so that in the release version you can just drag it off your dock so that you never have to look at it again.

I don’t know why others don’t use Launchpad, but I certainly have a few reasons why I don’t. Firstly, there are much quicker ways to launch apps. If I use an app frequently then I put it in the dock so it is always on screen and I can quickly launch it from there. If it’s something I use intermittently then I find Spotlight is a far faster and more reliable way to find and launch apps. Spotlight will find the app no matter where it is… typing into and using Spotlight is much quicker for finding a rarely used app than Launchpad because with Launchpad you have to search through many app icons and often have to swipe between Launchpad screens to find the icon you are looking for.

I really do wonder who is using Launchpad… is it just people who haven’t figured out how to use the dock, Spotlight, or any of the many great 3rd-party app launchers (e.g. Quicksilver, Launchbar).

 

iCal and Address Book

Thanks to the way Lion has given both the iCal and Address Book apps a makeover, I’ve learned a new word… skeumorphic (http://en.wikipedia.org/wiki/Skeumorph). The Oxford English Dictionary defines this as ‘a derivative object that retains ornamental design cues to a structure that was necessary in the original’. For example, a physical calendar may have a page for each month and as the month passes you tear off the last month’s page. A computer calendar does not use pages, so if it gives the appearance of having pages when there is no longer a reason to then it can be said to be skeumorphic.

This may be a personal preference thing, but I detest how this has been applied to both iCal and Address Book to an insane degree. iCal has a horrendous fake leather effect, fake stitching and fake bits of torn pages that add absolutely nothing for me and take up space that could be better used for displaying actual content.

I especially dislike how iCal appears when it combines many elements at once. To me, it is a mishmash of modern digital elements and extremely dated physical ones.

 

Another awful point with all this skeumorphic stuff that Apple is doing is that because it doesn’t actually update its appearance with the activity in the app it actually gives me an uncomfortable, creepy feeling. For example, when you open Address Book it looks like an open book, with 5 pages on the left and 5 pages on the right. If you then scroll through your addresses from A to Z the book doesn’t move or change at all. When viewing the As it looks like you are bang in the middle of a 10 page book, then when viewing the Zs it still looks like you are in the middle of a 10 page book. Since the book never moves, this makes it feel like everything you are doing is sitting on a picture of a book… a static, dead book. It is creepy. If Apple are going to do this skeumorphic insanity then they should at least do it right and make the underlying book metaphor actually behave correctly. By the way, iBooks in iOS suffers this same problem, where it always seems like you are in the middle of the book, even when you are on the last page. Recently, Apple introduced an alternative mode in iBooks where you can now get rid of the underlying book aesthetic. I really hope this is the first signs of a rethink of their approach to skeumorphic stuff in general.

 

Usability

So, I feel the previous examples can be boiled down to one overall point… in Lion Apple seems to have missed expectations on usability. Apple is renowned for making software (and hardware) products that look and feel great. This means focusing on maintaining extremely functional and usable systems; and not compromising on either. Exposé is a great example of this. When it was introduced it looked amazing, was easy to navigate, and provided a lot of functionality. In Lion it is now much harder to navigate (smaller targets for mouse due to overlapping, no keyboard navigation at all), less functional (can’t view all windows at all if you have multiple spaces, and is much harder to view all even on a single space), and (perhaps arguably) less aesthetically appealing due to the grouping and overlapping of windows.

Launchpad is another good example where usability has, in my opinion, not been thought through. I feel this is particularly tragic. When Apple released the iPhone it was clear that they hadn’t simply taken OS X and ported it to a smaller screen. Indeed, in the keynotes they frequently boasted about how they had realised that it just wasn’t appropriate to do that, they said that what works on a large screen doesn’t work on a small screen, and they developed the user interface and all the widgets from the ground up, focusing on making a UI perfectly designed for finger-sized input. Now with Lion they seem to have literally taken the opposite approach. They have just taken the exact iOS homescreen and forced it into Lion as Launchpad, without making any changes whatsover for the larger screen and additional input hardware on laptops and desktops. Moreover, they don’t seem to have asked themselves if emulating the iOS homescreen on a desktop machine was actually a good idea in the first place.

There are many, many other instances of usability problems in Lion. For example, how whenever you open any new window in any app it zooms out from the centre of the screen, taking a short while but essentially wasting time. Previously, animations were only applied when they guided the user as to what was going. For example, when you minimise a window it slides into the dock, guiding the user to where they can later find; or when you double-click a folder in Finder the window zooms out from the folder’s icon, both quickly confirming the window is opening (useful for network folders) and showing where it came from. However, this animation does not contain any such information, it isn’t guiding the user in any way. Such truly superfluous UI niggles are numerous in Lion. However, my overall point is that it looks to me that with Lion Apple has somewhat dropped the ball with usability and functionality.

 

Quality

Lion also seems to be buggy, even after two updates (I’m on 10.7.2). Some of the things I have experienced include:

  • The network failing to reconnect on wake if the machine went to sleep whilst a time-machine backup was in progress (this was fixed in 10.7.2)
  • Wi-Fi spontaneously disconnecting (occurred frequently in 10.7.0, still happens but a lot less often in 10.7.2)
  • Battery life on the same machine is an hour or two less on average when compared to Snow Leopard (I know this isn’t a bug per se, but it is a point I feel should be worked on and improved in future updates)
  • Numerous Safari bugs, such as the Safari UI apparently locking up on a page, or the page randomly scrolling wildly
  • Stock widget not updating
  • Desktop icons overlapping when plugging/unplugging an external display

There are obviously many more. I know every OS has bugs, and every major update typically has a lot of bugs that get fixed over the course of the OS. However, I have used every version of OS X since 10.2 and it seems to me that Lion is suffering significantly more bugs than any release in a long time.

 

Why does Lion have these problems?

Assuming Lion does have some problems, can we determine why it does, at least at some high-level? I have no information at all to go on here, but I am going to make 3 guesses. Perhaps the answer is one of these, none of these, or a combination of these.

 

Steve Jobs wasn’t involved much or at all in developing Lion

Jobs was renowned for his laser-like focus on numerous aspects of OS X. I believe that over the years this greatly helped shape OS X into fantastic product. Perhaps Jobs was far less involved in Lion’s development than previous versions, and perhaps OS X suffered from a lack of his input. Although Lion was released whilst Jobs was still alive, he was effectively on medical leave for a year before Lion’s release, and perhaps longer. This may have meant that he just didn’t get the opportunity to contribute as much to the project as he normally would.

 

Focus on iOS

The iPhone and iPad have outperformed nearly all predictions and sales break expectations and records nearly every quarter. Apple’s iOS (iPhone, iPod, iPad) products have been generating more revenue than their Mac products (MacBooks, Mac Minis, iMacs, etc) for years now. It may be that Apple have pulled a large amount of resources from OS X development and instead focused on iOS and the App Store. Perhaps it is simply that Lion has benefitted from less of Apple’s effort than any previous version of OS X.

 

Attempt to make OS X like iOS

Jobs himself stated that one of the goals for Lion was about bringing a lot of what they had learned and created for iOS back to the Mac. This is clearly evident in things like Launchpad, which is a direct port, and the skeumorphic iCal and Address Book, which clearly take their UIs from iOS’s Calendar and Address Book apps. Perhaps this was a misdirected goal and Apple would have been better on building the best experience for the laptop/desktop hardware of the Mac, rather than attempting to port elements from an OS designed for finger input.

 

Is Lion Bad?

So is Lion a bad OS? Personally, I still think OS X is the best OS available today. I’d rather use Lion than the latest versions of Windows or Linux. However, it clearly has some major issues that concern me. Indeed, whilst in every previous update to OS X I felt there was clear and valuable improvements, with Lion I find myself often wishing that I was back using Snow Leopard.

I am still thinking about Lion a lot. I know a lot of what I wrote may come down to personal preference. If you have any thoughts on whether you think Lion is good or bad, and why you think that is the case, I’d love to hear them in the comments.

UDID and UUID alternative for iOS

As of iOS5, Apple no longer want you to use the UDID (Unique Device Identifier) in your iOS apps, and would prefer you to use a UUID instead (I posted about how to get a UUID earlier). However, the disadvantage of this is that a UUID only identifies an installation instance of the app, and does not identify the device. If the app is deleted and reinstalled even on the same device then you will end up with a new UUID and have no way to link them.

There is another alternative. Since all iOS devices (iPhones, iPads and iPods) have at least one network interface they all have at least one MAC address, and this is unique to the device and does not change. Therefore, a MAC address can be used to uniquely identify a device. I’m not sure how Apple will feel about people using this in the future, but for now at least it does provide a way to do exactly what a UDID did before and it is permitted in app store apps.

Here is some code for how to get the MAC address off an iOS device. I originally had another version here but it stopped working after an iOS upgrade so this working version came from here. Make sure you include the imports too…

#import <sys/sysctl.h>
#import <net/if_dl.h>
#import <arpa/inet.h>
#import <net/if.h>

#if !defined(IFT_ETHER)
#define IFT_ETHER 0x6/* Ethernet CSMACD */
#endif

@implementation MACAddress

+ (NSString *)MACAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
size_t length;
unsigned char macAddress[6];
struct if_msghdr *interfaceMsgStruct;
struct sockaddr_dl *socketStruct;
NSString *errorFlag = NULL;

// Setup the management Information Base (mib)
mgmtInfoBase[0] = CTL_NET; // Request network subsystem
mgmtInfoBase[1] = AF_ROUTE; // Routing table info
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK; // Request link layer information
mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces

// With all configured interfaces requested, get handle index
if ((mgmtInfoBase[5] = if_nametoindex(“en0″)) == 0)
errorFlag = @”if_nametoindex failure”;
else
{
// Get the size of the data available (store in len)
if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = @”sysctl mgmtInfoBase failure”;
else
{
// Alloc memory based on above call
if ((msgBuffer = malloc(length)) == NULL)
errorFlag = @”buffer allocation failure”;
else
{
// Get system information, store in buffer
if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
errorFlag = @”sysctl msgBuffer failure”;
}
}
}

// Befor going any further…
if (errorFlag != NULL)
{
NSLog(@”Error: %@”, errorFlag);
free(msgBuffer);
return errorFlag;
}

// Map msgbuffer to interface message structure
interfaceMsgStruct = (struct if_msghdr *) msgBuffer;

// Map to link-level socket structure
socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);

// Copy link layer address data in socket structure to an array
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);

// Read from char array into a string object, into traditional Mac address format
NSString *macAddressString = [NSString stringWithFormat:@”%02X:%02X:%02X:%02X:%02X:%02X”,
macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]];
NSLog(@”Mac Address: %@”, macAddressString);

// Release the buffer memory
free(msgBuffer);

return macAddressString;
}

Blogging about stuff