Nick Harris

Numbers as Unique ID’s

leave a comment »

Brent Simmons talking about sync for Vesper:

Here’s the thing: unique IDs for notes and users are 64-bit integers in my system.

This actually surprised me a bit. My old co-worker, Brian Reischl on both the NewsGator RSS Sync platform as well as Glassboard, tweeted this reply:

The reason we mandated strings is because we learned a tough lesson with the NewsGator platform that broke most of our client apps including mine, NewsGator Inbox. I know FeedDemon was also affected but perhaps NetNewsWire was not, so maybe that’s why Brent didn’t feel the effect of this issue like the rest of us did.

The Day Sync Died

One day in the NewsGator office we all started to notice that our web app was no longer working correctly. I looked at NewsGator Inbox and noticed the same thing. We quickly discovered that our internal unique id assigned to each blog post in the system had become too large for the integer type we were using and had in our documentation. We had to mad scramble to patch the database, the web app and the client apps. I don’t remember exactly what the fix was, perhaps Brian does, but the lesson we both learned was to mandate strings for unique ID’s.

Brent had this thought, but dismissed it based on database bloat and inelegance. That’s a silly argument to me. As well as Brent’s other thought of leaving it to a future platform team to figure out when it becomes a problem. You see the problem now, fix it in a way so that its never a problem in the future.

Imagine if the issue does come up in the future and part of the solution is a client side code change. If the problem isn’t noticed way before it happens, your app could be broken for days while waiting for Apple review. Even if you contact Apple and push the bug fix version through, your users are still out of luck for some amount of time.

As someone who has dealt with this situation in a real world scenario, my suggestion would be to use strings as unique ID’s even if its inelegant and causes some minor database bloat. Its a good trade off to not have to worry about the problem in the future.

Update

I should note that we had two other reasons for using strings for unique ID’s.

The first was to obfuscate any REST API calls so that guessing a number wouldn’t somehow get you access to data you weren’t suppose to see. Our security infrastructure rendered this issue moot.

The second was the idea that a client shouldn’t care what’s in a unique ID. The client should just treat the ID as an opaque string. Should the server ever need to encode additional data into an ID, which the NewsGator Platform eventually needed for performance, it shouldn’t effect how clients interact with that ID. I realize Vesper generates some ID’s on the client (which I find to be an intriguing design decision) so this concern doesn’t apply, but I wanted to further explain our approach.

Written by Nick Harris

April 14, 2014 at 5:35 pm

Posted in Uncategorized

The Night I Rocked Out With Kim Deal

leave a comment »

I grew up in Dayton, Ohio.

When I was 17, I worked at a restaurant called Friendly’s. My friend Mike and I scooped ice cream while my other friend Eric was a line cook. We worked with this other line cook named Ben Schelker.

Ben was 10 years older then us and was in a local band called Candyass. His previous band, The Oxymorons, was fairly well known in Dayton so Candyass was being invited onto billings with major up and coming bands. One of the first Candyass shows I went to they opened up for a band named Sebadoh at a strip mall club less then a mile from my parents house.

Dayton at the time was being compared to the next Seattle for its music scene. We had the likes of Brainiac and Real Lulu tearing up the bars around the University of Dayton ghetto. We also had a band named Guided by Voices who were starting to see some real commercial success outside of Ohio.

Ben was friends with Robert Pollard and was asked to join a multi band billing at a jazz club in Dayton.

Benefit for the Winos
June 2nd, 1995
Gilly’s Jazz – Dayton, Ohio
Ticket Price: $8

Eric, Mike and I bought our tickets and headed into the show. We knew Candyass and GBV were on the bill, but there was another band opening named Tammy and the Amps.

As soon as they hit the stage (with a half empty club) this was our conversation:
“Is that Kim Deal?”
“No… Well..”
“That guitar case has Breeders spray painted on it.”
“Yep. That’s Kim Deal.”

Kim and her twin sister Kelly are from Dayton. They had a band called The Breeders. Kim had spent a lot of time in Boston with another band she had founded called The Pixies but both were now back in town. Kelly had just been busted for heroin so the Breeders were no more (at least at that time). In response, Kim started Tammy and the Amps. This show turned out to be their first major gig. They were awesome.

Candyass played after. It was always fun to watch Ben play. He was a damn fine rocker.

The last band was GBV and after Ben’s set he met up with my friends and I. As we were waiting for GBV to start, another friend of his named Kim joined us.

