Farewell (For Now) iDevBlogADay

Hey guys,

I wanted to thank everyone for letting me be a part of the iDevBlogADay community.  You guys have been super supportive and I really appreciate all of the commenting, retweeting, and upvoting of my iDevBlogADay articles.

I have found myself in a position with life (work + family) where I may no longer be able to consistently write a post per week.  So, after 2 months of writing, it is time for me to pass the torch to the next blogger on the list.

I will still continue to blog (and continue my Twitter For Mac Series), so I really encourage you to subscribe to my RSS feed (or Twitter feed).

Thanks again and Happy Coding!

AppBlogger: A Tool For iOS App Developers And Bloggers

Imagine that you have just found the coolest app in the world and just can’t wait to tell all of your followers about it.  So, you head to the admin panel of your blogging engine (hopefully Wordpress) and begin to write your review.  Now, you want to insert some screenshots, icons, descriptions, app store links, etc… So, what do you do?  You head on over to Bing and type in google.com.  Next, you search your app name and hopefully find the iTunes URL so that you can slowly grab some information about the app. #Fail

Dum duh dum duh (trumpet noises)!

Enter AppBlogger.  AppBlogger is a little tool that I have been working on that uses “Instant Search” technology (jquery fanciness) to allow you to instantly search the app store and quickly get the information you need.

How Does It Work? (you say)

As you start typing, AppBlogger makes an asynchronous request to the iTunes web service and pulls a list of applications that match your search terms.  This list is presented as a bunch of icons.  You will then click on one of these icons to pull of the details page of that application.

The details page (see above screenshot) then contains everything you need to write a stellar blog post about that application.  It provides text fields (for easy copy and paste) with icon URLs, download URL, and screenshot URLs.

I have some plans to integrate this in the near future with my Link Share tool to auto generate shortened URLs that contain your affiliate code (so you can make $).  If you have any other suggestions for it, I would love to hear them.

I know many of you are heartbroken and were expecting the next iteration of my Twitter Client For Mac series.  I want you to know, you are not forgotten and I will continue the series next Thursday.  So Stay Tuned!

Check out AppBlogger!

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Image Manipulation: Retrieving And Updating Pixel Values For A UIImage

[caption id=”attachment_1371” align=”alignright” width=”400” caption=”Grayscale Jobs”][/caption]

With the recent success of cool photo manipulation apps such as Camera+ and Instagram, it got me wondering.  How do these photo apps modify the pixel data of the image.

After doing a bit of research on the subject, I found countless posts on Stack Overflow and the Developer forums about various methods to get and set the pixel values of a UIImage.  Most of them unanswered or partially answered.  I tested out many solutions and banged my head on my computer into the whee hours of the morning with no success.  Every solution I tried seemed to completely destroy the image.

It wasn’t until this morning, I had an “aha” moment, changed one line of code and was able to produce a grayscale version of a UIImage.

Having the ability to get and set pixel values of a UIImage is super important if you want to create a photo related app that has “Filters”.  Once you know the basics, you can apply your ninja math skillz to implement cool filter algorithms on the pixels.  Below, I will show you onc such algorithm for converting an image to grayscale (it’s not that clever).

I should note, that a good majority of my code comes from Olie’s solution on this Stack Overflow post.  His example simply returns and array of UIColor objects for a given image.  Mine will modify those colors and write them back to a UIImage.

Converting A UIImage Into A Pixel Array

Here is the first part of our grayscale method.  It is creating a char array from a global UIImage property named workingImage.

- (IBAction) grayscale:(id) sender {
    CGContextRef ctx;
    CGImageRef imageRef = [self.workingImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = malloc(height * width * 4);
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
	bitsPerComponent, bytesPerRow, colorSpace,
	kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);
    .
    .
    .

This is a lot of Core Graphics fanciness that isn’t super important to understand. It’s just getting the RGBA values from the image and writing them into the rawData char array. There are 4 bytes per pixel (red, green, blue, alpha), so this array contains 4 * height * width elements.

Modifying The Pixels of a UIImage

Here is where the magic happens.  You can replace this code with the logic necessary to apply the filter you are making.  Another clever way to approach this would be to pass this code in as a block into the method (I’ll leave that as an exercise for the reader :)).

.
.
.
    int byteIndex = 0;
    for (int ii = 0 ; ii 

The first part is pretty straight forward, we have a for loop that goes from 0 to width * height.  We index into the rawData array using a counter that we increment by 4 each time (remember 4 bytes per pixel).  As you can imagine, the first pixel (rawData[byteIndex]) represents the red pixel, then green for +1, blue for +2, and finally alpha for +3.  Note that the alpha byte is last because kCGImageAlphaPremultipliedLast flag above.

In order to do grayscale, we simple set all of the color values to the average color value.  So, for example the color [218,232,244] (which is the light blue color of the Wordpress editor's toolbar) would be converted to [231,231,231] which is a fairly light gray color.

The most important step that everyone in the forums seemed to miss was casting the new value to a char.  Remember we are using a char array, setting ints as values will generally screw up your image. (This was my "aha" moment that I mentioned above)

Writing The Pixels Back To a UIImage

The final step is to write the pixel data back to a UIImage.  Again, I borrowed some of this code from somewhere else and unfortunately lost the link.  If I find it, I will update the post.

.
.
.
	ctx = CGBitmapContextCreate(rawData,
		CGImageGetWidth( imageRef ),
		CGImageGetHeight( imageRef ),
		8,
		CGImageGetBytesPerRow( imageRef ),
		CGImageGetColorSpace( imageRef ),
		kCGImageAlphaPremultipliedLast ); 

	imageRef = CGBitmapContextCreateImage (ctx);
	UIImage* rawImage = [UIImage imageWithCGImage:imageRef];  

	CGContextRelease(ctx);  

	self.workingImage = rawImage;  

	free(rawData);
}

All we are doing here is creating a new Bitmap Context, writing it to our CGImageRef and constructing a new UIImage from that CGImageRef. Finally, we just update our workingImage with the modified one. Fancy, I know…

Now, much of this code is to work with my example (download below), but it could easily be tweaked to fit within your super awesome photo app. If you have any questions or comments PLEASE leave them here or send them to me on Twitter (but probably leave them here ;) ).

