Posts Tagged ‘iPhone’

Voices That Matter

Tuesday, July 21st, 2009

A great opportunity for you to hone your iPhone Dev skills is coming up this fall.

Voices That Matter: iPhone Developers Conference is a two day event that will be held in Boston on October 17-18. It will feature talks from some of the most talented and influential iPhone developers, authors, and experts.

Speakers include:

Bill Dudney
Daniel Jalkut
Fraser Speirs
Marcus Zarra
Aaaron Hillegass
Andy Ihnatko
Jon Rentzsch
Steve Kochan
Lee Barney
Daniel Grover
Bill Licea-Kane
August Trometer
Erik Buck
Erica Sadun
and others…

This conference is designed for developers looking for a succinct, easy way to get up to speed on the specific skills needed to build, test and distribute successful applications for the iPhone and iPod touch.

You can attend sessions covering a variety of topics. Choose whatever sessions best fit your individual skill level.

Not only will you learn how to build and ship successful iPhone apps from the great speakers, but also have the chance to meet and network with many other passionate developers like yourself.

Voices That Matter will help you begin developing iPhone apps as quickly and profitably as possible.

I personally am excited to meet the authors who wrote the books from which I learned Cocoa Touch.

If you register before September 12th, you get a $200 discount.

You will get an additional $100 discount, when enter this code: PHBLOG

So if you are thinking about attending, make sure you register while you can still get $300 off.

See you there!

150x150JoinMeiPhoneVTM-1.jpg

PlaceHolder

PlaceHolder

Full Disclosure: I am attending this conference as non-paying guest.

Help out your NSDates

Friday, July 17th, 2009

If you are like me, you really appreciate those nice, neat classes that make your most tedious work a little more bearable.

Billy Gray over at zetetic has done just that with his NSDate+Helper category.

if allows you to completely forget about NSDateFormatter and easily format dates in just about any format you need. it also has some nice convenience methods built in to it.

You can find it on here on GitHub.

Private Properties

Wednesday, July 15th, 2009

Objective-C 2.0 properties are pretty useful.

They not only save you time, but also help “automate” memory management on the iPhone. They save you from screwing up your accessors.

Another benefit, is the orthogonal relationship with dot notation. Dot notation short hand makes it extremely quick to change the state of an ivar with minimal keystrokes.

There are (too) many debates about whether this syntax is “ugly”, “tacked on”, etc… This post makes a great case for using dot notation to differentiate the intent of your code.

In fact, properties used in concert with dot notation are so convenient that there is little excuse to ever access instance variables directly. Another bonus is the “automatic” memory management. Well as automatic as you can expect in a reference counting situation.

You may be opposed to creating a property for an ivar you want to be private since doing so allows unrestricted access. This creates an encapsulation problem, but one that is easily circumvented with another Cocoa trick: anonymous categories.

By declaring your private property within an anonymous category in the implementation file, you effectively hide it from other classes.

It is still true, that you can peek in the implementation and find these hidden properties. But it will be readily apparent to you, or anyone else, that they should be left alone since they reside within the implementation file.

I use this technique to clean up my interface files (along with placing private methods in the category as well). This gives your classes a nice, neat, and more importantly, easy-to-understand interface.

Another issue is when you need to react to state changes of an ivar. This can be mitigated using KVO. By observing properties, you can react easily such changes.

Do you use dot notation or do stick with brackets? Do you create properties for all of your ivars or do you prefer to handle their memory management in the implementation?

Filtering UITableViews: Deleting Multiple UITableViewCells with Animation

Wednesday, June 24th, 2009

If you have done any iPhone development, you are already intimately familiar with table views. They are an integral part of UIKit. They are highly flexible and customizable.

However, making table views work smoothly with anything but a small, simple, static data set can be trying, to say the least.

Many Cocoa developers have come up with solutions to cope with scrolling performance issues, abstracting cell content, creating preference views, adding network awareness, etc…

Ideally much of this functionality should have been included in the Apple frameworks. Alas, this is not the case. We must use third party solutions to fill the gaps or “roll our own” solutions. Sometimes we need to combine the work of several developers into one class.

Recently, I had to create a network aware table view that also supported filtering with animation. Already having setup a UITableViewController for receiving network data, all that was needed was to filter my data and animate the change. Simple.

Well, not really. If you want to perform that nifty animation that Apple uses when viewing missed calls in the phone app, you will most likely need to make some changes to your current design.

