As I began refining some sample code for making Universal Apps for the iPhone and iPad, I sought a way to make my code as concise as possible. I needed to determine if the app was running on an iPad or iPhone/iPod Touch and use it to my advantage. This basic information is contained in the UIDevice class.
Unfortunately, using:
[UIDevice currentDevice].model
did not do precisely what I needed to do. I needed something specialized. I wanted to add new functionality to the UIDevice class as if it had been there all along.
Looking for Solutions
A few months back I ran into a code sample that adds functionality to the NSDate class called NSDate+Helper. This class, created by a programmer named Billy Gray was my first exposure to a wonderful feature built into Objective C called Class Categories. When I saw how one could do this, it set the wheels turning in my mind at all the possibilities!
In this tutorial I am going to show you how to use class categories, and for our example we are going to add functionality to the UIDevice class for use in ultimately creating a sample Universal App.
note that the above video contents are easier to see in full screen mode.
Sample Code Info:
Getting Sample Project Source Code & Running it in the Simulator
It would be handy for you to download a copy of our Universal App project to look over and try out. In order to really use it you will need to have an Intel-based Mac computer, and XCode 3.2 or better installed on it. Once you have done this, you will be able to run it in the iPhone Simulator.
Make sure when running on the simulator that you set the proper build version before doing a build:
Simulating the app running on an iPhone:
Simulating the app running on an iPad:
Running the Sample Project on an Actual Device
If you want to run the project on an actual device rather than just the simulator, you will need to be a paying member of the Apple Developer Network ($99 a year at the time of this post). And you will need to have gone through the hoops of setting up your certificates, app record, and provisioning. ... We are not covering any of this getting on the device stuff in this tutorial.
At least you can run the project in the iPhone Simulator for free!
Getting In Class Categories
What is a Class Category?
You use class categories to add new functionality to an existing class. This could be one of your own classes, or it could be a class in Apple or someone else's API.
You do not have to sub-class the class you are adding to.
You can add the new functionality in such a way (inside your project) that it seems that the functionality was there all along!
Step 1: Come Up With A Category Name
When creating a class category you are adding some sort of new functionality to an existing class (without touching any of the code actually in the existing class)! If you were to describe in a general way what that new functionality was, how would you phrase it? What "category" would it fall under? This is something you make up. I make up some sort of camel-cased phrase for my category name. In the case of my new functionality to add to UIDevice, I thought that MyDeviceType captured it well. Perhaps if I had thought about it longer I could have made up something better! But that is what I came up with so that is what I used!
Step 2: Create a Group in Our Project to Place our Class Category in (optional)
The first thing you may want to do is create a new group (folder in your project) to place it in. This is optional, but it can make finding it easier as well as providing some form of internal documentation.
So, for the sake of argument, let's say that this is what you want to do. Let's go through the steps needed to do this:
- First of all click on your project file item (in examples shown in the screen shots, this is "classcat").
- Then control-click on it again to bring up a pop-up menu.
- Click the Add option at the top of the menu...
- Then click the New Group option (see screen shot below)
At this point you will see a new group appear under classcat with the text highlighted and ready for you to edit like in the screen shot below:
Lets rename the group to "Class Categories"...
Step 3: Create a new Class from the NSObject Class
- Control-click on our Class Categories group to bring up the pop-up menu.
- Pick the Add option.
- Pick the New File... option.
- The New File dialog window will appear.
- Make sure that Cocoa Touch Class is highlighted on the left hand side.
- Make sure the Objective-C class option is selected.
- Make sure Subclass of is set to NSObject.
- Then click the Next button.
The next screen will come up. It is looking for you to name the class:
We need to enter our class name. Gotta have some sorta naming convention! We will use the name of the original class we are creating a category for followed by the name of the category itself. That sounds good! So the original class in our example is UIDevice. The name of our class category is going to be: MyDeviceType. So we will type in UIDeviceMyDeviceType.
Above I type in my new class name. Then I would just click the blue Finish button.
Here is the initial header file XCode created:
This file starts out as just a normal class being subclassed from a superclass (NSObject).
Step 4: Modify Our New Class Files and Turn them Into a Class Category
The first thing we will do here is replace the class name UIDeviceMyDeviceType with the class name we are creating a category for. In this case that is UIDevice.
Next we are going to put MyDeviceType in parenthesis and delete the colon, NSObject and the curly braces and end up with this:
- Again note that above UIDevice is the existing class we are creating a category for.
- MyDeviceType is the category name we made up for our category.
- The category name is in parenthesis.
- Although it might seem that we should put the category name in quotes... we do not.
- Again, we removed the normally correct curly braces... to leave them in on our class category will get you errors when you build your project.
While we are at it, lets add some interface definitions for the methods in our class category that we want to make public:
There may be other members in our class category than these, but these are available to be used by the "outside world."
Now let's look at the implementation file (the .m file)...
Notice it has the class name we gave originally. After the text UIDevice, we need to put parenthesis around MyDeviceType... Again, no quotes go around the class category name.
There! It is now setup to be used as a class category! All that remains to be done is add any variable declarations and code for our members.
Here is a screen shot showing a partial view of what that could look like:
The new functionality at this point is ready to be used. There are two ways to make it accessible to various classes in your project:
1. In the implementation file of a class that is going to use this functionality, add an #import line at the top. In our case the line would be:
#import"UIDeviceMyDeviceType.h"
2. If you are going to use it widely in your project there is a better way!
Click in the Other Sources group in the project and click on the classcat_Prefix.pch file.
(the first part of the file name is the project name).
You will see two import lines defined for Apple framework stuff. XCode puts these in so that the programmer does not have to use #import for anything in these frameworks throughout the project... the #import is implied. Underneath the #import add our import statement:
#import"UIDeviceMyDeviceType.h"
Save your changes and BOOM! All your new functionality in your new class category is available to project!
You could say:
NSString *myDev = [UIDevicemyDeviceType];
in your code anywhere in your project and the new myDeviceType method will just work!
Different Uses for Class Categories
Here are some possibilities to think about:
Add new functionality to existing classes (especially API type stuff) like we did in this tutorial.
Break a large class up into separate files grouping various blocks by function "category."
Can you think of anything else? :)
Hope you find this tutorial useful. Any questions? Ask away. If you could rate my Youtube videothat would be great too!
In the next tutorial we will be talking about the structure of a Universal App.
Well, several days have gone by since Apple announced it's new tablet device the iPad. It seems that all that could be said about a device that we can't have yet has been said. The iPhone Obsessed blog has remained silent. Well one thing you didn't know before: I want one! Not that anyone cares but me! One thing that I have wished for when programming for the iPhone is more screen real estate. This cannot be underestimated in importance. The iPad addresses this problem in spades. So I talk here, hopefully providing just a slightly different angle of looking at a subject that has already been written about at length.
As I read all the buzz for the iPad: the initial disappointment after the device didn't meet people's heightened expectations due to all the hype, then the growing realization by developers that they have all this space to put their user interfaces in... I see others are focusing in on this advantage. Some say that "look, a laptop has a bigger screen." But a laptop computer does not have a touch screen. A laptop computer has this physical keyboard that gets in the way and makes it feel a bit awkward sitting on your lap. When I saw Steve Jobs during the key note sitting in the chair with the iPad in his lap just using it, it connected with me: This was precisely like how I would interact with a book or magazine, or a pad of paper. It is not almost there like a laptop computer is. The awkwardness has been completely removed.
Steve Jobs called it an "intimate" experience. I have to agree. It worked for him as a real-world, non-tech device would work, and has worked for thousands of years. In fact, it works better than books and magazines do (no more holding the page down to keep it from turning when you don't want it to, no more trying to put a crease in the page so it stays open... more like a clay tablet with ancient cuneiform written on it. A flat, single surface. The iPad is like that except its able to hold lots more information, does color, is back-lit, and is hooked up to the internet!
As for all the prognostication on how it will sell, and will Apple save the publishing industry, will the iPad bring world peace or feed starving children, I have no clue. But I know I want one, and am planning on buying one.
You probably already know this, but I share it anyways... Have you ever been listening to your tunes on your iPhone through the ear buds that came with the phone, and you squeezed the little clicker on the wire to pause the playing of your music, and the music continued playing merrily along?
You clicked it again, and still it played on?
I discovered today, that it is possible to have your headset plugged in far enough to hear your music just fine, but not far enough for the "clicker" to work.
Solution? Just push the plug in a little farther and try again!
I made (in my opinion) a big mistake by installing iPhone OS 2.2 on my iPhone a couple of days ago. Now I cannot install any apps I've worked on onto my phone! :(
I basically thought, well, it doesn't matter that this happened, I just got an iMac a short time ago and I want do do development on it instead of my MacBook anyway. The screen is much larger and easier to read that the laptop, the keyboard is better, it has more storage, etc.
So I revoked my certificates, created a request for a certificate and posted it into the program portal.
Part of vast frustration: After posting, usually I get the option to approve the certificate (since I am the "agent") but no option shows up to do this. Arrrrggghhh!
I've submitted a "request" I think the day before yesterday. Still no word from Apple. It makes me want to tear my hair out! Appeo! Appeo! wherefore art thou Appeo!
Another wonky thing: Controls you place on a view in Interface builder don't always appear in the simulator where you put them in the builder. You have to offset their positions to make them come up right. Also, the positioning (both wrong) is different from 2.1 to 2.2!
If you haven't installed the iPhone OS 2.2 on your iPhone yet, I would say hold off for now. Just my take.
Quite some time has passed. In that period of time much has transpired.
I have a better understanding of Interface Builder now (I would not say that I have a good understanding yet... but I know enough to get some stuff done now).
I've actually got little apps I've made to install and run on my actual phone instead of just running in the iPhone Simulator.
I've finally got a tab view/navigation view controller type app to work properly.
I've got more proficient at working with "tables" in the views (not to be confused with database tables).
And speaking of databases, I've been able to create an app the creates a SQLite database file and creates some tables in it and read/writes data to those tables.
I've successfully got to work the showing and hiding of a modal view with a modal view controller.
Oh, and I bought myself a new iMac for my birthday!
I wouldn't say that I have learned everything I need to know in order to write successful iPhone apps, but I think I probably have 90% of what I need to know down. I am planning on doing some video tutorials on what I've learned... stay tuned...
With Apple's NDA out in force. It was very frustrating to find any information outside of Apple's online documentation on developing software for the iPhone. You want to take classes? Sorry! Apple is great at having all sorts of classes on various Apple software at their stores. Not for programming the iPhone though. What about classes offered by someone else? Sorry! Websites? Books? Buzzzzzz! No dice. Thankfully the super-restrictive NDA has been lifted (of course if you follow iPhone programming development you already know that)!
There are three books that I have had my nose stuck in of late. Let's take a high-level look at each:
Programming in Objective-C Initially, I got this book pre-NDA. I mean, Objective-C is not just a language for programming on the iPhone or the iPod Touch. It's been around for years. It is the main programming language Apple uses for their apps that run on the Mac.
Considering I had never programmed in Objective-C before much less heard of the language in the first place, this seemed like a good book for me to get.
Turns out this is a pretty good book. It won't actually show you development on an iPhone, but it will teach you Objective-C. It assumes zero knowledge of the language (which is good because that is where I was at)! It allowed me to start to get used to Objective-C's strange syntax of square brackets, declaring object references with asterisks, an initial foray into delegates and more. Don't know Objective-C? Get this book!
Once the NDA was lifted, the following two books became available for purchase:
Beginning iPhone Development: Exploring the iPhone SDK Of the three books mentioned here, this book is my favorite and the one I have been spending most of my time with. It has spent allot of time with me going to and from work on the train. I've been reading it after dinner. I've been sitting with it and my Mac Book trying stuff out in XCode. It has been my evening reading before going to sleep. It's really a good book.
There are some things I wish were covered in more detail. I wish there was more info on tab view controllers and just more conceptual information on view controllers period. I find it hard to visualize some of the view controller/view relationships.
That being said, the book is chock full of detailed examples. The authors take you step-by-step through each example in a very thorough manner. I love the cheerful banter of the language. It's just fun reading this book! The layout of the book, the illustrations, are well done. I just want to pick it up to look at it. Does that mean I'm a geek? :P
One thing I would mention though, if you never programmed in Objective-C before, this book is not enough. There are syntax things going on that you'll be saying, "what is that for?" Best to get Programming in Objective-C to go along with it.
The iPhone Developer's Cookbook I actually got this book before Beginning iPhone Development. It is instructional and can help you learn how to program the iPhone, but, just has the title implies it's more of a cookbook type of book. That is, it has "recipes" on how to code different things on the iPhone.
The section on view controllers was helpful to go along with what was said in the Beginning iPhone Development book. It didn't complete the picture for me though.
One thing I like about this book is the recipes included for functionality that does not necessarily show up in Apple's documentation. Like do you want your app to use that cool feature known as Cover Flow? This book has a recipe on how to do it.
Again, if you don't know Objective-C, you best get a book like Programming in Objective-C to go along with it.
Final Thoughts on These Books If you're looking for information on how to use the Program Portal after paying your $99, you won't find much here. What you will find is a lot of good programming information to kick-start you into the world of iPhone/iPod Touch software development.
Below are some sample screen shots I did on my iPhone.
You can click on it to see it in more detail:
So, how do you do screen shots on your iPhone or your iPod Touch? The hard way is to attach your iPhone to your Mac, fire up XCode, open the Organizer window and use the screen shot tab. The problems with this method are obvious:
You can only do this with a Mac.
Your iPhone/iPod Touch has to be tethered to your computer.
You have to load XCode and bring up the Oganizer window.
The Better Way A nice nifty feature that I found out about for my iPhone to do a screen shot (a little bird told me that this feature was available starting in iPhone OS 2.2):
Navigate on your iPhone/iPod Touch to a screen you want to create a screen shot of.
Hold down the Wake/Sleep button on the top of your iPhone.
While holding down the Wake/Sleep button, press the Home button (just below the screen) and release both buttons.
The screen will flash white, and, if the phone is not in silent mode, you will hear an SLR camera type noise.
Any screen shots you took this way will now be in your iPhone Photo Album! Just go into the Photo Album app like you normally would, and go to the end of your photos!
Using Those Photos
You may be completely satisfied with just looking at your screen shot handiwork inside of the iPhone Photo Album. But I think I can make a good guess this is not the case. Chances are you will want to add these pics to documentation, a web site, maybe even a blog (like I am doing right now).
If you sync up your phone on a Mac when you dock, the photos will be synced into iPhoto and then you can go from there. But another quicker way that needs no connecting and no Mac is to email the photo to yourself.
Get into the Photo Album app on your iPhone and bring up the desired screen shot.
In the lower left hand corner will be a button for sending emails. Tap it!
You will see your screen look like something to the left. Tap the Email Photo button.
You will see an email be generated with the screen shot in it.
Make sure that the from and to email addresses are there and accurate. And Send!
Finally, on your computer, open the email and save the picture attachment to your hard drive. You may want to tweek it in a graphics program such as Photoshop.
Now you can:
Add the screen shot to a document such as a Word document.
Upload it and add it to a blog post (like I'm doing here).
Upload it to your web server, etc.
In Closing Finally, I leave you with one funny side effect of doing screen shots like this:
If you are browsing those screen shots in the Photo Album, you just might get confused and forget that you are in the photo album and try pressing "buttons" and wonder why they don't work! This can be good for pulling some pratical jokes on your friends!
Steve Wozniak, the co-founder of Apple, has been complaining about how closed the iPhone is. I just think about him and Steve Jobs starting the company together in a garage. That was then. Now, today, who's probably setting the tone, establishing the vision of the iPhone? Steve Jobs. Who gets up in front of crowds and demonstrates the latest features? Steve Jobs.
I'm guessing when they started out together they were probably pretty good friends. I wonder, do they talk to each other anymore? Do they go to the same parties?
I wonder if they've talked about the direction of the company mano-o-mano.
I know one thing: I'm too chicken to unlock my iPhone! And though the jail-break stuff is cool, I, again, am too chicken to mess with this stuff. My hope lies in announcements of a future SDK in '08.
A few times lately I've forgotten to bring my iPhone with me (its in my pocket right now). My wife has been suprised by this. More than once she's said: "Have you forgotten your girlfriend?"
I must admit the intense infatuation is pretty much over for now. Now my phone and I have a more low-key relationship! It is definitely an awesome mobile phone. I still can't wait to see what Apple comes up with for developers at the beginning of '08. But I'm not draining down the battery like I used to.
I did watch "Meet The Robinsons" on my iPhone. It's a Disney movie I bought and downloaded off the iTunes store. It was fun. And the quality of the video output and sound is great. But watching video on it has already become sort of "been there... done that."
Well, it looks like the iPhone won't meet all my emotional needs! It's just a machine designed by some creative people after all. Well, now I can move on and have a more mature perspective on the iPhone. It's a tool not a Saviour. Should I change the name of this blog to reflect my new attitude?
You may have noticed that when you tap a link on a web page in Safari on your iPhone that it lightlights the area a light gray. For normal web pages this might be okay. I mean, it's nice to get a visual queue that the page is responding.
But let's suppose that you want to control the highlighting. And you don't like Apple's light gray color. Maybe you want to do some super-cool highlight routine controlled by a Javascript routine, or you want to do things the same way but you want the color to be blue or something. How do you:
Change the highlight color, or...
Get rid of Safari automatically highlighting your tab all-together?
-webkit-tap-highlight-color:
I'm a control-freak when it comes to programming so when I saw this I was like really happy! If you use the rgb() function with the fourth parameter, you can set the opacity. Setting it to zero hides the highlighting.
To see Apple's documentation on this CSS tag with examples click here.
Yesterday MacWorld's Dan Moren posted this entry: 3G iPhone Getting Closer to Reality. One of the big beefs with 3G is how much energy it consumes. It goes on to talk about how a new 3G chip from Broadcom uses less energy.
Now, we don't know for sure if this chip would "do the trick" for the iPhone. Or if it would fit in the case with all the other stuff, etc. We don't even know concretely if Apple will make a 3G phone. I would say it is highly probable that they will make a 3G iPhone eventually. It is likely that they will make a 3G iPhone. I guess I find it humorous that the title is 3G iPhone Getting Closer to Reality when really, most likely no one outside of Apple knows this as gospel truth. I think I would have called it something like: 3G iPhone Possibly Getting Closer to Reality.
One thing Dan mentions is "and the lack of widespread availability of 3G networks in the US" as a reason Apple didn't go with it here. This is something Apple really has no control over. The phone companies (in this case AT&T) have to provide the better coverage. I can tell you its not as simple as telling your engineers: "Ok have all the 3G networks up by the end of the week." All the equipment needed to setup the network costs money. And, allot of time and man-power is needed to install and test those new network nodes. This isn't setting up a small LAN in a local business. This is an ongoing task that has many people working on it. When will 3G networks be ubiquitous in the United States? I don't know. My point is though, even if Apple came out with a 3G iPhone tomorrow with good battery life doesn't mean things would be better (near term) they might actually get worse!
It will be fun to see this all play out over the next couple years!
MacWorld had this post today. This really sounds good! I'm hoping there will be flexibility of say coding in C, and still being about to create web apps that can run off line a-la Google Gears type setup. Can you tell? I think I hear the sound of hundreds software developers drooling and panting. At least we have something to look forward to!
Ok, I've been finding alot of useful stuff that Apple did for iPhone 1.1.1 that will help use developers alot! Instead of listing each change in a seperate post, I decided in this post to give you a bulleted run-down that I captured after going through the online documentation that Apple has. Let's look at the new features:
For the viewport meta tag there are two new constants available for you to use: device-width device-height for more info on using them go to this page here and this page here.
The next item doesn't explicitly say that its for 1.1.1, but I've never seen it before. Over on Google Groups, one question has come up on how to keep Safari from creating a phone hyperlink on a number that it thinks is a phone number but is not a phone numer! Introducing the meta tag: format-detection for information on how to use this meta tag, go to this page.
Here's another item not linked explicitly to 1.1.1, linking to a youTube video. Saw some questions in the Google Groups on this. Here is a page that gives you the syntax.
So you have an input form on your web page. And you don't like how mobile Safari either auto-corrects the user's spelling or auto-capitalizes. Or, maybe you want to make sure that one or both of these things happen during text input. iPhone 1.1.1 adds two new attributes you can use on an input tag to address this problem: autocorrect autocapitalize How to use these attributes...
Read some interesting information on one-finger events. What interests me here is the mention of a working onscroll event.
Alright, we know that the onresize event doesn't work properly on the iPhone. Well iPhone 1.1.1 introduces the onorientationchange event to use in your body tag. Why they just didn't make onresize work is beyond me. But at least now we can check this without using setTimeout hacks! More information on this event. Oh yes, here you will find out that they added a new property to the window object: orientation. So, in your event handling routine you can check window.orientation for a value and decide what to do. Cool! Hey it returns the angle in degrees how the user re-oriented their iPhone! Doubly cool!
You might want to check out this list of Supported Events for the iPhone as of 1.1.1.
Well, that is about it. I know they made some CSS changes too but what precisely I do not know. But hey! All this stuff I've bulleted is very good stuff! All you web app developers for the iPhone / iTouch: enjoy!
I am now realizing (via personal experience), that Apple's move to add the wireless iTunes store to the iPhone/iTouch is a very smart move. Although the selections available are limited compared to running iTunes on your PC, it's still a good selection.
I found myself looking for different songs and have purchased/downloaded several. There's a few things I'd like to note here:
I probably would not have purchased these songs if the wireless iTunes store on my iPhone did not exist.
When on a Wifi network, getting new tunes is so easy... increasing the likelihood of a person purchasing music.
Although I purchased several different songs and one album, I didn't break the bank. The prices were reasonable (especially compared to the price of an album at a record store).
Although the purchase I made add up to a small amount of money, multiply that amount times the thousands (or potentially millions) of iPhone owners who will do the same thing!
I'm still hoping that they add audio books to the Wifi iTunes store, we'll see.
Apple has provided a web app directory for the iPhone and iTouch. You can browse applications by Most Recent, Most Popular, Alphabetical, and Staff Picks. I'm adding a section on the left of this blog page to provide you with links there which you can use even when this post has rolled off the bottom.
I noticed that some apps that I've seen listed elsewhere are not included. This is probably due to the flakiness of those apps: i.e.: too buggy or too hard to use. Hopefully the app I'm working on will make it into Apple's web app directory! It should show up under "Most Popular" ... ahem... cough... :)
It's not ready yet! Hopefully it will be ready soon.
I've been doing a little work on my "super-secret" iPhone project and I noticed that my page layout is more messed up than usual. Me-thinks it has something to do with the 1.1.1 update! Alot of the style sheet stuff I used is copied right out off Joe Hewitt's iUI css file. I guess that might mean that iUI got messed up too. I haven't had a chance to bring up the sample on his site on my iPhone.
Looks like I have some style fixin' to do! Fortunately, though it messes stuff up, it doesn't mess things up enough to make the application useless.
I went to the Wisconsin Dells for a long weekend with my wife and a couple we know. We had a good time. I brought my iPhone and showed it off (as best I could). The main problem is that the place we were staying had poor coverage. Barely one bar or the infamous "No Service" message would display in the upper left hand corner of the display.
I did notice someone else chatting away on their cell phone in the cabin across from us with no problems. My best guess: they have a different cellular provider. My wife's plain-jane cell phone had trouble too (but she uses AT&T too).
This is where things get a little strange: We went into town and I expected my coverage to return. It did not. Though my wife's did! That set my mind in motion. What if I cold-booted my iPhone? Turn it completely off, wait abit, and then turn it back on. That did the trick. I now had good signal strength. When I went back to the cabin area out of town though the signal strength went away again.
My conclusion: When using an iPhone in a low or no coverage area, the phone can get confused when entering a good coverage area and behave as if it's still in a low coverage area. This could be a hardware or software issue. I hope it is a software issue because then it can be corrected on our existing phones. At least I can get things jiggered back so they will work by turning the phone completely off and then restarting it! Have you run into anything like this?