Download The Sample Source Project

* Note on the sample code: Before you give me crap about doing this in the main thread, I know. Don’t do these operation on the main thread. The example is meant to be quick and dirty and by no means is ready for production. Enjoy!

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

What Does Your Workspace Look Like?

I am always very fascinated with the workspaces of others and frequently check out Lifehacker’s posts on their featured workspaces.  So, for this iDevBlogADay post, I thought I would keep it short and simple with a request.  I want to see (and I’m sure others do too) photos of YOUR workspaces (especially those of you with standing desks).

Seeing someone’s work area is especially inspring to me, I love seeing where others create and what they surround themselves with for inspiration and motivation.

So, I’ll start by sharing a photo of my current workspace.  This is where the magic happens…

Within my workspace, you will find:

  • Macbook Pro
  • 24” Apple LED Display
  • iPad with Kensington Keyboard Case
  • Logitec Speakers
  • “Just Like Jesus” Daily Devotional
  • Embark (Target Brand) Fitness Ball
  • Apple wireless keyboard and Magic Mouse
  • Bonsai Tree (coming soon :) )

So there you have, this is my workspace.  Please post a link to your workspace photos or email them to  brandontreb [at] gmail [dot] com and I will append them to this post.  I can’t wait!

Update: Here are some workspaces submitted by readers so far:

[caption id=”” align=”alignnone” width=”498” caption=”Submitted by Roaming Gamer”][/caption]

[caption id=”” align=”alignnone” width=”507” caption=”Submitted by Wayne D”][/caption]

[caption id=”” align=”alignnone” width=”478” caption=”Submitted by dwsjoquist”][/caption]

[caption id=”” align=”alignnone” width=”475” caption=”Submitted by zzelladonatella”][/caption]

[caption id=”” align=”alignnone” width=”480” caption=”Submitted by beninati”][/caption]

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Changing Your Life In 2011

For this blog post, I decided to take a small break from my Twitter Client for Mac tutorial series and discuss something a little more useful ;) .  I felt that a fitness post would be most appropriate around this time of year as all of our “Geek Guts” begin expanding.

My Fitness Story

It’s December 23rd and as we gear up for Christmas, we are also compiling our New Year’s resolutions.  And I’m sure that on most people’s (especially us computer geeks) lists is something related to weight and a healthy lifestyle.  So, I wanted to discuss a little bit about how I made fitness a priority in 2010 and how you can too in 2011.

I began my fitness journey at the beginning of 2010 where I weighed in at 185 lbs and had 19% body fat.  Now, I am in not way saying that I was a thick dude.  I have been blessed with a stellar metabolism, but I definitely didn’t look “in shape”.  More importantly I didn’t have a clue about living a healthy life style.  Being a geek, I sat for hours at my desk every day, eating quick foods and drinking soda.

One night, I saw a commercial for the fitness program P90X and was actually very intrigued.  Don’t worry, I’m not including any affiliate links or things of that sort, so please don’t think I’m trying to sell you on something.  Needless to say, I went on YouTube to find out just how legit this program was.  After some browsing, I was quite impressed and inspired.  It seemed that after 3 short months (seriously no time), people had changed their entire life around in terms of health and fitness.

So, I did what any geek would do and took a visit to the Bay and acquired a copy from some Pirates.  After checking out the program for a week or so, I was hooked and decided to go legit and purchase a copy.  Within 3 months, I began to absolutely LOVE exercising, in fact I became a little addicted to it :/ . I learned how to track what foods I was intaking as well as replaced much of the crappy liquids I was drinking with water.

After completion of the program, I was down to 163lbs with a 12% body fat and have been exercising since. I’m not posting photos because I feel that would be in bad taste.  Check out others on YouTube.

Getting Started

Now, this is a really lengthy intro (kind of sounds spammy too, sorry), but the point is, it’s not hard to get into a healthy routine.  I have talked to tons of people about my “transformation” (I hate this term), and almost every person asks me how I got started.  Everyone either feels that it’s too late for them, or they will start ‘tomorrow’.  So, here is a formula for you lazy geeks (I can call you that because that’s what I was last year :))

  1. Grab a copy of P90X. Again, I’m not a P90X salesmen, Pirate a copy if you have to.  Just get one!  If you want to buy it, it’s about the cost of 3 months of the gym, which coincidentally is the length of the program (90 days) $120
  2. Buy a resistance band - These are everywhere (target, walmart, big 5, etc…) - $20
  3. Buy a pull-up bar - $30
  4. Quit stalling - Start this Monday and let me know how it goes :)

