Showing posts with label ios. Show all posts
Showing posts with label ios. Show all posts

Friday, August 19, 2011

Road to devLink: Installing and Running the Candy Store Server

I just updated the README file in github. Visit the project to download the source. Follow the README to configure the server. If the documentation works, it should guide you step-by-step through getting couchdb installed and configured and getting node solution installed and running.


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


Saturday, August 13, 2011

Road to devLink: Functionally Complete

As of this yesterday (8/12/2011) the Candy Store app is functionally complete. I have several blog posts that I would like to write. Of course, I had hoped that I would write more right in the middle of the process. However, I just got too tangled up in In-App Purchase. Now, I am turning my attention to polishing up the app to use as demo fodder at devLink, and of course to finishing up my slide decks. I have more than enough good material and examples from Candy Store for both sessions of devLink. Here's a few screenshots of the current state of the app.

Future blog posts that I would like to write about Candy Store might include:

  • Pulling down the bits and configuring
    • Unfortunately, you can’t just get my iOS source and run Candy Store. There are a lot of configuration parts outside of just the Xcode project. There is also a server to set up. I will discuss how to set up iTunes Connect, what bits to download to get the server parts working, and configuring the database.
  • How Candy Store uses In-App Purchase
    • Holy cow! IAP is complicated. I think, though, this app has served as a great tool to figure all out all of the intricacies.
  • Candy Store server - node.js & couchdb
    • Really, I didn’t do very much with this. However, I now have a general idea of what node.js capable of and I have a real appreciation of couchdb and the whole NoSQL thing.
  • Coding style
    • I will admit right off the bat that the probability of this post ever happening is pretty low. However, I would like to get my thoughts down on this matter at some point. It is pretty arrogant of me to say this, but I am fond of my Objective-C coding style and conventions. I think they make the code readable and easier to understand.