To analyze the problem, lets look at the major components: data model, presentation model, view. We will stay away from code, and look more at the design to accomplish this.

For my typical table views, Matt Gallagher’s solution works fantastic.

CellDeletion1.001.png

The diagram is a bit simplistic, but illustrative (In reality, we have nested arrays representing sections within the table). There are two arrays, one to hold our model data and one to hold our presentation data. Also note, the structure of the data model does NOT necessarily need to reflect that of the table, but it seems logical to organize this particular set of data in this manner.

We have created a “Cell Controller” to manage individual UITableViewCell logic. The UITableViewController now only has the responsibility of creating and destroying these Cell Controllers. This moves the UITableViewController one step closer to adhering to SRP.

One undesirable aspect of this methodology is the requirement to instantiate every Cell Controller and link it to its model data upfront. In return you receive better flexibility and encapsulation without a noticeable performance loss (at least with the moderate sized data sets I have so far worked with).

So, lets look at our basic algorithm for creating our Cell Controllers:

  1. Loop through each dictionary in the model data array.
  2. Create a cell controller.
  3. Add a pointer to the dictionary in the cell controller.
  4. Add the cell controller to the array of cell controllers.

This approach works well for static tables and it is easily adapted for network aware tables. For static tables, you set up your relationships once, and your done. For a networked table, you must add a new object to handle network activity. Then they can communicate through any combination of notifications, KVO, and delegate methods.

CellDeletion2.002.png

This is pretty basic, but it is nice to see the relationships laid out.

Now we need to modify our approach to handle filtering. We need a way to represent the full data set and any subsets. Two methods of accomplishing this task are:

  1. Create separate arrays for each set. One for the full data set and one for the filtered set.
  2. Use a flag to mark filtered results.

Flagging is preferable for a two reasons. In reality, the data didn’t change, we just want to update the presentation. In this case we don’t want to actually modify our data. Additionally, it is more difficult to track several arrays and which one is the “real” data.

As we stated earlier, the presentation model needs changed to display the filtered results. In our previous design, the view controller “looked” at the model and created the cell controllers based on the structure of the data. Not much has changed, but now we just need an additional check. So our algorithm could be:

  1. Loop through each dictionary in the data model.
  2. If a dictionary has the flag set,
    • Create a cell controller,
    • Add a pointer to the dictionary in the cell controller,
    • Add the cell controller to the array of cell controllers.
  3. Finally, replace the old (unfiltered) array of cell controllers with the new (filtered) one.

As we connect the Cell Controllers to their corresponding model data, we check our flag. If we did not want to animate our deleted cells collapsing, we would be finished. We need to devise a method tell our table view which cells have been removed (as well as sections).

There are a few ways to accomplish this. In place of the previous algorithm we could do the following:

  1. In our view controller, loop through each cell controller in the array.
  2. If a cell controller’s model dictionary does not have the flag set,
    • Add the cell controller’s index to an indexPathSet to removed from the array
    • Add the cell’s index path to the array of cell paths to be removed from the table.
  3. Remove the cell controllers from the array of cell controllers.
  4. Remove the table view cells from the UITableView.

Not too bad, but we have completely changed our algorithm. Instead of creating an entire new array of cell controllers, we now remove the ones . The motivation behind this, is that we need to give the table view a list of cells to delete. If we had used our previous algorithm, it would have been difficult to produce this list.

We have just one more issue, but you will not discover it until you try to update a remove all the cells in a section and you app crashes. UITableViews do not like empty sections after deletions. So make sure you remove any empty sections as you remove UITableViewCells.

Hopefully this helps some of you get a head start on your table views. We mostly went over design and algorithms which should help you produce your own code and cut down on much of the trial and error that goes into this problem. In a future post, I will include some code as well.

Let me know if you have already coded your own solution to this or are using open source code.

Clang GUI front-end

Wednesday, June 17th, 2009

If you want to run Clang from a GUI you can using the tool at this site:

http://www.karppinen.fi/analysistool/

Not that the scan-build CLI is that intimidating, but if you have any problems getting reports (I just had an issue with a static library), it may help

WWDC thoughts – AT&T

Wednesday, June 10th, 2009

I’m not at WWDC this year, but in light of the announcements, I figured I would chime in on a few things.

I’ll first get my AT&T hatred out of the way. This isn’t exactly developer related, but it is annoying enough that I feel compelled to address it.