Now, this is just the beginning.  The biggest problem with diets/fitness programs/etc is people don’t look at them as a lifestyle change, they see them as temporary.  People say crap like “I want to be XYZlbs or fit into a size J”.  Don’t do that! Sure these are nice goals to have, but DONT MAKE THEM THE REASON YOU EXERCISE AND EAT HEALTHY.  If you do, you are just setting yourself up to fail.  Exercise and don’t eat crap because you want to be healthy.  Do it because you are sick of being tired and lethargic all the time.

I don’t have time to exercise

Of course you would say that… I did too.  That’s why I love P90X. It’s only 1 hour a day and within that hour, you are told exactly what to do.  I always felt that to exercise, I had to spend hours in the gym, running, lifting, blah blah… No, one hour a day.  I spend that reading Reddit.  Get up an hour earlier, go to bed an hour later.  Stop eating on your lunch break and exercise then.  You can always eat at your desk when you get back.

Staying Motivated

So, you have decided that 2011 is going to be your year; you are going to get in shape.  Here are a few tips to help you stay motivated.

  1. Learn, learn, learn - Just as you spend time learning about new programming languages, or reading about yet another tablet device.  Learn about new things to eat, new exercises to try, new goals.  Whatever, just maintain the excitement by learning new things.
  2. Get others involved - This generally comes naturally.  When others see you getting into shape, they will most likely want to join.  This can be a great motivator, especially when you are feeling burnt out.  Get a workout buddy to go to the gym, run, do P90x, etc… with.
  3. Find healthy things to consume that don’t suck - This is a huge challenge for people starting out.  They think that they have to eat celery and chicken breasts all day.  This is one thing I love about p90x.  It comes with an incredibly (and delicious) diet plan including recipes. In a future post, I’m going to write about a stellar protein smoothie that I have every day.
  4. Get the crap out of your house - I’m serious, you won’t miss it. Cookies, Soda, Doughnuts, whatever…
  5. If you want soda, drink a soda - A can of soda is roughly 120 calories, this isn’t terrible.  But don’t make it a habbit.  Limit yourself and throw away your effin Big Gulp cup!
  6. Eat before you leave your house - this is huge.  If you are hungry and you are out, what do you do? You go scoop up a McFeeces from McDonalds… Instead, eat some lunch meat or whatever before you go run those errands.
  7. Eat frequently with smaller portions - I told my dad that I eat about  5-7 times a day, and he responded with “you’re going to get fat doing that”  Contrary to popular belief, it is far better for you to eat more frequent, smaller meals.  This is tricky when you spend the day in the office.  You have to somewhat plan your day in terms of food. Bring stuff to snack on such as nuts, popcorn, protein bars, and beef jerkey.
  8. Share your success - Blog, Tweet, Facebook, Youtube.  Whatever it is, tell people about it.  Others will surely praise you for this, and you will most likely motivate them. Plus, it will hold you accountable.
  9. Get a good water bottle and take it everywhere - Water is a tricky thing.  It’s so hard to remember to drink enough.  I have found that if I have water in front of me, I will always sip on it, especially when I’m sitting at my desk all day.

To wrap this up, I’m not trying to sell you on P90X or any other fitness program.  I just feel that it will be a killer start and give you all of the tools needed to launch into a healthier, more fit 2011.  Also, you will start seeing results very quickly.

Conclusion and Resources

I hope you have enjoyed this post and I would LOVE to answer questions as well as point to more resources.  I have linked all of the referenced resources below for you to check out.

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

Creating A Twitter Client For OSX – Part 3: Publishing Tweets

Welcome to part 3 of my #iDevblogaday series about creating a Twitter client for OSX

Now that we have some of our UI built, we need to add a key feature to our Twitter client: The ability to write and publish a tweet.  We will be adding a textbox that the user can type their tweet into along with a live character counter to ensure the character length does not go beyond 140 characters.  Finally, we will be using  MGTwitterEngine to publish the tweet to Twitter.

In case you didn’t read it, here is a link to the previous tutorial in this series.  We will be using the interface created in it as a basis for this tutorial.

Updating and Preparing Our Code

Before we jump into the new stuff, I want to back up for a second and do some simple refactoring.  In our last tutorial, we just loaded the new tweets when our application fired up.  That’s great and all, but it’s not reusable.  So, we need to make a class property for our MGTwitterEngine and a method that we can call to refresh the tweets.  This will also come in handy later when we implement an auto refresh feature.

Let’s start by updating our header file TweetsController.h

#import 

@class MGTwitterEngine;

@interface TweetsController : NSViewController{
	IBOutlet NSTableView *tableView;
	NSMutableArray *tweets;
	MGTwitterEngine *twitterEngine;
}

@property (retain) IBOutlet NSTableView *tableView;
@property (retain) NSMutableArray *tweets;
@property (retain) MGTwitterEngine *twitterEngine;

- (void) refreshTweets;

@end