So there are a few posts. Those are most certainly not going to get written before devLink. So, keep posted for updates after devLink. Between now and the conclusion of devLink (probably right after my talks on Wednesday (8/17) I will put my slide deck online somewhere and link to it from this blog.

Wednesday, July 27, 2011

Road to devLink: Services & App Store

I am writing this post after pushing the following commits:


iOS App: 1cb26d2

Server: e2d8d02


In this commit, I have set up the first redimentary calls from the iOS app to my web service. The web service is written in node.js with a couchdb backend. I think I am going to make this one short, as the content here is more stuff that I am learning that it is stuff that I plan to cover at devLink.


iOS App

I added a lot of code I have been building up over time. I added some categories that I find helpful. I also added some stuff to manage asynchronous NSURLConnection calls. I parse the json to NSDictionarys and NSArrays using this code by Stig Brautaset.


I wrote some unit tests to validate the communication between the iOS app and the service. I was able to sort-of sleep the main thread for the tests for an arbitrary amount of time while it waits for the web call to return. It works, but it feels klunky. At any rate, these are probably more integration tests than real unit tests. Whatevs, I am not too concerned. It gets the job done.


Services

I created a README.md file, you can see that in the github branch here. That has links to the things you will need to install (node.js, npm, and couchbase). It also has some example documents that refer to the Candy Store products for sale from the App Store.


In-App Purchase Items

In iTunes Connect, I created the IAP items that will be used by Candy Store. Though it was a rather tedious effort of entering data in web forms, it was not very difficult. The best resource to guide you through the process is the iTunes Connect Developer Guide. There is also an excellent video from this year’s WWDC on In-App Purchases. Pretty much, these two things are helping me fumble through my app. Both of these resources require you to be registered in the Apple Developer Program.

Tuesday, July 26, 2011

Road to devLink: View Controllers, Web View, Services, and Tests

I am writing this post after pushing the following commits:


iOS App: a862663

Server: N/A


Open Terminal, navigate to a nice place where you would like to store this code, and then perform the following to view this commit

git clone git@github.com:danielnorton/CandyStore-app.git --branch development
cd CandyStore-app/
git checkout a862663

In this commit, I have set up the main view controllers of the iOS app, I have also set up the first vestiges of a few of the services that the app will use, and I have written a few unit tests.


View Controllers

You will see that in MainWindow.xib I have set up a UITabBarController with three tabs. Each tab holds a UINavigationController that then each hold one of the three root view controllers that represent the three distinct sections of the app (My Candy Jar, Candy Shop, and Candy Exchange).


In my devLink session, I will probably discuss this approach. I have the idea in my head that I will have this completed app and then do separate branches or something like that to implement discrete portions of the app that are pertinent to the topic at hand. So, when I am talking about view controllers, I will (in advance) create a branch of the completed app that does not have this initial setup built. Then we can step through creating tab view controllers and navigation controllers, etc. We can see how to wire them up in Interface Builder and talk about how every thing that is done in Interface Builder can be done in code.


Services

As discussed above, there are three tabs. If a user is not currently subscribed to the Candy Exchange and they tap on the Exchange tab, I would like for the app to alert them to visit the Candy Shop and subscribe to the exchange. To facilitate this, I have registered the app delegate as a UITabBarControllerDelegate. That will notify me when the tab is tapped. All of the logic to test the current state of the user’s subscription and decide if the app should notify is contained in a service. At the moment, there isn’t much logic in the service. It will probably get more fleshed out as I add a model and wire up to In-App Purchasing and my own web services. But for now, I can still build the concept that some amount of work needs to be done, and that work needs to be contained in a service. When the complexity comes later, I can change the service without having to do much work (if any) outside of it.


When the service communicates back to the app delegate, the app delegate will display a UIAlertView. When all you need is a to display a modal message to the user, it gets somewhat tedious to fill in the big init method on UIAlertView. For situations like this, I am a big fan of categories. I have created a category for this situation called UIViewController+popup. I will use this at devLink as an example of categories and how to use them.


... hmm ... I have used UIViewController+popup in a number of projects. It’s one of my little “toolbelt items”. While writing this post, the thought occurred to me that tying the popup method to a UIViewController is not necessary ... I will leave it there for now. Maybe somebody at devLink will catch it and start a good discussion.


Tests

I am a big fan of TDD, but to be honest, I am not rigorous about using it. Additionally, I don’t find the testing tools built in to Xcode to be very good. The mocking tools I see out there aren’t terribly impressive to me, and I have yet to find an IoC container / framework. So, I really don’t write a lot of iOS unit tests. But since part of this project is for my own education, I am going to make a new concerted effort. Since the services I am writing at the moment are still self contained this is working out pretty well. Here is an example of a test and, as tests go, an example of how to use one of my services (with a huge name that I don’t like typing over and over).

- (void)testShouldNotAlertUserPurchaseExchange_IncrementThree {

ExchangeSubscriptionNotificationService *service = [[ExchangeSubscriptionNotificationService alloc] init];

[service reset];
service.counter++;
service.counter++;
BOOL shouldNotify = service.shouldNotify;
[service release];

STAssertFalse(shouldNotify, @"should not notify.");
}

When I get a little meatier code, I intend on writing a post about my preferred coding style and how I like to structure the contents of the .m and .h files. service.counter++; violates my preferred style, but it works in this instance so I am not going to get all excited. My preferred style would end up as something like: [server setCounter:service.counter + 1]; which is kind of ugly in this particular scenario.


Web View

If a user has not yet purchased any candy, instead of showing an empty list for the Candy Jar view controller (the first tab), I would like to show a welcome view. I thought it might be helpful to demonstrate the use of a UIWebView in showing this welcome message. I wanted to build a single ... welcome.html ... file to embed in the app. I fumbled along with Safari Mobile CSS stuff and decided to punt and see if I could get some cheats from Dashcode. It turns out I was able to put together a rudimentary welcome view very easily in Dashcode. It only took a few minutes. I kind of liked it. It is not fancy, and it really doesn’t end up looking as whiz-bang as I wanted. I really wanted to build a thing that used multiple colors on a single line of text or something like that which would be difficult with UILabel. But, anyway, it will work for now. I will show that off at devLink. The web view is in My Candy Jar view controller. It includes a good opportunity to demonstrate a simple animated fade in for the web view when it completes loading its content. Also, this view controller will offer a good talking point of how and when to use a UITableViewController and when to use a regular UIViewController that implements UITableViewDelegate and UITableViewDataSource. For this controller, I chose the latter. This will also make a good talking point when introducing protocols and delegation in my devLink talks.


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 ...