Monday, July 25, 2011

Road to devLink: Intro: Candy Store demo app

Update: Here's a list of the following relevant blog posts

  1. Intro: Candy Store demo app
  2. View Controllers, Web View, Services, and Tests
  3. Services & App Store

I have a number of technologies that I am dinking around with at the moment. I also need to prepare some demo code for some upcoming talks at devLink. I would like to try building all of this together. I would also like to do it completely in the open, so that you can watch my progress. This might be a good way to sneak in some posts that I have been meaning to create for some time like coding style and memory management considerations with properties.


I have a general idea of what I want to build. I have a few drawings. I have no idea how this is going to work out. Perhaps I will fly right through the project, learn some great things, give a great talk at devLink, and the end result will prove this initial post to be a prophesy of success. Perhaps I will get a few posts into it and the entire thing will crash and burn. I’ll still give at least a good talk at devLink. Perhaps this experiment will land somewhere in the middle.


Let’s start with a description of the problem that I would like to solve and how that is going to drive my first few decisions. The problem I would like to solve is to build an educationally productive demo app that makes cohesive use of several key technologies. The technologies I would like to incorporate are as follows.


For my own learning:

For my devLink talks:

It is important to keep in mind that my primary goal is to build an app that is an educational aide; both to me and to my “students” at devLink. Therefore, I am very comfortable with a contrived business problem. In fact, I am really fine with that. There are always limitations on using “real world” code from a real client. Instead, since there is no actual business problem, I am free to invent some nonsense and build for it. However, I want to build something that is a bit more polished than a typical demo app. It would be great if, at the end of this, I were able to say the app is more-or-less production ready except for the one caveat that the business problem that is solved is complete bullocks and no one would ever, ever, ever buy this ridiculous app.


So, here goes. My project is called Candy Store. The basic idea is an app where a user can buy, “eat” and trade virtual candy. Here is a first drawing of the basic idea of the app.


As you can see, there are maybe ten or so views. The primary view controller will be a UITabBarController. It will host several customized UIViewControllers, possibly with some UIWebViews, a few UITableViewControllers, and of course some UINavigationControllers.


The local data will be stored in CoreData. The app will call out to my web services and use StoreKit for the IAP stuff. The web services will be written in node.js with a couchdb backend.


So, where do you keep up with my progress? Well, firstly here on this blog. I will amend this post to include links to additional relevant posts. I will be using github for source control. You can find the app and server repositories here:


https://github.com/danielnorton/CandyStore-app

https://github.com/danielnorton/candystore-server


At the time of this writing (July 22, 2011) there is little more in each repository than the initial project setup.


More coming soon.

Friday, July 22, 2011

Notes from Debugging live apps in the App Store

I recently released an app to the App Store. We are getting reports back from users that the app crashes on certain versions of iOS. Following are the steps I took to figure out the cause of the crash.
  • Firstly, I logged in to iTunes Connect
  • clicked "Manage Your Applications" -> MyApp -> View Details -> Crash Reports
  • downloaded the crash report to my local machine and unzipped it
  • opened Xcode -> Organizer -> Archives
  • selected the build that I had submitted to the App Store, control-clicked it, chose Show in Finder
  • control-clicked the .xcarchive file and chose "Show Package Contents"
  • copied the files /dSYMs/myapp.app.dSYM and /Products/Applications/myapp
  • pasted these files in the same directory as the unzipped crash reports. The contents of that folder looked something like this:
MyApp_1-1_2011-07-22_iOS-5-0_Top-Crash_1_1.crash
MyApp_1-1_2011-07-22_iOS-5-0_Top-Crash_1_2.crash
MyApp_1-1_2011-07-22_iOS-5-0_Top-Crash_1_3.crash
myapp.app
myapp.app.dSYM
  • I opened the first crash report, MyApp_1-1_2011-07-22_iOS-5-0_Top-Crash_1_1.crash, in a text editor. Here's what the first little bit looked like:
Date/Time:       2011-07-19 14:44:19.660 -0700
OS Version: iPhone OS X.X (XXXXXXX)
Report Version: 104

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xa0020008
Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x3490807c objc_msgSend + 20
1 Foundation 0x31f2e2a4 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
2 UIKit 0x359071bc -[NSIndexPath(UITableView) row]
3 myapp 0x0000a728 0x0000a728
4 myapp 0x0000a074 0x0000a074
...

Thread 0 is the thread that crashed. Below the statement "Thread 0 Crashed:" you can see the first few lines of the offending backtrace log. Each line is the next level up in the backtrace, also called a stack frame. Stack frame 0 is the message that crashed, it was called by stack frame 1 which was called by stack frame 2, etc.

The first thing I looked for is _my_ code that was nearest the top of the call stack. In this instance, it was stack frame 3. Next to the name of my binary (myapp) are two similar hex numbers. These numbers correspond to the address of the command that is being called in that stack frame. Since frames 0 - 2 are Apple code, I can see the names of the messages. However, the crash was generated from ... somebody's ... iPhone. Since that person does not have my app's debugging symbols loaded on their phone (no one ever would) the crash report only shows the address of the message, not the name. So, my task is to figure out the line of my code that corresponds to address from the crash report. The command line tool 'atos' will help in this instance.
  • copied the address of stack frame 3
  • opened terminal, navigated to the directory
  • issued the following command
