It's Brent

Update to iOS Html to Pdf Conversion

My previous post on how to convert or print UIWebView / html / url to pdf has generated a ton of traffic to my site. Lots of Google searches hit my site. I have always wanted to update this code, possibly make it easier to use. Even package it up into a single easy to use class.

Today I’m happy to say that I finally did that. I released BNHtmlPdfKit on GitHub just a little bit ago. BNHtmlPdfKit easily turns HTML data from an HTML string or URL into a PDF file on iOS.

One of the things that always bothered me about my previous solution was the generated PDF files looked absolutely horrible because they were rendered at 72 dpi. I also knew that somehow there must have been a way to get the PDF file to generate using the UIPrintFormatter.

Turns out the solution was a tiny hack. Create a custom UIPrintPageRenderer and override paperRect and printableRect. This will cause the UIPrintFormatter to return a pageCount as well as render the document.

Check out the Readme and feel free to fork the project!

Hacking My Garage With A Raspberry Pi

Several months ago our Craftsman garage door openers stopped responding to our remotes. I tried everything I could think of to fix this problem, short of buying anything new. Garage door opener parts are expensive, to the point buying new openers is a better option.

After much research I found out that RF interference was the issue. No new remote or logic board was going to solve the issue, even getting new openers wouldn’t solve the issue.

By knowing the wall switch which, still worked, simply closes the circuit I set out for a wireless solution. I wanted to try my hand at an Arduino, but getting WiFi to one isn’t cheap. I then discovered the Raspberry Pi had programmable pins. Getting wireless to the Pi was nearly $80 cheaper. I soon placed an order on Amazon for all my parts.

After getting the parts in I wrote a quick node.js app that serves a single page and also has a 2 backend requests to open each garage. I also quickly wrote an iOS app as well. I’m using Forever to make sure the app stays up.

The only issue I came across was that the relay I bought turned on when firing low, and off when high. The Raspberry Pi has a default state of low, but the GPIO pins are set to input mode so the relay doesn’t immediately fire until the pin is set for output.

As far as wiring goes, I have 2 sets of door switches. The regular wall switches that came with the openers which are right next to each other, then a separate set of switches wired in another part of the garage. I went to Lowes and got some Alarm Wire (it has 4 wires inside of it), this made me only have to make one run from the Pi. I just connected my wires to the back of the wall switches using the COM and NO ports from the relays.

I have open sources the node.js app at brentnycum/garage-node. I have also open sourced the iOS app at brentnycum/garage-ios. There isn’t much to learn from these projects except using node.js and the GPIO pins on a Raspberry Pi. You can find a picture of the built product from my tweet.

A picture of the device put together can be found in my tweet.

How I Grew As A Programmer in 2012

Learning to be a better, faster, and more efficient programmer is difficult when you act like you already are. To become a better programmer I had to look from the outside at myself and pick apart my flaws that I didn’t see in front of my face. Even after programming for over 13 years there is still plenty of room to grow.

Early Bird Gets The Worm

Since I started working from home with my current job 3 years ago I’ve been a little lazy with my mornings. The morning is my absolute most productive time of the day. At my previous office job I would be one of the first to arrive, after waking up to cook an awesome breakfast. Before this year I was barely able to get to the other side of the house by 8. While I’m still not getting up as early as I’d like, I’m working on it. I’ve gained more of my mornings back, and as a result gained a lot more productivity.

Getting Things Done

I was not a full follower of the whole GTD thing. In fact I’m not an Scrum / Agile type person either. Most of my projects for my job are me working alone, which probably lead to this. In the past my list of things to do has been kept in my head as I have a pretty good memory. Keeping this list in my head has gotten harder as I’ve gotten older and had a kid. The best solution I have found has been Trello. Working as a consultant with many clients and even more projects, it’s difficult to find project management software that doesn’t charge an arm and a leg for a high amount of projects. Trello is currently still free for an unlimited number of projects.

Reading Later

There have been several read it later apps pop up, I immediately skipped these. Earlier in the year Read it Later became Pocket, and went free. I gave it a shot. By pushing all the articles I found during the day while waiting on compiles to reading at night, it felt as if I gained an extra hour a day.

No Amount of Help Is Too Small