As you can see we have added a few things.  First, at the top we see a forward class declaration for our MGTwitterEngine.  If you recall, forward class declarations are to combat circular imports. Here is a snippet from the objective-c documentation about forward class declarations.

The @class directive minimizes the amount of code seen by the compiler and linker, and is therefore the simplest way to give a forward declaration of a class name. Being simple, it avoids potential problems that may come with importing files that import still other files. For example, if one class declares a statically typed instance variable of another class, and their two interface files import each other, neither class may compile correctly.

Next, we create a property called twitterEngine.  It goes without saying by now that you should synthesize this property and release it in your .m file.  I’m not going to show that code.  Finally, we declare a method called refreshTweets.  This will be the method we will call to when we want to refresh the list of tweets.  At some point we will alter this method to take an additional argument that will allow us to differentiate between timeline, replies, and messages.  For now, we will stick with timeline.

Now let’s take a look at the updates in the .m file.

.
.
.
- (void)awakeFromNib {
	self.tweets = [[NSMutableArray alloc] init];

	OAToken *token = [[OAToken alloc] initWithKey:@""
									  secret:@""];;

	// Put your Twitter username and password here:
	NSString *username = @"brandontreb";
	NSString *consumerKey = @"";
	NSString *consumerSecret = @"";

	// Create a TwitterEngine and set our login details.
	self.twitterEngine = [[[MGTwitterEngine alloc] initWithDelegate:self] autorelease];
	[twitterEngine setUsesSecureConnection:NO];
	[twitterEngine setConsumerKey:consumerKey secret:consumerSecret];
	[twitterEngine setUsername:username];
	[twitterEngine setAccessToken:token];
	[self refreshTweets];
}

- (void) refreshTweets {
	[twitterEngine getHomeTimelineSinceID:0 startingAtPage:0 count:20];
}
.
.
.

So, nothing really new here, we are just moving the scope of our twitter engine out of the awakeFromNib method and creating a reusable way to grab the user’s timeline.  We are now ready to declare our IBOutlets and IBActions for our interface.

Setting Up IBOutlets and IBActions

Two additional IBOutlets will need to be set up for our Twitter client.  The first is an NSTextView in which the user will by composing their Tweet in to.  And the other is an NSTextField that is not editable.  This will essentially be a label that displays the number of remaining characters to the user.

In addition to the IBOutlets, we need an IBAction that responds when the user clicks the Tweet button.

Our TweetsController.h header file should now look like this.

#import 

@class MGTwitterEngine;

@interface TweetsController : NSViewController{
	IBOutlet NSTableView *tableView;
	IBOutlet NSTextView *tweetTextView;
	IBOutlet NSTextField *tweetCountLabel;
	NSMutableArray *tweets;
	MGTwitterEngine *twitterEngine;
}

@property (retain) IBOutlet NSTableView *tableView;
@property (retain) IBOutlet NSTextView *tweetTextView;
@property (retain) IBOutlet NSTextField *tweetCountLabel;
@property (retain) NSMutableArray *tweets;
@property (retain) MGTwitterEngine *twitterEngine;

- (void) refreshTweets;
- (IBAction) tweetButtonClicked:(id) sender;

@end

One other thing that I failed to mention above is we tell our class to implement the NSTextViewDelegate protocol. This will allow us to have a live counter of the characters being entered in our text view.

Now, let’s work on the interface…

Updating The Interface

Open up MainMenu.xib and drag an NSTextView, Label, and Button on to your view resizing as necessary. Your interface should now look something like this:

Make sure that you click on the NSTextView that you added and uncheck the box that says “show vertical scroller”.  Also, drag from the text view to TweetsController to set the delegate.  I found that I had to expand the view tree to get at the TextView as in the screenshot below:

Next, click on  TweetsController in the explorer window and hook up each of the 2 IBOutlets.  Here is a screenshot of the explorer window and the Connections window with the connections made.

Also, you will want to control-click and drag from your button to the TweetsController to hook it up to your tweetButtonClicked IBAction.

You can now close Interface Builder and jump back to the code…

Implementing Live Character Counting

This process is actually pretty simple.  We just need to implement one delegate method of our NSTextView.  Open TweetsController.m and add the following method:

- (BOOL)textView:(NSTextView *)aTextView
   shouldChangeTextInRange:(NSRange)affectedCharRange
   replacementString:(NSString *)replacementString {
	NSString *text = [tweetTextView string];
	int length = [text length] + 1;
	[tweetCountLabel setStringValue:[NSString stringWithFormat:@"%d",(140 - length)]];
	// Allows user to delete characters
	if([replacementString length] == 0) return YES;
	return length 

The shouldChangeTextInRange delegate method gets called every time the user types a character.  We first check the length of the string currently in the box.   1 is added to it since we are looking at adding a potential character.  Next, we update our character label to 140-(length of current string).  Following that is a line to check if the replacement string is 0.  This is needed for when the user presses backspace and they have already entered 140 characters.  The final line will only return true if the character count in the text box is less than 140, otherwise it will prevent the user from typing anything else.

Publishing The Tweet To Twitter

Our final step is to actually publish the tweet to Twitter and update the timeline.  We need to implement the tweetButtonClicked method and update the statusesReceived delegate method.  So in, TweetsController.m, update to the following code:

- (IBAction) tweetButtonClicked:(id) sender {
	[twitterEngine sendUpdate:[tweetTextView string]];
	[tweetTextView setString:@""];
}

#pragma mark -
#pragma mark MGTwitterEngineDelegate
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {

	if([statuses count] == 1) { // when user updates their status
		NSDictionary *tweetDict = [statuses objectAtIndex:0];
		NSString *screenName = [[tweetDict objectForKey:@"user"] objectForKey:@"screen_name"];
		NSString *text = [tweetDict objectForKey:@"text"];
		Tweet *tweet = [[Tweet alloc] init];
		tweet.screenName = screenName;
		tweet.text = text;
		[self.tweets insertObject:tweet atIndex:0];
		[tweet release];
	} else {
		for(NSDictionary *tweetDict in statuses) {
			NSString *screenName = [[tweetDict objectForKey:@"user"] objectForKey:@"screen_name"];
			NSString *text = [tweetDict objectForKey:@"text"];
			Tweet *tweet = [[Tweet alloc] init];
			tweet.screenName = screenName;
			tweet.text = text;
			[self.tweets addObject:tweet];
			[tweet release];
		}
	}

	[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}

First, we see the implementation of our IBAction.  It simply calls one of our super handy methods in MGTwitterEngine.  The sendUpdate method, will asynchronously update your Twitter status and post back to the statusesReceived method with YOUR status info.  After that, we clear the text box that the user typed into.

The statusReceived method gets updated because we need to handle things differently when the user updates their status verses when we are pulling down the timeline.  If there is only one status (ie the user just posted), we want to push it on to the head of the tweets array.  We do this so that it displays at the top of our client as the timeline that comes down from Twitter is ordered from newest to oldest.  Other than that, there are no major changes to this method.

After building and running, your client should now look something like this:

Well, that about does it for today.  I hope you have enjoyed this one.  If you have any comments or questions, feel free to leave them here. You can even write them to me using your new “fancy” Twitter client to @brandontreb.

Download The Source Here

Until next time, happy coding!

—-

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.


Creating A Twitter Client For OSX – Part 2: Displaying Tweets

Welcome to the second installment of my #iDevBlogADay tutorial series entitled “Creating A Twitter Client For OSX”.  In case you missed it, here is a link to the previous tutorial in the series.  From the last tutorial, you should have a basic understanding of the folllowing:

  • Checking out the MGTwitterEngine code from github
  • Setting up Twitter and creating a new application
  • Building and running the MGTwitterEngine
  • Basic usage of the MGTwitterEngine including retrieving Tweets and updating your status

In today’s tutorial, we are going to go a bit further and begin work on our very own Twitter app for OSX.  By the end of this tutorial, you should have a simple OSX application that displays tweets in a table view.

Creating A New Project And Integrating MGTwitter Engine

We will start off by creating a new Cocoa Application.  This will provide us with a simple window that we will later fill with a table.

Now, I’m sure there are several ways we can integrate the MGTwitterEngine framework into the project, but I’m going to go the route that I found to be the easiest. We are going to simply go folder by folder and copy all of the source files into our project.  That way we don’t have to deal with header search paths and all of that fun stuff.

Here are the steps to get MGTwitterEngine into your project.  It was actually much easier to do this, than to build the sample project that came with the source ;) .

  1. Create a new group in your project called MGTwitterEngine
  2. Copy all source files (except AppController.m/h) in the MGTwitterEngine root folder into the group.  (Make sure you tick the box that says “Copy items into destination’s group folder”
  3. Copy the entire TouchJSON folder into the project.  Then, expand it and delete the Support folder from your project (it causes some errors)
  4. Copy the entire oauthconsumer folder into your project.

When you are done, your project directory should look something like this (I made a subgroup called core to put the engine files into).

The last dependency is on the libxml2 framework.  We need to add it to the project.  So, rightclick on the Frameworks folder and click Add -> Existing Frameworks… Search this list for libxml2.dylib and click Add.

Next, we need to set up the header search path to use this library.  Right click on your project and click Get Info.  Scroll down to the cell that’s labeled “Header Search Paths”. Double click in the empty cell on the right, and then click the + button on the next window. Then enter /usr/include/libxml2 into the path and click ok.

At this point, try to build your project.  It may contain a few warnings, but no errors.

Creating The Tweet Model

We could simply take the dictionaries that TouchJSON returns to us, stick them in an array and display them in the table, but that wouldn’t be very clean.  So, we are going to create a simple Tweet model.  Keep in mind, we are only storing the necessary data for this stage in the tutorial.  We will be adding the rest of the data later.

Go to File -> New File and select Objective-C Class.  Name the file Tweet.m. And here is the code:

The header…

// Tweet.h
@interface Tweet : NSObject {
	NSString *screenName;
	NSString *text;
}
@property(retain) NSString *screenName;
@property(retain) NSString *text;
@end

And the source…

// Tweet.m
#import "Tweet.h"
@implementation Tweet
@synthesize screenName;
@synthesize text;
- (void) dealloc {
	[screenName release];
	[text release];
	[super dealloc];
}
@end

Next, we are going to set up our table view that will display the tweets.

Creating An NSTableView And ViewController

So, there are 2 ways to populate a table view in Cocoa.  The “newest” way is to use Cocoa bindings, however we are not going to do that today.  Since I assume most of you are coming from iOS dev, we will stick with the “old Skool” way which is actually quite similar to how the iPhone populates a UITableView.

Start by adding a new Objective-C file to your project called TweetsController. Just take the default subclass of NSObject.  Once it’s added, change it to be a subclass of NSViewController and let it implement NSTableViewDelegate.  Here is what the code for the header file should look like (The NSTableViewDelegate stuff isn’t appear because of this WP plugin I’m using to display code ). :

@interface TweetsController : NSViewController{
	IBOutlet NSTableView *tableView;
	NSMutableArray *tweets;
}
@property (retain) IBOutlet NSTableView *tableView;
@property (retain) NSMutableArray *tweets;
@end

We have an IBOutlet to the table and an array of tweets that will populate the table. Also, make sure to synthesize these properties in the .m file as well as release them in your dealloc method (not created automatically like the iPhone does). We will come back to the implementation of the .m file.

Now, double click on MainMenu.xib opening it up in Interface Builder.  There are a few steps involved here.

  1. Double click on Window in the content explorer and you should see the main application’s window
  2. Drag an NSTableView from the library on to your view and size it accordingly.  By default the NSTableView will have 2 columns, delete on of them and stretch the other the width of the table.
  3. From the library, drag ViewController object into the content explorer.
  4. Click on it and from the top menu click Tools -> Identity Inspector.
  5. In the box that says Class, type in TweetsController.
  6. Right-click drag from your table view to your new Tweets controller to connect both the delegate and datasource (same as you would do for the iPhone)
  7. Finally, drag from the controller to the table view to hook up the tableview outlet.

We are done in interface builder and you can now close it.

Populating The TableView With Tweets

The last steps are to pull the tweets using the MGTwitterEngine and display them in the tableview.  Open up TweetsController.m and let’s add the first bit of code:

#import "TweetsController.h"
#import "MGTwitterEngine.h"
#import "Tweet.h"

@implementation TweetsController

@synthesize tableView;
@synthesize tweets;

- (void)awakeFromNib {
    self.tweets = [[NSMutableArray alloc] init];

    MGTwitterEngine *twitterEngine = [MGTwitterEngine twitterEngineWithDelegate:self];
    OAToken *token = [[OAToken alloc] initWithKey:@"16369316-GgqA00WO0poCAj0XAFhJYDDRthVvWMxTnVyKdfWa1"
										   secret:@"someSecret"];;

	// Put your Twitter username and password here:
    NSString *username = @"brandontreb";
    NSString *consumerKey = @"aKKEsJHTDNsv4xVlMHmMqw";
    NSString *consumerSecret = @"AnotherSecret";

    // Create a TwitterEngine and set our login details.
    twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
    [twitterEngine setUsesSecureConnection:NO];
    [twitterEngine setConsumerKey:consumerKey secret:consumerSecret];
    [twitterEngine setUsername:username];
    [twitterEngine setAccessToken:token];

    [twitterEngine getHomeTimelineSinceID:0 startingAtPage:0 count:20];
}

So we see some of the usual suspects (imports, synthesize, etc…). Now, take a look at the awakeFromNib method. Like on the iPhone, this method fires when this controller is loaded from the nib.  This is where we will initialize our engine, and grab the user’s timeline.  Most of this code should be familiar from the last tutorial.  We have one new addition, and that’s setting ourself as the delegate. MGTwitterEngine has some nice delegate methods that it calls back to when it has grabbed all of the data.  Let’s add that method to our code:

.
.
.
#pragma mark -
#pragma mark MGTwitterEngineDelegate
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {
	for(NSDictionary *tweetDict in statuses) {
		NSString *screenName = [[tweetDict objectForKey:@"user"] objectForKey:@"screen_name"];
		NSString *text = [tweetDict objectForKey:@"text"];
		Tweet *tweet = [[Tweet alloc] init];
		tweet.screenName = screenName;
		tweet.text = text;
		[self.tweets addObject:tweet];
		[tweet release];
	}

	[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}

This method simply returns an NSArray of NSDictionaries containing all of the information about each tweet in the user’s timeline. We loop over this array, build a new Tweet object, and add it to our tweets array. Finally, we reload the table view on the main application’s thread (UI operations should always be done in the main thread).

The last step is to implement the delgate/datasource methods for the tableview that will feed our tweets into it.  Let’s add the final bit of code to TweetsController.m:

the#pragma mark -
#pragma mark TableView Data Source
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
	return [self.tweets count];
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
	return nil;
}

#pragma mark -
#pragma mark TableView Delegate
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
	return 50.0;
}

- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
	Tweet *tweet = [self.tweets objectAtIndex:rowIndex];
	[aCell setTitle:[NSString stringWithFormat:@"%@: %@",tweet.screenName,tweet.text]];
	[aCell setWraps:YES];
}