Kim Deal. And she hung out with us for the entire Guided by Voices set.

I remember standing there, a 17 year old kid going into his senior year in high school thinking: “You were in The Pixies. You were on David Letterman. You toured with U2. How am I hanging out with you?”

Infamy
GBV was already known for their drunkenness during shows. This show was over the top. People were jumping on stage and singing the songs themselves. Even Ben got into the action.

At one point, Robert Pollard was laying on his back “signing”.

My friends and I were all sober and in the middle of a drunk rock show meltdown.

A local band beat writer for the Dayton Daily News was at the show. He was an obvious fan but his review, which was printed two days later, tore into the show as the worst and an embarrassment to the band.

Guided by Voices, having a great sense of humor, bootlegged the show on vinyl with the DDN review on the jacket. It’s a very sought after GBV bootleg.

For me, I’ll always remember it as the night I rocked out with Kim Deal.

One of the best nights of my life.

Guided by voices benefit for winos article

via http://www.gbvdb.com/album.asp?albumid=1005

 

Written by Nick Harris

April 10, 2014 at 4:48 am

Posted in Uncategorized

KIS My YAGNI

leave a comment »

Rudy Lacovara’s Smart Guy Disease post is a fantastic read. I’ve encountered many of those situations myself, but when you think about it in the context of Scott Hanselman’s Analysis Paralysis: Over-thinking and Knowing Too Much to Just CODE, I think it brings the overall problem more into focus.

I don’t believe that smart, seasoned, experienced programmers create overly complex solutions because they want to appear smart (though admittedly some I’ve met have). I believe Scott’s answer that we over-analyze problems, then over-architect the solution is the real culprit.

When I’m starting on a new piece of code, I often find myself thinking through and solving issues that will most likely never occur. Its a hangover effect from some bad situation I ran into previously that I simply want to avoid again.

For myself, a combination of the solutions from both posts is the best.

YAGNI – Ya Ain’t Gonna Need It

You’re a seasoned, experienced programmer who has seen many pitfalls and issues. That’s awesome. Use that experience to evaluate the actual problem you’re solving now and potential pitfalls that are eminent. Forget the rest. If / when they become problems you can solve them then. You already know how to solve them, but why complicate the problem at hand.

KIS – Keep It Simple

Simple code is easy code. Easy to learn. Easy to maintain. Easy to transfer. If you can’t explain your solution to a programming problem by pointing to well known and accepted coding standards, you most likely over thought the problem and out thought yourself. I love the standard Rudy has:

…your boast should be that your architecture is so well designed that any junior developer can come in off the street, understand the basics in a day or two, and be productive within the week.

That standard is my idea of true programming expertise. Been there. Done that. Made it simple.

Written by Nick Harris

April 3, 2014 at 4:43 am

Posted in Uncategorized

Full Stack App Developers

with one comment

I enjoyed reading Justin Williams “The Parts of Your Platform”. It’s a good rundown of how an indie developer (or small team) can leverage the tools available to them in todays world to build every layer of a software product. What’s more interesting to me is the term “Full Stack App Developer” and the reaction by some who seem to think this is a new idea.

The ‘full stack’ paradigm is starting to make its way to app development going forward as well. It’s no longer enough to just know how to write code for a single platform. To be truly relevant and valuable you need to have an understanding of API design and implementation and cloud computing as well.

This is what I’ve been doing throughout my 12+ years as a professional software engineer. When I’m asked to describe my career in a phrase, I say that I’m “well-rounded”. What I mean is that I’ve been a major contributor or owning architect at every layer of a software solution at some point in my career.

In my first professional job after graduating college in 2001, I wrote software that communicated with teleconferencing bridges through raw socket connections. On top of that layer we created a web service (using classic ASP pages and XML-RPC), as well as a Windows Pocket PC app that allowed the host of a conference call to control the conference from their device.

At NewsGator, I started by taking over NewsGator Outlook and integrating the new RSS sync web service, then writing a handful of other RSS desktop apps before joining the platform team and working on the lowest levels of the codebase.

With Glassboard I had the honor of doing File > New on the Microsoft Azure platform, architecting the REST API as well as implementing the 2.0 version of the iOS app.

I recount all this not to brag (though its good to remember your accomplishments), but to counter the thought that the “new full-stack developer” is actually new. For myself and many of my friends and co-workers, its been our template for success.