I usually have few complaints about AT&T. My reception as been good where I live, customer service has been tolerable, and usually don’t have billing issues. I am not happy with how they gouge for text messaging and internet, but prices aren’t “outrageous”.

But for the first and largest iPhone wireless carrier to be lagging behind the rest of the world is absolutely ridiculous. Their rationale for the MMS delay is like an excuse from a student who didn’t do his homework. The non-answer on tethering is almost better by comparison.

The real reasoning is likely two-fold. First, I am sure they are contemplating how much they can charge us. The other stems from holding a monopoly on iPhone service. They have no motivation to provide good service to retain their iPhone customers. We would never give up our perfect phones and they know it.

Sadly, Apple is also to blame for creating this type of environment. They may have needed to commit to a single carrier in 2 years ago, to obtain certain network guaranties, but those reasons no longer exist.

Just having Verizon, Sprint, or T-Mobile as potential competitors would scare AT&T enough to force better service and competitive prices. From the sound of things, Apple is more than savvy to this fact. I am optimistic that the AT&T’s exclusivity contract will soon be coming to a close.

Getting started with Key-Value Observing

Friday, June 5th, 2009

Getting started in Cocoa can be hard. Just learning the frameworks is a challenge.

Once you get to that point, most or your journey still lies ahead. If you were like me, you probably learned a lot about iPhone programming from online tutorials and books. Then one day, after your 16th tutorial and 3rd book, you looked around and said, “Now what?”

The truth is that technologies like Core Animation, Core Data, and Core Graphics are just tools. They are only a means to an end.

A full toolbox does not make a carpenter good. You still need experience, planning, and vision.

With this in mind, I want to talk about Key-Value Observing. This won’t be a full coding example, per se, but a discussion of how you may use this tool in your code.

Many readers may know the gist of KVO, as well as KVC and bindings. Although bindings are beyond the scope of this post, we will give a quick definition of keys and Key-Value Coding.

KVC is a technology that allows you to access an instance variable by using a string referred to as a key. So using an example:

Interface.png

To access are aptly named dictionary, we can type the two equivalent statements:

kvc.png

They do exactly the same thing, but in KVC we use supply keys using the “valueForKey:” method available to all NSObject subclasses.

To set this property we can use either of the following statements:

kvcgtters.png

This can get more complicated with key paths and some other things. If you would like more information, there are some great tutorials available here and here.

Now to KVO. For those who don’t know, KVO provides a mechanism to receive notifications that an instance variable, has been modified. Of course you know now we will be using keys to do this. First you register as an observer for the key:

setupobserver.png

(Note: I won’t engage in any “self=[super init]” talk here)

We simply registered the class to receive notifications about its own instance variable, but we could have easily selected an ivar of another object.

We also have set some options and a context here, but nothing that need be delved into for our discussion.

To receive the notification, we need to implement one method:

observe.png

Every time the instance variable is changed, this method will be called automagically.

Now that we have a very, very rudimentary understanding of what KVO (and KVC) are, we can begin to talk about how to use them.

One very common use of KVO is model observation. On stack overflow, I see many questions like: “If I have a variable in view controller A, how do I pass it to view controller B?” Of course the real problem is that we are asking the wrong question.

The right question is: “How can I get two view controllers to know about changes of a single variable?”

We know now that we can use KVO. What we want to do is make our views observe our models. By registering view controllers as observers to the model, we can have an unlimited of views showing and/or using the same data. This also gives us well defined MVC boundaries. What’s more, is that we will write almost no code to accomplish this feat.

As you will read elsewhere, KVO has some (few) disadvantages. The one that sticks out, is that it may make your code harder to debug. This is because it is hard to sometimes tell who is observing who. Otherwise this is a very elegant solution that will eliminate some of your glue code.

If you want to go deeper into Key-Value Observing you can read more here, here, here, and of course you can use Apple’s documentation.

What are some uses and patterns of KVO and KVC in your programming?

Cocoa conceptual problems

Monday, June 1st, 2009

After Scott Stevenson put out this question on Twitter and his subsequent blog post, it got me thinking. When I really started digging into Cocoa, I remember staring at UIViewController and UITableViewControler for hours, maybe days. Figuring out what all of those methods did seemed impossible.