- (void) dealloc {
	[tableView release];
	[tweets release];
	[super dealloc];
}

These methods should look vaguely familiar to the iOS developer.  The method objectValueForTableColumn is not needed here but is required for a table view datasource so we just make it return nil.  willDisplayCell is very similar to the iOS cellForRowAtIndexPath only this time it passes the cell to us and we do the configuration.  In this case we display the tweet and tell the cell text to wrap.

Finally, we just see our dealloc method for cleanup.

That’s it for the code. Go ahead and hit Build and Run to see what we have created (spoiler alert: look below).

Ok, so it’s not much to look at in its current stage, but we will improve on it.  In the next tutorial, we will be displaying a bit more data as well as adding more functionality.

If you have any questions or comments, please feel free to leave them in the comments section.

Download The Source For This Tutorial

Until next time, happy coding!

Click here to go to part 3

—-

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.


Creating A Twitter Client For OSX - Part 1

With the upcoming release of the Mac App Store, I can only imagine another gold rush is upon us. Clever Indie developers making money hand over fist while the store as well as developers find their identities. With that being said, I feel that there is a serious lack of interesting (maintained) Twitter clients for OSX. I say “maintained” because Tweetie for OSX is just fantastic, however Twitter said they don’t have any plans for it at this time.  So, I want to provide devs with the tools to create an amazing Twitter client for the Mac that I will want to use :)