I’d encourage everyone to be a full stack developer. Not to “adapt or die” but instead to “learn and grow”. Your software (and users) will thank you.

Written by Nick Harris

March 27, 2014 at 3:28 am

Posted in Uncategorized

UIWebView, PDF’s and Page Numbers

with one comment

UIWebView’s are powerful. Not only do they render HTML, they can also render a handful of known file types. One of the most common use cases for this is to display a PDF file. Whether the PDF is loaded from a local file or from a URL, its basically “load and go”.

When viewing a PDF file, the UIWebView has a handy little layover view in the upper left corner that lets the user know what page out of the total number of pages they are viewing.

IOS Simulator Screen shot Mar 17 2014 10 00 10 PM

This works great, until you want that page number in your code.

Problem

In my situation, the code needed to report the current page number elsewhere while the user is scrolling through the document. The UIWebView is already showing the page number so I figured hooking into that would be straight forward.

Nope.

UIWebView has two properties that sound promising, pageLength and pageCount, but as far as I can tell, they aren’t used when previewing a PDF file. A quick web search showed some suggestions, but none of them worked for my situation.

So I dug in a came up with my own solution. I have no idea if this will be valuable to anyone, but it was fun to figure out so I thought I would share.

Solution

This solution makes one big assumption: each page in the document has the same page height. My project can make this assumption. If yours cannot, this solution will not be accurate.

The Math

Page Height = Total Document Height / Total Number of Pages
Current Page Number = Distance Scrolled / Page Height 

There are handful of variables here that we need to find the values for. Lets start with the Total Number of Pages.

Getting the Number of Pages in a PDF Document Using Core Graphics

Lucky for us, Core Graphics has tremendous support for PDFs. You can create a reference to a PDF document using the same NSURL you use to load the PDF into the UIWebView. With that document reference, you can use the CGPDFDocumentGetNumberOfPages function to get its total number of pages:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@“Sample” ofType:@”pdf”];

NSURL *url = [NSURL fileURLWithPath:filePath isDirectory:NO];

CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);

self.pdfPageCount = (int)CGPDFDocumentGetNumberOfPages(pdf);

Getting the Total Document Height

UIWebView uses a UIScrollView internally. A UIScrollView is typically used when the content of a view is too large to show on the screen at one time. It has a property named contentSize which returns the entire size of the view, not just what is visible to the user. Once the PDF document is loaded in the UIWebView, you can use the internal UIScrollView to get the total height of the PDF document:

CGFloat contentHeight = self.webView.scrollView.contentSize.height;

Getting the Distance Scrolled

The last value to figure out is how far a user has scrolled. UIScrollView has another property called contentOffset which is a CGPoint holding how far the user has scrolled from its original point in both the x and y dimensions. We only care about how far down the user has scrolled our PDF document so we can use this code to get the Distance Scrolled value:

float verticalContentOffset = self.webView.scrollView.contentOffset.y;

Updating Values On Scroll

In order to know when a user scrolls a UIWebView all your code needs to do is set itself as the UIScrollView’s delegate then implement scrollViewDidScroll:.

One Small Adjustment

You’ll notice when scrolling through a PDF document that the built in page number view updates not when a page is first visible, but when it consumes over 50% of the total view. Having our code do the same is a simple addition: take the UIWebView’s visible height, divide it by two, then add it to the distance scrolled.

Putting it Together

I put together a sample project you can download, but the code is simple:

- (void)viewDidLoad

{

    [super viewDidLoad];

    

    // set the pdfPafeHeight to -1 so it gets calculated.

    self.pdfPageHeight = -1;

    

    // set the delegate of the UIWebView’s underlying UIScrollView to self.

    self.webView.scrollView.delegate = self;

 

    // create an NSURLRequest to load the PDF file included with the project

    NSString *filePath = [[NSBundlemainBundle] pathForResource:@“Sample” ofType:@”pdf”];

    NSURL *url = [NSURL fileURLWithPath:filePath isDirectory:NO];

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

    

    // create a Core Graphics PDF Document ref using the same NSURL

    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);

    

    // use CGPDFDocumentGetNumberOfPages to get the number of pages in the document

    self.pdfPageCount = (int)CGPDFDocumentGetNumberOfPages(pdf);

    

    // load the PDF file into the UIWebView

    [self.webView loadRequest:urlRequest];

}

 