atos -o myapp.app/myapp -arch armv7 0x0000a728

This showed me my offending line:
-[MyClass myMessageThatDoesStuff:] (in myapp) (MyClass.m:327)

OK! I could see that the offending line was the message myMessageThatDoesStuff: in MyClass at line 327. I opened my code and had a look
I needed to see what message called myMessageThatDoesStuff:, so I copied the address from stack frame 4 and ran atos again.
atos -o myapp.app/myapp -arch armv7 0x0000a074
with the response of something like:
-[MyOtherClass myOtherMessage:didDoStuff:forUser:] (in myapp) (MyOtherClass.m:231)
So, I inspected MyOtherClass at line 231.

Eventually, this technique helped me to find my code that had released an object and then turned around and tried to use it. derp.

Thursday, May 19, 2011

UIImage and UIColor

I just got asked a question about setting the background of a UISearchBar to an image. Something like this:
When using an image as a repeating pattern, for a background on a view, for instance, check out
+ (UIColor *)colorWithPatternImage:(UIImage *)image
The resulting UIColor is similar to a graphics engine or Photoshop brush loaded with an image.

For the UISearchBar, we found that setting the tint color property to our image brush did not cause the desired effect. So we painted a normal view and slipped it in just above the default view. Here's a snippet of the code. I'll leave it to you to make your own Xcode project, build the NIB and use your own image. I grabbed an outrageous polka dot image from Google image search.
tintyViewController.h
@interface tintyViewController : UIViewController

@property (nonatomic, retain) IBOutlet UISearchBar *searchBar;

@end
tintyViewController.m
#import "tintyViewController.h">@implementation tintyViewController

@synthesize searchBar;


#pragma mark -
#pragma mark NSObject
- (void)dealloc {
[searchBar release];
[super dealloc];
}


#pragma UIViewController
- (void)viewDidLoad {

UIImage *image = [UIImage imageNamed:@"Polka_dots"];
UIColor *col = [UIColor colorWithPatternImage:image];
[searchBar setTintColor:[UIColor purpleColor]];


UIView *searchBack = (UIView *)[searchBar.subviews objectAtIndex:0];
CGRect backFrame = searchBack.frame;
UIView *newBack = [[UIView alloc] initWithFrame:backFrame];
[newBack setBackgroundColor:col];
[searchBar insertSubview:newBack aboveSubview:searchBack];
[newBack release];
}

@end
UPDATE: According to this guy using colorWithPatternImage is dangerous. I profiled the sample in Instruments, got this result (1.65MB):fixed it to not use colorWithPatternImage, profiled it again and got this result(956.82KB). Sure enough, he's right.
Here's the fixed code:tintyViewController.m (try two)
- (void)viewDidLoad {

UIImage *image = [UIImage imageNamed:@"Polka_dots"];
[searchBar setTintColor:[UIColor purpleColor]];

UIView *searchBack = (UIView *)[searchBar.subviews objectAtIndex:0];
CGRect backFrame = searchBack.frame;
UIView *newBack = [[UIView alloc] initWithFrame:backFrame];
UIImageView *imageBack = [[UIImageView alloc] initWithImage:image];
[newBack addSubview:imageBack];
[newBack setClipsToBounds:YES];
[searchBar insertSubview:newBack aboveSubview:searchBack];
[imageBack release];
[newBack release];
}

Sunday, February 13, 2011

iOS encryption and export law

I may need to store passwords on a device for an upcoming iOS app. I would like to encrypt the passwords. I know from previous iTunes Connect submissions that there are questions about government export compliance when using encryption. I intend to sell (free app, actually) the app internationally. I did some research and found the following links. By the sound of it, I _think_ there are exceptions to an intimidating government review process when using encryption for authentication. I hope so.

Export Administration Regulations Database
http://www.access.gpo.gov/bis/ear/ear_data.html

Commerce Control List Supplement No. 1 to Part 774 Category 5 - Info. Security
http://www.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf

Checklist on Encryption and Other “Information Security” Functions
http://www.bis.doc.gov/encryption/checklistinstr.htm
-- "encryption review or notification is NOT required ... for ... limited forms of cryptography, such as authentication ...

Thursday, November 4, 2010

Spirit of Nashville iPhone app

The Spirit of Nashville iPhone app is in the App Store here. It's a mobile representation of some of Nashville's most talented artists and video producers. It's also a fun way to get a little Nashville history. Long before we met the design company, Mary and I fell in love with their work and bough two of their posters for our kitchen. When the project started to gel, I was a bit star struck. It's kind of like stringing guitars for one of your favorite bands. I am very honored to have worked with them to build the app.

Sunday, October 17, 2010

Moving Media

I just bought two external USB drives to serve as a mirrored set. Setting up the RAID was easy using Disk Utility. Now I'm copying over iTunes, iPhoto, etc. Here's some handy instructions for iTunes: http://support.apple.com/kb/ht1449