Quite some time ago, I began (and never completed) a series on writing a Twitter client for OSX. It was very well received by the development community, however once Twitter switched over to OAUTH, I became too lazy to update it :( . So, I figured a tutorial series for #iDevBlogADay would be the perfect opportunity to complete it.

So we are going to start from the ground up. In today’s tutorial, we are going walk through getting the initial resources and setting up Twitter to authenticate our application.  We will also post a basic tweet.

Setting Up Twitter

In order for your application to interface with Twitter, you must register it with them over at http://developer.twitter.com.

  1. Go to http://developer.twitter.com and sign up if needed
  2. Click on Your Apps
  3. Click Register A New App and fill out all of the information about your client
  4. You’re all set!

Getting Necessary Resources

I spent a bit of time researching the various options for handling OAUTH and all of the fun stuff that goes along with Twitter integration and found that MGTwitterEngine was the least painful to implement. I say least painful because it has a few quirks of it’s own along with not having the best documentation in the world.

So after battling for a bit to get the thing compiled, I have figured out the setup process :).  You could also read Matt’s installation instructions, but I will regurgitate them here a little differently and hopefully be more clear.   So here it is:

  1. Make sure you have git installed.  If not, download it for OSX here.
  2. cd to the directory that you want to clone the files to
  3. Clone the MGTwitterEngine repository. Type:
    $ git clone git://github.com/mattgemmell/MGTwitterEngine.git
  4. cd into the MGTwitterEngine folder (we will install the dependancies at this level)
  5. Now install the dependancies (TouchJSON and OAUTHConsumer). Note: There is an option to use yajl (yet another json library), but I found it a pain to integrate, so we will just throw it out.
    $ git clone git://github.com/schwa/TouchJSON.git
    $ git clone git://github.com/ctshryock/oauthconsumer.git

Altogether, this is the order of commands you should have:

$ cd ~/Desktop
$ git clone git://github.com/mattgemmell/MGTwitterEngine.git
$ cd MGTwitterEngine
$ git clone git://github.com/schwa/TouchJSON.git
$ git clone git://github.com/ctshryock/oauthconsumer.git

Building MGTwitterEngine (What a freakin pain)

I find it interesting that this project is riddled with errors directly upon download.  So much work went into it, yet it’s so challenging to get working.

Now open up MGTwitterEngine.xcodeproj.  You will notice that there are quite a few missing files (they show in red).  That’s fine.  DELETE THEM ALL…

  1. Delete the yajl group with everything in it
  2. Delete the Twitter YAJL Parsers group and everything in it
  3. Delete OAToken_KeychainExtensions.m and OAToken_KeychainExtensions.h (they are not used)
  4. Delete CJSONDataSerializer.h and CJSONDataSerializer.m
  5. Delete CSerializedJSONData.h and CSerializedJSONData.m
  6. Click the arrow on the OAuthConsumer group and you will notice that the Crypto is missing.  We still need this group, but it’s in the wrong place. Delete this group and then open up your MGTwitterEngine folder in Finder. Navigate to MGTwitterEngine->oauthconsumer.  Drag the Crypto folder into your project.
  7. We need to change the C Language Dialect to C99.  To do this right click on MGTwitterEngine in XCode and click Get Info.  Scroll down to C Language Dialect and click the drop down changing it to C99
  8. Finally, we need to tell MGTwitterEngine that we want to use TouchJSON instead of yajl.  To do this open up MGTwitterEngineGlobalHeader.h and set TOUCHJSON_AVAILABLE to 1.
  9. If you still have any hair left at this point, click Build and Run to and check out the output in the Console
  10. If you don’t feel like jumping through all of these hoops you can download my MGTwitterEngine project with all of this fun stuff completed. Download it here.

Testing MGTwitterEngine