Not committing to open source projects has been a weakness of mine. It took me a while to realize that I don’t have to implement full blown features to help out on an open source project, fixing trivial bugs is helpful. There is no patch too small.

Changing of Text Editors

As a programmer changing text editors is a big deal, so for the first time since 2005 I have changed text editors. I switched from TextMate to Sublime Text. I used TextMate to get me through my Bachelors and Masters, then continued to use TextMate into my professional career. So even thinking of switching was a big deal. I tried out Sublime and never looked back, it’s speed and customizability won me over.

Skipping Frameworks

There are tons of frameworks out there that make our jobs much simpler. In the past I’ve been quick to jump to use some frameworks, now I have apps that are fully relient upon code that isn’t maintained anymore. I built several iOS apps using Three20 in years past, now Three20 has pretty much gone of the way of the Dodo. When I originally started using Three20, development was full speed ahead and not slowing down plus Facebook was behind it. Three20 breaks, and breaks a lot these days. I’ve patched things locally, but they are mere bandaids on a large wound. Stripping out Three20 from these apps would take more time than it’s worth. Now I weigh my decisions on using any framework.

Just Buy the $2.99 App

I have a bad habit of anytime that I see an app that I like, I feel I need to build it myself instead of paying for it. Cutting out the features I don’t need and shoving in my own. Now, unless it’s something I can complete in 5 minutes, it’s worth more to spend $2.99 and go about my day.

Side Projects

I have always kept a ton of side projects going, mainly to myself. Most never see the light of day, and most I never use again. I’m now starting a rule that if I can’t open source it or make money off of it, then I will not work on it. I have wasted too many hours of my life that I will never get back on these projects. While every project has been enjoying, there never has been much gain for me or for anyone else.

My Daughter

Having my daughter last September has made me think a lot about the future. I no longer have just myself, or my wife to worry about. I have someone who is dependent upon me to provide everything they need. She has a long ways to go. I want to make sure she has every chance in life, and gets as much education as she can.

To provide these things for her, I can’t help but always be a better programmer than I was the day before.

Switching to Jekyll

After over 5 years of running Wordpress for my blog I’ve decided to hang it up. Wordpress is nothing short of great, but it is overkill for what I need. If you look at my archives it’s not like I have written to the lengths of a novel. It’s taxing to run a database for that. Using Wordpress for client’s sites has been great and offered an easy way for them to be able to change information themselves, and I will probably continue to use it in that regard. So long and farewall my good friend. Welcome to my new friend, Jekyll.

Hopefully this will finally push me to start writing again. I have a few posts that I’d love to write.

Ember Nycum

Our daughter, Ember Nycum, was born on September 8th. Check out http://embernycum.com for more pictures and information. Yes, I'm a proud geek dad.

Ember Nycum

Bouncer on GitHub

Created my first jQuery plugin and put it on GitHub tonight. It’s called Bouncer. Bouncer is a plugin that is designed to enforce rules on your input fields in much the same way a bouncer would serve at a club. With Bouncer you can set which and which type of characters are allowed or disallowed, as well as imposing a max limit of characters.

github.com/brentnycum/bouncer

I have been wanting to learn jQuery a little bit more and thought this was something I could easily see myself using a lot. I seem to only use ready made plugins in my projects and never touch it more than binding events to simple actions. Fork it and improve it if you want, willing to accept Pull Requests.

Printing / Converting UIWebView to PDF

I had a client that requested printing in their iPad app, which is no problem now with iOS 4. The app was a set of forms with inputs like text fields, switches, etc. Pretty standard stuff. I decided the easy way with so much dynamic content was to render everything to HTML and use UIMarkupTextPrintFormatter. This would handle displaying text without calculating metrics on everything at the very least. Easy enough and it worked well. Then the client also wanted to be able to print to PDF and email the document. This is where the fun started.

I figured that I would be able to use the same UIMarkupTextPrintFormatter to generate out my PDF for me, after all it was a UIPrintFormatter subclass. UIPrintFormatter contains the method, - (void)drawInRect:(CGRect)rect forPageAtIndex:(NSInteger)pageIndex. I played around and got nothing but blank pages. Even the pageCount property on my UIMarkupTextPrintFormatter was returning 0. After a bunch of Google searches I still kept coming back to the same question on StackOverflow. Which the answer seemed to suggest that nothing is drawn till the system takes over.