In retrospect, I can see these classes represent some of the fundamental design patterns used in Cocoa (touch): delegation, composition, protocols, MVC, nibs, memory management, etc… Once I understood how to use a UITableViewController, I was able to dissect and comprehend the interactions and use of other classes much more easily.

There were many “ah ha” moments when learning those concepts. Previous to iPhone programming, I mainly wrote C and machine level code. It wasn’t my first foray into OOP, but it has been my deepest and most comprehensive.

Learning to write methods that you never actually call yourself was a huge mental hurdle. Splitting class responsibilities according to MVC was logical, but hard to do right (I know, a discussion in itself) the first few times.

Similar to MVC, was memory management. It’s so easy: alloc(or new or copy)+retain = release+autorelease. But when do you actually release? When should you just set to nil? Should you use the accessor or not? Maybe it is best to just use the assign property. Should I create an autorelease pool? Is it best to just “leave the object around” and just handle it if a memory warning pops up. You have a lot of design decisions to make even though the basic premise is simple.

Nibs were simply awesome to layout my views, but learning to hook up the right things and how to use them effectively was no simple task. The outlets and actions themselves weren’t that confusing. The “things you don’t quite have to know until there is a problem” were hard to get my head around. For example: how to load nibs from other nibs, load UINavigationControllers in UITabBarControllers, what the proxy objects actually are, which controller classes to include in the nib, what “really” happens when objects are unarchived, realizing that “initWithCoder:” is called on classes that are defrosted from a nib, how to load UITableViewCells from nibs, etc…  There are many intricacies, most of which you never think about until your app doesn’t work.

After I had some time to think over these problems and Scott’s question, I came to realize (at least for me), Cocoa just took time to learn. Everyone comes from a different background with a different skill set. Add to that, the size and breadth of Cocoa. It should come as no surprise that everyone has to take there knocks when moving to Cocoa and Objective-C, no matter where there coming from (save Next developers).

So, how to wrap this up? To all of the beginner iPhone and Mac developers: know that you have a mountain to climb. Find information where ever you can. The Cocoa development community is great and there is no shortage of resources. Eventually you will reach the “critical mass” of information when you can begin to solve your own problems much more effectively. You will always have more to learn, but will develop an instinct to find what is wrong and begin to ask the right questions.

Is there anything that you think is missing from Scott’s list or that I glossed over? Let me know.

Stack Overflow Addiction

Friday, May 29th, 2009

Until recently I have been, for lack of a better work, selfish in my use of Stack Overflow. I asked many questions, but but gave few answers. I was a good citizen in that I at least searched for answers before I posted a new question. If i did post an answer, It was usually in response to my own questions.

For the past few weeks, my routine has been quite the opposite. I answer as many questions as time allows. To better keep up on the latest questions, I keep a RSS feed of Stack Overflow tags “iPhone” and “iPhone SDK” in Safari’s bookmark bar.

I was reluctant to answer questions because of my (perceived) lack of knowledge. I have since discovered that I am able to help much more often than I thought. It feels good to contribute to the community that has helped me so much.

Even better, answering questions helps me more than asking them. Thinking through the problems of others allows me evaluate my skill set and identify any non-obvious holes in my knowledge.

I highly encourage everyone to get involved in the community. Even if you’re a beginner, you will find you know more than you think. It will only help you improve your problem solving skills and make a few friends in the process.

Moving version control out of Xcode and into Cornerstone

Tuesday, May 26th, 2009

I have been using Xcode’s integrated subversion SCM for several months (against the advice of several articles). Overall, it has been pretty painless. Xcode has a simple set of svn functions, but meets 90% of my needs.  The biggest advantage is the integration within the IDE.  Moreover, if I needed advanced functionality, I could always go to the command line. So, I lived, and loved, with Xcode over the next few months.

I originally decided to try Xcode after some experience with Versions.app, my first SCM experience. Versions is a collaboration between Pico and Sofa. I used Versions during it’s beta. At this time, I was painfully inexperienced with version control. I frequently went back and forth between Versions and Terminal, picking up what I needed along the way.

Eventually, when Versions went 1.0, I made the decision to not purchase it. I could never get Versions to display all of the change logs of a working copy if it hadn’t existed locally since the creation of the repository. As I said, I wasn’t the best with svn at this time. I probably just couldn’t find the control to download the logs from the repository, but it shouldn’t have been that difficult nonetheless. This was something that should have happened “automagically”.  This and a few other quirks didn’t make a good value (for me) over Xcode and the command line.