For today’s tutorial, we will just be displaying our timeline and updating our status using the demo file provided by MGTwitterEngine.  In the next tutorial, we will actually be integrating the engine into a new project.  So, open up AppController.m in the Demo group.  Matt has given us some nice variables to fill in, in order to make this thing work.  Let’s update to applicationDidFinishLaunching method to look like the code below:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
        // Put your Twitter username and password here:
        NSString *username = @"brandontreb";
	NSString *consumerKey = @"aKKEsJHTDNsv4xVlMHmMqw";
	NSString *consumerSecret = @"oldpeoplenakedcriscotwister";

        // Create a TwitterEngine and set our login details.
        twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
	[twitterEngine setUsesSecureConnection:NO];
	[twitterEngine setConsumerKey:consumerKey secret:consumerSecret];
	[twitterEngine setUsername:username];

	token = [[OAToken alloc] initWithKey:@"16369316-GgqA00WO0poCAj0XAFhJYDDRthVvWMxTnVyKdfWa1"
								  secret:@"StrongEnoughForAManButMadeForAWoman"];
	[twitterEngine setAccessToken:token];
	[twitterEngine getHomeTimelineSinceID:0 startingAtPage:0 count:20];
}

So obviously I changed my consumer secret and Access Token Secret. You will need to fill this out with your information.  Here is how to obtain them.

Consumer Key & Consumer Secret

When logged into http://developer.twitter.com/apps/ , click on the application that you created in the first step:

Scroll down and you should see the Consumer Key and the Consumer Secret.

Access Token & Access Token Secret

In the right column, you should see a link titled “My Access Token”.  Click on it.

Now you should see YOUR Access Token and Access Token Secret

Have Fun!

After you copy the tokens, keys, and secrets into the app, you should be able start making calls to Twitter using the engine.  Build and run the application at this point and watch your home timeline get output to the console.  One thing I want to point out is we are displaying an NSDictionary.  That means MGTwitterEngine did all of the parsing for us (using TouchJSON), which is super rad.

One more thing to try for fun is to update your status.  It will even show that you updated it from YOUR application on Twitter. Add the following line and run it again.

[twitterEngine sendUpdate:@"@brandontreb is a code gangster!  Check out his #iDevBlogADay post on making your own Twitter client here http://bit.ly/gGrZvI"];

Well, that does it for today.  Join me next week when I will show you how to move the engine into your own project and we will begin displaying tweets in a basic table view.

Happy Coding!

Click Here To Go To Part 2

—-

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.


XCode Tips And Shortcuts To Improve Your Workflow

Intro

This is my first #iDevBlogADay post and I wanted to give a quick intro before jumping in.  My name is Brandon Trebitowski and I’m a software developer and author from Albuquerque, New Mexico.  I graduated from the University of New Mexico in 2008 with a bachelors degree in computer science.  For the past 2 years, I have been writing mobile applications (primarily for the iPhone) for ELC Technologies.

I also started http://icodeblog.com and currently write on it about once a month.

A Post On XCode Shortcuts?

Well, I’m sure by now, you have seen countless infographics and “cheat sheets” chock full of XCode shortcuts, tips, etc… These can be great resources, however, if you are anything like me, you see these, tweet the link, and move on never looking at them again.  The only difference between these and the XCode key-bindings menu IMHO is a fancy background. So, I thought I would share some of the most important shortcuts that I have adopted to really improve my workflow.  We spend so much time inside of XCode, it is worth the time to learn some of these.

Build Commands

By now, I would hope that you don’t click the “Build and Go/Debug” with your mouse whenever you want to run your application.  If you do, no worries, here are some of the build quick keys.

⌘ return - This builds and launches the application in debug mode.
shift ⌘ return - Kills the running application in the simulator.
shift ⌘ k - Cleans the build target.
shift ⌘ a - Build and Analyze.  This is quite possible the most important command to learn.  This invokes the static analyzer to help spot memory issues in your code.  Run this as early and often as possible.

My general workflow after writing a bit of code is to kill the last run, clean, analyze (hopefully not spend time on memory issues), and then build and debug.  These 4 commands in sequence are much faster than searching out the menu items for each of those commands.

File Management and Navigation

Navigating around files is one of the most common tasks you will perform in XCode.  It is really to your advantage to speed things up.

option ⌘ ↑ - This quickly switches between your .h and .m file.
⌘ ↑ - Move to the top of the file
⌘ ↓ - Move to the bottom of the file
shift ⌘ d - This was recently showed to my by @cruffenach and it has drastically sped up my workflow.  This is the command for “Open Quickly”.  It brings up a small window with a search box at the top.  Typing in the box instantly searches your project and allows you to quickly open up files by pressing return on the selected file.  I can’t believe I had been using XCode for so long before I found out about this command.

Binding Your Own Quick Keys

Some commands simply don’t have quick keys.  For example, I constantly use the Edit -> Sort -> By Name command to sort my source files alphabetically.  By default, you must click through all of the menus and select the command to get it to work.  However, XCode (like most OSX applications) will allow you to define your own quick keys and here’s how.

  1. Open up the XCode Preferences
  2. Click on the Key Bindings tab
  3. Navigate to the command that you want to bind keys for. (hint: they are organized the same way they in the top menu)
  4. Once you have found the command, double click in the Key column
  5. Press the keys that you wish to bind (I bound option shift ⌘ s for sorting)
  6. If there are any conflicts, XCode will let you know.  Otherwise, press apply and you’re good to go.

Wrap Up

Well, this concludes my relatively short first post for #idevblogaday.  If you have any shortcuts of your own that you can’t live without, please share them in the comments.  I’m always up to improve my workflow.

Thank you to everyone (especially @mysterycoconut) for allowing me to be a part of this community and I look forward to sharing my knowledge and experiences with you.

Happy Coding!

—-

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.