Next plan of action was to see if I could convert a UIWebView to PDF. I was brought back once again to another question on StackOverflow. Which technically works, but doesn’t really handle multiple pages. This is when I decided to roll my own solution.

First thing, I need my HTML, nothing fancy here just a NSString. Next I need to create a UIWebView and load it with my HTML string. I also need a UIWebViewDelegate. We are going to assume that we are printing on a 8.5” x 11” sheet of paper, using 1” margins all around. So 6.5 * 72 for width and 9 * 72 for height.

NSString *html = ...;

UIWebView *webView = [[UIWebView alloc] initWithFrame: CGRectMake(0, 0, 6.5 * 72, 9 * 72)];
[webView setDelegate: self];
[webView loadHTMLString: html baseURL: nil];

I needed to make a UIWebViewDelegate because if we try to do anything with our UIWebView now, it would still be empty. The system needs to parse and render our HTML. Now we need to implement the -(void)webViewDidFinishLoad:(UIWebView *)webView method in our delegate. This will let us know when the system is done rendering. The first thing we will do is get the height of our UIWebView. I tried adding the heights of the UIWebView subviews but it was never quite right, so I decided to use good ol’ JavaScript. We also have to make sure we aren’t drawing beyond the height of our HTML or else we get that grey background you are used to when scrolling beyond the bounds of the page in Mobile Safari. Next we need to change the currentOffset of the UIWebView for each page, which is now kind of a hack using the lastObject of the subviews which should be a UIScrollView. Then lastly render.

-(void)webViewDidFinishLoad:(UIWebView *)webView {
	// Get the height of our webView
	NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; 

	int height = [heightStr intValue];

	// Get the number of pages needed to print. 9 * 72 = 648
	int pages = ceil(height / 648.0);

	NSMutableData *pdfData = [NSMutableData data];
	UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );

	for (int i = 0; i < pages; i++) {
		// Check to see if page draws more than the height of the UIWebView
		if ((i+1) * 648 > height) {
			CGRect f = [webView frame];
			f.size.height -= (((i+1) * 648.0) - height);
			[webView setFrame: f];
		}

		UIGraphicsBeginPDFPage();
		CGContextRef currentContext = UIGraphicsGetCurrentContext();
		CGContextTranslateCTM(currentContext, 72, 72); // Translate for 1" margins
		[[[webView subviews] lastObject] setContentOffset:CGPointMake(0, 648 * i) animated:NO];
		[webView.layer renderInContext:currentContext];
	}

	UIGraphicsEndPDFContext();
	
	...
}

From here you can use our NSData object pdfData to save out to file, or perhaps in my case attach to an email.

Now as the note at the beginning of the post said, this isn’t an ideal solution. The generated content doesn’t look the best but it works. I could have done the better thing and drawn out all of my content using Core Graphics / Quartz.

CSC 490/690 - Development for iOS and Android

This summer I will be teaching a course at Louisiana State Univeristy in Shreveport titled Mobile Programming for iOS and Android. This class will cover the basics of getting you up and running to create and release mobile applications. I will cover the basics of Objective-C, the development tools for both platforms, using standard controls and features, and releasing to the app store / market place. Along with learning some fun things along the way like third party frameworks that make development faster and easier. Click on the image above to view the PDF flyer for the course.

NISBRE Poster

The following is the abstract to a poster that I am an author on being presented at National IDeA Symposium of Biomedical Research Excellence (NISBRE) August 6 - 9 in Washington D.C.

Neural Network Enhanced Visualization of High-Dimensional Data

Background and Objective

Large amounts of high-dimensional data not only create the need for the analysis of the data and interpretation of results, but also the need for the development of tools and methods that can handle such data. Many techniques are graphical in nature with ability to represent a small number of variables at a time. Application of information visualizations using neural network techniques enhance knowledge extraction and are targeted towards complex data and provide for a very small, if any, loss of information.

Methods

The algorithms are based on a self-organizing map (SOM) algorithm and are implemented in C/C++ programming language using OpenMP (shared memory) and MPI 2.0 (distributed memory) libraries for high-performance computing.

I'm Brent Nycum, a software developer living in Shreveport, LA with my wife, daughter, and two dogs. I have a passion for creating great software for Mac, iPhone / iPad & Web. Find out more about me.