Flash forward to last week when my repository host, beanstalk, sent a notice they were upgrading all repositories to subversion 1.5. This influenced me to look into upgrading my client side software to use 1.5 as well. At first, I figured I would just patch Xcode to use 1.5, but that seemed unnecessarily complicated. So once again, I decided to try an external solution, but armed with a much better understanding of my work flow and subversion itself.

I downloaded new demos of both Versions and Cornerstone. I had briefly looked at Zennaware‘s offering before, but this time I was able to examine it much more thoroughly. I setup Cornerstone first, and to be honest, I haven’t looked back.

Before I move on, this seems like a good place to get 2 (related) points of contention out of the way: DVCS (Git and Mercurial) and SCM GUIs.

I’ll address my need for a GUI first: I want a seamless and easy way to perform my version control. I already perform enough tasks extraneous to actual programming. I want this part of my workflow to be “point and click”, allowing me to focus more on delivering code.

As far as DVCS: I realize that Git is the new “hotness”. At this time, I operate primarily as a solo shop. Additionally, I now know how to get around svn just fine. For me there is no overwhelming advantage that switching to Git would provide at this time. I am almost never working out of internet range and I don’t collaborate very often. Moreover, there is no “great” GUI for Git yet. I am sure one is eminent, taking in account GitHub as an example of Git’s growth in both marketshare and mindshare.

Back to Cornerstone.

I really like its layout. It matches up extremely well with my “mental” picture version control.

The side bar is split: working copies up top, and repositories on the bottom. This is in contrast to Versions where the repositories are like “folders” and the working copies are subfolders.

voila_capture2

The main window contains a file browser for the selected repository or working copy. When I pressed the space bar, I got a nice surprise: Quick Look. Located along the top of the main window are quick filters for “changed”, “modified”, “unversioned”, etc… These make it super easy to filter a long list of files.

voila_capture5

When you make a commit, Cornerstone automatically asks if you want to begin versioning any files not added to the repository. Sweet.

By clicking a checkbox, you can automatically setup your repository with the default trunk, branches, and tags folders. You can also set ignore files just as easy.

Corenerstone has an entirely different window devoted to file history. Simply select one or more files within the file browser and click the history button. You are then presented with a graphical timeline with a “node” for each past revision. Select any 2 nodes and they are opened for file comparison.

voila_capture6

This presentation does have some drawbacks. Primarily, it just doesn’t scale well. Each file has its own timeline at the top of the window. This works well for a few files, as you can see. View many, though, can be cumbersome. It is possible to view a timeline for just the root folder of the repository which cleans it up a bit, but this wasn’t an immediately obvious solution.

Corenerstone has a decent comaparison engine built into the app. Versions performs its comparisons by using an external app of your choosing. I know many users love this because it enables them to use their favorite comparison tool. Personally, I prefer the speed of Cornerstone’s implementation. With a single click, I can compare any local changes to the latest revision.

When packing a large amount of information in to a GUI, some items will become focal points, while others will move to the periphery. For me, it appears as if commit messages and change sets are presented as second class citizens in this Corenerstone’s UI. They are regulated to a small info pane whose purpose wasn’t readily apparent. Versions, on the other hand, has the change sets and commit messages beautifully laid out in a seperate view.

voila_capture7

I imagine that when I stop working on a 13″ Macbook and have a larger 24″ desktop, it won’t matter so much. This will also allow me to evaluate Cornerstone’s ability to switch froma an all-in-one mode to a multi-window mode, ala Xcode. With a large and/or multi-monitor setup, these issues will likely disappear. My interface complaints are mostly my fault for developing on a contrained consumer laptop.

Speaking of hardware limitations, Cornerstone did not seem to be bothered by the specs of my development machine. Not that you would expect a subversion application to give a modern Mac any such issues. All the same, I haven’t noticed any interface delays, network hangs, excessive disk access, or any other performance problems. This clearly demonstrates the skill, care, and time investment of the developer, who from my understanding operates a single-man shop.

Cornerstone’s interpretation of the svn domain is the most solid out of the apps I have seen (although I admit to not diving as deeply into all other solutions). I am currently running Cornerstone in its demo period and plan to purchase it soon. It has definitely made subversion painless to use while packing a fair amount of power into its interface. If you are seeking a powerful GUI for subversion, Cornerstone is the best you can get.