#pragma UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

    // if pdfPageHeight is -1 it needs to be calculated

    if(self.pdfPageHeight == -1)

    {

        // the page height is calculated by taking the overall size of the UIWebView scrollView content size

        // then dividing it by the number of pages Core Graphics reported for the PDF file being shown

        CGFloat contentHeight = self.webView.scrollView.contentSize.height;

        self.pdfPageHeight = contentHeight / self.pdfPageCount;

        

        // also calculate what half the screen height is. no sense in doing this multiple times.

        self.halfScreenHeight = (self.webView.frame.size.height / 2);

    }

    

    // to calculate the page number, first get how far the user has scrolled

    float verticalContentOffset = self.webView.scrollView.contentOffset.y;

    

    // next add the halfScreenHeight then divide the result by the guesstimated pdfPageHeight

    int pageNumber = ceilf((verticalContentOffset + self.halfScreenHeight) / self.pdfPageHeight);

    

    // finally set the text of the page counter label

    self.pageLabel.text = [NSString stringWithFormat:@"%d of %d", pageNumber, self.pdfPageCount];

}

The Results

The sample project now shows a UIView overlay controlled by the code that shows the same page count as the UIWebView:

IOS Simulator Screen shot Mar 17 2014 9 59 41 PM

Written by Nick Harris

March 18, 2014 at 4:28 am

Posted in Uncategorized

Passwords and Keychain

leave a comment »

I answered my first Stack Overflow question today. I’ve learned so much there over the years and decided its time I start giving back.

My answer is actually a follow-up to Tom Harrington’s after I saw his tweet…

The question was how to store a single entity, in this case a password, using Core Data. Tom’s answer was to not use Core Data at all because its bad design. I completely agree with this. My followup answer was to use Keychain, which is the correct approach.

Passwords are very special data which demand special attention. Storing a password as clear-text in any type of database or storage scheme is a security flaw. If the platform you’re developing for has a well tested and secure way to store a password, use it. For iOS that means using Keychain.

Keychain can be difficult and intimidating to new iOS developers. I believe that’s why some decide to forgo it and instead use things like Core Data or NSUserDefaults. That’s where Buzz Andersen’s STKeychain comes in. Its open source, free to use without restrictions and most importantly tested and used by many iOS apps. Its solid code that makes interfacing with Keychain really simple.

I’ve also used Keychain to do two factor authentication with digital certificates. The code from my 360|iDev session is probably a bit outdated but the concepts are the same.

One other consideration about using Keychain is if you ever need to get your app certified for enterprise security. In my experience building enterprise iOS apps, password security is always asked about. Knowing how Keychain works and passing along Apple documentation answers those questions throughly.

Written by Nick Harris

January 13, 2014 at 3:29 am

Posted in Uncategorized

Unit Testing

leave a comment »

I started a new Xcode project this week to kick the tires of the new unit testing framework built into Xcode 5. I’ve long been an advocate of unit testing. Its great to see it being tightly integrated into Xcode and continuous integration. My impression so far has been very positive. Most of the hoops you needed to jump through in the past are now gone reducing the excuses to not unit test.

If you’re on the fence about unit testing, here’s a few thoughts to consider…

Code Design
Unit testing forces you to rethink how you design your code. I compare it to building a brick wall. Instead of focusing on the entire wall, you concentrate on just a single brick. The brick needs to be crafted well and tested to make sure it won’t fail and bring down the wall. Unit testing forces you to break down complex problems into manageable, understandable and testable pieces.

You’re Not Coding Alone
Most likely you’re working on a project with other developers (if you’re working by yourself you should consider your past self as another developer). Unit tests show other developers how you intended your code to be used. If someone needs to modify code you wrote, your tests will tell them if they are keeping with your intent.

Unit tests are also very handy when coding against web services. Your tests will alert you to changes in the request or response allowing you to adjust your code appropriately.

Reproducing Bugs
Unit testing also involves creating a mock environment for the tests to run against. The mock environment can help you reproduce real world bug reports. Its much easier to tweak a few parameters in a mock environment then to try and recreate a real world situation.

It may seem like you’re writing double the code. That’s because you are, but its well worth the effort.

Here are some unit testing resources from Apple:

Setting up Unit Testing and Continuos Integration
Sample Project 
WWDC Session 409 – Testing in Xcode 5 

Unit Test. You’ll thank yourself later.

Written by Nick Harris

January 7, 2014 at 1:11 am

Posted in Uncategorized

Follow

Get every new post delivered to your Inbox.

Join 476 other followers