At work recently I’ve been hacking out some front-end Javascript focused on DOM manipulation. I wasn’t that pleased with how intuitive the syntax felt to me or my ability to implement event logic. While I was fresh off lots of Node.js, some CSS work, a few copy-paste extensions of existing coffeescript, as well as implementing a mobile-friendly .js tooltip plug-in, I thought it would go easier.

So I hit the books this weekend, revisiting both:

 

Something caught my brain in Chapter 3 of Secrets of Javascript Ninja. Here the authors stress the importance of functions as “first class citizens” in the language. While comparing the brevity of a sort descending function between Java and Javascript, the authors use the following example:

var values = [ 213, 16, 2058, 54, 10, 1965, 57, 9];

values.sort(function(value1, value2) {

return value2 - value1;

});

While I understood that the function was taking the difference between values, I couldn’t see how many times it was running or what it was doing with the deltas between the two numbers.

So I took to my old friend Microsoft Excel to try and “see” what was happening here.

Screen Shot 2014-03-09 at 2.55.39 PM

Note: The above screenshot is gibberish. The only value it provides is to show what does not work.

After about an hour of feeling like a numerologist, I remembered a YouTube video I’d seen months prior and enjoyed (but didn’t fully understand).

I watched it again with a new perspective, fascinated all over again. And while it brought some clarity, it also brought a sense of staring up a frozen waterfall I’d need to climb to unlock the next layer of the onion.

Being the lazy SOB I am, I went to a friend who lets me ask him inane computer science questions. And because I know he’s horrible at e-mail, I hit him up on Facebook. I could see he was online with his mobile.

Here’s our exchange:

Me:  Trying to mathematically understand or prove… values.sort(function(value 1, value2){ return value2 - value1; }); as it relates to ordering a random array. I tried to solve it using Excel and patterns were deceptive. Which lead me to revisit this video

Me:  So I don’t understand the function, but I feel I understand there’s multiple ways to do it mathematically and Excel is not the right tool to prove this math?

Friend:  This is sorting descending right?

Me:  right!

-

Friend:  Okay so if value 2 is bigger then the result is a positive number which means reorder.

Friend:  But if it’s negative then do not reorder.

Friend:  0 means they are the same so nothing will happen…

Friend:  So only sign matters.

-

Me:  how many times does this need to run?

Friend:  Depends on the algo

Friend:  For a naive sort it’s n squared. Merge sort is nlogn

-

Me:  what’s under the hood for Javascript?

Friend:  Could be quick sort…

Friend:  That’s also nlogn.  I think

Friend:  It’s easy to derive sorting order of algos, all you have to know is what happens in there and then you can use methods like plug and chug to get to the order

-

Me:   when do you choose a different sorting strategy?

Friend:  Speed.  Some can be distributed.

Friend:  So some interview questions at google are like how would you sort 4 million integers.

Friend:   Then they ask what if you had 100 machines.

Me:   love it

-

Friend:   But for the most part you can use library functions and not worry about it… They are usually optimized for generic use. Keyword is generic here.

Me:   thx man

Friend:   Np, I love this stuff!

WHAT’S THE POINT?

Maybe this has given you some fresh perspective on sorting and/or Javascript. If not, well – try this:

Learning can’t me measured in big or small increments. Progress is on a person-specific continuum and all nodes on that continuum must be crossed. If you’re having a good time, keep going.

Also be thankful for other, smarter devs who are willing to throw you up to the top of a frozen waterfall from time to time. If you get a chance to help someone on their journey, do it.

This tweet – leading me to this website, largely inspired this post.

Open-Source Traffic Stats

bluetoothMy last post After the Install: Scenario-Based RVM Best Practices was over a month ago. Since then, I’ve been immersed in an iOS bootcamp. Today’s post has been my first chance to come up for air and share a bit about what I’ve learned.

Similar to Rails, my journey into iOS has come with a lot of support from other devs. In fact, this post was made possible by my bootcamp instructors John Bender and John Clem as well as one of my classmates – Christian Hansen. Specifically, John and John wrote 80% of the code that appears in this post. Christian and I worked closely together to optimize the code and write a thorough explanation of its inner workings. I hope you enjoy the results of our teamwork.

APPLICATION OVERVIEW
For today’s post, Christian and I will walk you through an iPhone application that leverages Apple’s Multipeer Connectivity Framework. Specifically, the application does the following:

  • Has a view showing three colored shapes – called “bubbles”.
  • When another device running the same application is in range, a Bluetooth connection is enabled.
  • When either user drags a bubble with their finger, other connected devices show the same movement.

icon@58Note! I recently released an iPhone app and would appreciate it if you would give it a try. It’s free and called smoov. smoov is a text messaging assistant for gents.

You can download it here or search for it by name in the App Store.


From an architectural standpoint, the application has the following 3 main components, each of which will be thoroughly explained in this post.

    1. View Controller
    2. Bubble View
    3. Bluetooth Manager

Before we get into any code, here’s an overview of the major responsibilities of each of the main components.

bluetooth_arch

The project does include some other components, that while essential for the application to work properly, won’t be addressed in detail in this post. Specifically, we won’t address the contents of the Supporting Files folder, the App Delegate files, the Tests folder, or the Products folder.

Additionally, the astute reader will notice files titled UIColor+RandomColor in the project. These files represent an Objective-C category that make it easy to programmatically assign random colors to UIViews. This file will not get a line-by-line explanation, but it’s role and purpose will be referenced briefly in the Bubble View section.

RUNNING THE APPLICATION LOCALLY
As you read this post, you might find it useful to run the application locally to see it do its thing (as well as inspect the NSLog output).  To do so, simply drop the below into your command line.

$ git clone git@github.com:mxstrand/iOS_Bluetooth_App.git

Then open the project in Xcode and deploy.

Note: This application will successfully pair between a true iOS device (iPhone or iPod touch) as well as the Xcode simulator. Just deploy one right after the other and wait for the pairing confirmation.

With all that out of the way, let’s walk through what’s happening in each of the 3 main components.

1. VIEW CONTROLLER
After the App Delegate files, the View Controller is the first to fire when the app starts up. As such, the BTViewController.h file will be a good place to start our code review. There’s not much happening here, but I will call out that because our BTViewController inherits from UIViewController, the UIKit is imported automatically.

#import <UIKit/UIKit.h>

@interface BTViewController : UIViewController

@end

Moving onto the BTViewController.m file we see a bit more going on. First let’s talk about the imports:

#import "BTViewController.h"
#import "BTBubbleView.h"
#import "BTBluetoothManager.h"

Here we are importing the header file of the same name.  Additionally, we import the header files of the other two key components of the app (as outlined in the Application Overview section above). This is necessary as we’ll be sending and/or receiving information with both the BTBubbleView and BTBluetoothManager. Both the interaction between and the inner workings of these files will be fully addressed in the course of this post.

Next we define some constants that will be fundamental building blocks for our application. As mentioned, our app shows “bubbles” on the screen. With the below constants we begin to define the count and size of bubbles to be used.

static const NSInteger nBubbles = 3;
static const CGFloat bubbleSize = 50.;

Another cornerstone of this view controller is establishing that we’ll be storing references to our bubbles in an array as per the below.

@interface BTViewController ()
{ 
    NSArray *bubbles;
}

@end

As you’ll soon see, storing references to the bubbles in an array makes it easy for us to manage all the bubbles at once when necessary.

Moving into the @implementation BTViewController section, we first define some initial instructions to run immediately after the view appears. If you are newer to Objective-C, I’ll call out here that viewDidLoad is a pre-existing function that is quite common is iOS view controllers as it runs automatically after a view appears on screen. In fact, viewDidLoad is just one of a series of useful pre-existing functions to automatically fire based the view rendering timeline. For a list of other similar functions, check out this list of instance methods from Apple’s reference documentation on the UIViewController.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self makeBubbles];
    [BTBluetoothManager instance];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(bluetoothDataReceived:)
                                                 name:@"bluetoothDataReceived"
                                               object:nil];
}

Breaking down the above, first we inform the parent controller (the UI View controller) that after it’s done doing its viewDidLoad thing, we’ll be providing our own set of instructions.  As such, our first request is to run a method called makeBubbles that is defined in the same file. While this post will cover exactly what makeBubbles does very soon, let’s finish with the rest of viewDidLoad. Next we run a class method defined in the BTBluetoothManager called instance. This too will be addressed in detail, but for now I’ll just say that gets our Bluetooth engine running. Similarly, we tell NSNotificationCenter to begin watching for a specific event – namely an event named bluetoothDataReceived. Additionally, when that event occurs, please send a message to the View Controller. Conceptually, the NSNotificationCenter is like a dispatcher or telephone operator. It listens for certain events, and upon receipt, broadcasts subsequent messages or instructions.

Okay, now for some fun! Let’s make bubbles! As mention, the below method is called during viewDidLoad. Have a read and then let’s discuss what it’s doing.

-(void) makeBubbles
{
    NSMutableArray *b = [NSMutableArray new];
    for( NSInteger i = 0; i < nBubbles; i++ ) {
        BTBubbleView *bubble = [[BTBubbleView alloc] initWithFrame:CGRectMake( bubbleSize, bubbleSize*i,
        bubbleSize*i, bubbleSize*i )];
        bubble.originalIndex = i;
        NSLog (@"Bubble was given index# %d", bubble.originalIndex);
        [self.view addSubview:bubble];
        [b addObject:bubble];
    }
    bubbles = [NSArray arrayWithArray:b];
}

First we instantiate a mutable array. A mutable array is simply an array that can be altered, meaning values can both be added or removed from it. We also assign a temporary pointer (“b” for bubbles) to this array’s location in memory.

With our empty array in place, we trigger a standard for loop that will run until our counter i is no longer less than the constant for bubble count (nBubbles) that we defined at the top of this file. In summary we’re saying we want this loop to run three times.

The first step of the loop is to create a new instance of the BTBubbleView class (we can do this because of the #import "BTBubbleView.h" declaration at the top of the file). Thankfully, Objective-C gives us the initWithFrame:CGRectMake statement that basically draws a rectangle in the view. This statements takes 4 main arguments – x, y coordinates for location on the screen and width and height in pixel size.

After creation, we assign a value to a property called originalIndex. We’ll be using this value later to signal to other devices paired with us via Bluetooth which of the bubbles is moving.

Next we see our first NSLog. NSLog doesn’t impact anything in the user experience, it simply  instructs the application to write a message to the log file – visible to us app developers during runtime, when the application runs while connected to XCode. This is a common debug technique and here we are writing a log statement when each bubble is created and what originalIndex value the bubble has been given. You’ll see quite a few more NSLog statements throughout the code.

Now that a bubble has been created, we use the predefined method addSubview to add it to our main View Controller.

Next, we use the pre-defined method addObject to add our bubble to the end of our mutable array called “b”.

Great, so that’s one bubble created, given an identifier, added to the view, and stored in an array. From here the for loop runs twice more, creating a second and third bubble.

If you look closely, you’ll see that “i’ is influences bubble location and size. As such, our second bubble is placed in a different position on the screen and it slightly larger than the first bubble created.

After the for loop finishes, we use the arrayWithArray method to move our bubbles from a mutable array called b into a non-mutable array that we call bubbles. We’ll be using the bubbles array in the next method.

The next function -(void) bluetoothDataReceived:(NSNotification*)note is a cornerstone of the application. In summary, it receives a “note” from the NSNotificationCenter. This should sound familiar as we discussed notifications just a few paragraphs above. The key point was

Conceptually, the NSNotificationCenter is like a dispatcher or telephone operator. It listens for certain events, and upon receipt, broadcasts subsequent messages or instructions.

In this case specifically, the View Controller has been passed a note of bluetoothDataReceived from the NSNotificationCenter. As the name implies, this method will instruct the View Controller how to update itself based on the receipt of Bluetooth data.

Looking more closely, let’s break down the first few lines of the method.

-(void) bluetoothDataReceived:(NSNotification*)note
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    NSDictionary *dict = [note object];
    NSInteger command = [dict[@"command"] intValue];

If your background is in Rails (like mine), you may not be used to instructing your application to use multiple processing queues of varying priority. However, the first line here is basically putting this method front-and-center on the main processing queue. While such instructions should be used thoughtfully, given that we want near-real-time mirroring of bubble movement between the paired devices, this is an appropriate use of the ability.

You might be asking yourself, “is queuing the same as multi-threading?”. The answer is mostly yes. You can think NSOperationQueue as an abstracted, higher-level approach to multithreading. As it’s outside of the scope of this post, I’ll offer the following StackOverflow posts as a good starting point if you’d like to scratch the surface of the nuances.

Next we instantiate an NSDictionary object, and we base that dictionary on the “note” received from the NSNotificationCenter.

After that we’ll pull the “command” out of the dictionary.  In our application, there are three basic commands that can be passed between devices. In summary, they are:

  1. An object has been picked up (started moving)
  2. An object is moving (this includes x,y coordinates throughout it’s movement path)
  3. An object has been set down (stopped moving).

Knowing this, the following switch statement will begin to make sense.

switch( command ) {
    case BluetoothCommandPickUp:
    {
        NSInteger viewNumber = [dict[@"viewNumber"] intValue];
        NSLog (@"PICKED UP with ARRAY-based viewNumber %ld", (long)viewNumber);
        for( BTBubbleView *bubble in bubbles )
        if( bubble.originalIndex == viewNumber ) {
        [bubble performSelectorOnMainThread:@selector(pickUp) withObject:nil waitUntilDone:YES];    
        break;
        }
    }
    case BluetoothCommandDrop:
    {
        NSInteger viewNumber = [dict[@"viewNumber"] intValue];
        NSLog (@"DROPPED with ARRAY-based viewNumber %ld", (long)viewNumber);
        BTBubbleView *bubble;
        for( NSInteger i = 0; i < bubbles.count; i++ ) {
            bubble = bubbles[i];
            if( bubble.originalIndex == viewNumber ) {
                break;
            }
        }
        if( [bubble isKindOfClass:[BTBubbleView class]] )
        [bubble performSelectorOnMainThread:@selector(drop) withObject:nil waitUntilDone:YES];
            break;
    }
    case BluetoothCommandMove:
    {
        NSInteger viewNumber = [dict[@"viewNumber"] intValue];
        for( BTBubbleView *bubble in bubbles )
            if( bubble.originalIndex == viewNumber ) {
                bubble.center = [dict[@"newCenter"] CGPointValue];
                [bubble performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
                break;
            }
        }
    }
}];

As we have 3 basic commands being shared via Bluetooth, we have 3 cases being evaluated in our switch statement. Based on the command (pick up, move, or drop) found in the dictionary received, the method then goes on to verify which bubble the command is intended for.

You’ll note we’ve embedded some NSLogs here as well which make for some interesting reading if you monitor the console in Xcode while moving the bubbles on paired devices.

Now that the case condition knows which command should be run and which bubble it should be run against, we again see a priority execution statement of performSelectorOnMainThread (arguably redundant based on the previous NSOperationQueue mainQueue) .

The @selector argument is how the receiving device knows what is needs to do. In the cases of pick up and drop, is refers to methods of the same name in the BubbleViewController files.

In the case of move, the bubble repositions its center to new x,y coordinates that have been passed along in the dictionary as per CGPointValue.

Like I said, the above method is a cornerstone of the application and really worth taking some time to understand. Between the use of NSNotification, NSOperationalQueue, switch cases, for loops, dictionaries, and CGPointValue it’s a great piece of code to learn from to take your understanding of Objective-C to a new level.

To close out this file, we’ve got another very common, pre-existing method.

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

As per the method name and comment, it’s easy to infer that when the application experiences a low memory warning , this method will trigger the release of available memory. It you’d like to read more about this function, here’s the link.

2. BUBBLE VIEW
Taking a look at BTBubbleView.h, we find the following:

#import <UIKit/UIKit.h>

Similar to our BTViewController,  our BubbleView inherits from UIView, thus UIKit is imported automatically when the file was created.

Next, we tee up the fact that we want to be able to assign our BubbleView objects a numerical property called originalIndex. If you look back, that we’ve already seen this property in use in our bluetoothDataReceived function. While this value is interpreted (think “getter”) in that method, we’ll see it being set (think “setter”) in shortly.

@property (nonatomic, assign) NSInteger originalIndex;

Next, we give a heads up that our implementation file (.m) will include both pickUp and drop methods. These too we saw used in our bluetoothDataReceived function.

-(void) pickUp;

-(void) drop;

Keep reading to see exactly what these methods do.

Moving along to BubbleView.m, we see a number of import statements.

#import "BTBubbleView.h"
#import "BTBluetoothManager.h"

#import "UIColor+RandomColor.h"
#import <QuartzCore/QuartzCore.h>

The first 2 imports should look familiar as they are the other 2 “main components” of the application described in the introduction. Specifically, the BTBubbleView.h is the header of the file set we just finished explaining in detail. The BTBluetoothManager.h is the header of the file set we’ll explain in the next section.

The UIColor+RandomColor is a basic example of an Objective-C category. This one in particular, provides some helper methods to easily format UIView objects with random colors. If you want to see exactly how that’s done check out the source code – it’s only a few lines.

QuartzCore is a framework we’ll borrow some methods from to format our bubbles. More on that next.

While our header (.h) file outlined a few properties and methods publicly so they could be leveraged by the BTViewController, our implementation (.m) file defines some properties and methods that will be used privately only. Namely,

@interface BTBubbleView ()
{
    BOOL isMoving;
    UITouch *movingTouch;
    CGSize touchOffset;
    CGPoint originalPosition;
}
@end

While the names are quite descriptive, each of these lines of code will be fully explained as we move through the rest of this file. Let’s start with the first method in the @implementation section.

-(id) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if( self ) {
    self.backgroundColor = [UIColor randomColor];
    }
    return self;
}

initWithFrame is a pre-existing UIView method that runs whenever a BubbleView object is created. Here we also set its color using the randomColor method. This ability is coming from the before-mentioned UIColor+RandomColor category. Because we’ve imported the category into our file, we can call it here to set our bubble background color. If you are wondering where the bubble size is being set, have a look back at the makeBubbles function in the BTViewController.m. To understand the full chain of events, when the main View Controller’s viewDidLoad action fires, it calls makeBubbles, which in turn calls initWithFrame.

Next, we are going to look at bubble movement and sending notification of that movement to Bluetooth.

First we have touchesBegan. touchesBegan is a pre-existing UIEvent class function and from Apple’s own documentation it says, “Tells the receiver when one or more fingers touch down in a view or window”.

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event //touchesBegan is a canned function.
{
    if( isMoving ) return; //if an object is already moving, end function.
    movingTouch = [touches anyObject];
    CGPoint touchPoint = [movingTouch locationInView:self.superview];
    touchOffset = CGSizeMake( self.center.x - touchPoint.x, self.center.y - touchPoint.y );
    originalPosition = self.center;
    [self pickUp];
    // Create a dictionary containing key, value pairs for an indicator of the current command and the acting object. Send that dictionary to your peers via the BluetoothManager.
    NSDictionary *dict = @{@"command": @(BluetoothCommandPickUp),
                        @"viewNumber": @(_originalIndex)};
    [[BTBluetoothManager instance] sendDictionaryToPeers:dict];
}

As you can see, the first check we is whether or not the touched object is already moving. If it is, no further action is taken. We accomplish this a simple check using the isMoving Boolean. By default, isMoving is set to FALSE – so the first time it is evaluated, the function continues as desired.

Next we put the movingTouch object to work. As declared at the beginning of the file, the movingTouch object inherits from the UITouch class.  Basically, the touchesBegan function allows us to identify which object has been touched. As you can see the touchesBegan function takes an NSSet as an argument. This means it can interpret more than one touch (finger) on a single view. While this is useful for multi-touch scenarios like 2 finger pinch and zoom, it’s more ability than we need.  In our case, we simply evaluate the NSSet and grab the first touch – it is this touch that consider our movingTouch for further evaluation. Next, we note exactly where on the movingTouch’s location the user touched – we do this by recording its x, y cooridnates within the superview (the view within BTViewController). By comparing the x, y coordinates of where the bubble was touched with its center, we calculate what we call the touchOffset. We’ll use the touchOffset in the subsequent touchesMoved function to creates a handle-like behavior – more on that shortly.

Next, we record the starting point of the bubble and pass it into a variable called originalPosition, before calling a custom method called pickUp.

The final two lines of touchesBegan create a dictionary of  key information to be passed to paired devices. Finally, the dictionary is send to the Bluetooth Mananger.

Moving on, let’s take a closer look at what the pickUp fuction does for us.

-(void) pickUp
{
    isMoving = TRUE;
    [UIView animateWithDuration:0.3 animations:^{
    self.alpha = 0.85;
    CGAffineTransform t = CGAffineTransformMakeScale( 1.11, 1.11 );
    t = CGAffineTransformRotate( t, M_PI );
    self.transform = t;
    self.layer.cornerRadius = 50.;
    } completion:^(BOOL finished) {
    }];
}

First of all, it flips the isMoving Boolean to TRUE, so that if a paired device tries to move the same bubble concurrently it will not respond. (This should raise an interesting question in your mind about resolution of near-simultaneous, conflicting movement of bubbles. This topic is addressed in the Bluetooth Manager section which comes next).

Next, we use Objective-C’s animateWithDuration command to add some special events to the touchesBegan event. In our case, we give the touched object a bit of transparency, make it 10% larger, spin it, and round its corners.

We’ve added a cool effect to when the object is touched and passed some information about the touched object to paired devices via Bluetooth, next we handle movement or dragging of the object.

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event // touchesMoved is a canned function.
{
    if( [touches containsObject:movingTouch] ) {
        CGPoint touchPoint = [movingTouch locationInView:self.superview];
        self.center = CGPointMake( touchPoint.x + touchOffset.width, touchPoint.y + touchOffset.height );
        // Create a dictionary containing key, value pairs for an indicator of the current command and the acting object. Additionally, this dictionary will contain the x, y coordinates of the bubble's center as it moves.
        NSDictionary *dict = @{@"command": @(BluetoothCommandMove),
                            @"viewNumber": @(_originalIndex),
                             @"newCenter": [NSValue valueWithCGPoint:self.center]};
        [[BTBluetoothManager instance] sendDictionaryToPeers:dict];
    }
}

Just like touchesBegan, touchesMoved is a pre-existing UIEvent class function. And just like touchesBegan the main purpose of this function is to record key information about movement (via a Dictionary) and send that information to the Bluetooth Manager. As discussed before however, this method also leverages the previously calculated touchesOffset to actually shift the center of the moving object away by a fixed amount – creating a handle effect.

One other key difference between touchesBegan and touchesMoved is what is passed in the dictionary data set. Besides an identifier for which bubble is moving as well as a command identifier (pickup, move, or drop), the move dictionary include a newCenter value. This is effectively instruction on where a paired device should move the bubble to on its view to mirror the movement on the original device.

At this point, a detailed explanation of touchesEnded is probably overkill.

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event // touchesEnded is a canned function.
{
    if( [touches containsObject:movingTouch] ) {
        [self drop];
        movingTouch = nil;
        // Create a dictionary containing key, value pairs for an indicator of the current command and the acting object. Send that dictionary to your peers via the BluetoothManager.
        NSDictionary *dict = @{@"command": @(BluetoothCommandDrop),
                            @"viewNumber": @(_originalIndex)};
        [[BTBluetoothManager instance] sendDictionaryToPeers:dict];
    }
}

That said, it’s probably noteworthy to call out that here we set the movingTouch object back to nil and call a custom function called drop. In summary, drop is similar to pickUp in that it includes some custom animations as well as sets our isMoving Boolean back to FALSE.

-(void) drop
{
    [UIView animateWithDuration:0.3 animations:^{
        self.alpha = 1.; // remove transparency
        self.transform = CGAffineTransformIdentity;
        self.layer.cornerRadius = 0.1; // round corners
    } completion:^(BOOL finished) {
        self.layer.cornerRadius = 0.; // remove rounded corners
    }];
    isMoving = FALSE; // by setting back to false, the touchesBegan function will run fully when triggered.
}

Next, we’ve got touchesCancelled. touchesCancelled is invoked if the user does something like drag their finger off the screen. In this case, the previous moves are undone by placing the bubble back at it’s original position – which was recorded in touchesBegan. It’s effectively an undo.

-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event // touchesCancelled is a canned function.
{
    if( [touches containsObject:movingTouch] ) {
        [UIView animateWithDuration:0.3 animations:^{
        self.center = originalPosition;
    } completion:^(BOOL finished) {
        [self touchesEnded:touches withEvent:event];
        }];
    }
}

That’s it for the Bubble View, now let’s get into the Bluetooth Manager!

3. BLUETOOTH MANAGER
Up to this point we have looked at the BTViewController and the BTBubbleView classes which were laying the groundwork for how our app will function, display and pass data between peers Now though, we will look at how the sessions are created and managed within the BTBluetoothManager class.

For our app to work, we imported the MultipeerConnectivity.framework into the project. If you’re unfamiliar with adding frameworks, jump over to Apple’s documentation here.

So let’s jump right into the BluetoothManager.h file

#import <Foundation/Foundation.h>
#import <MultipeerConnectivity/MultipeerConnectivity.h>

Here we are importing the framework that we previously included in our project.

The second chunk of code here is the typdef enum block which assigns a number value to the commands listed. The benefit of assigning values to strings gives you (the programmer) a more human-readable way to pass commands and it gives Xcode (the compiler) a way to simply pass a number instead of a string (computers dig numbers).

typedef enum {
    BluetoothCommandHandshake=1,
    BluetoothCommandNegotiate,
    BluetoothCommandNegotiateConfirm,
    BluetoothCommandLayout,
    BluetoothCommandPickUp,
    BluetoothCommandMove,
    BluetoothCommandDrop
} BluetoothCommand;

Now we are adopting the delegate protocols to our class. Essentially this just mean that while this class inherits from NSObject it is also implements (adopts) the three delegates within the <> brackets. The next parts, within the curly braces, we are declaring our instance variables for nearbyBrowser, nearbyAdvertiser, session, peerId and playerIndexTimestamp which will all be used later in the code.

@interface BTBluetoothManager : NSObject <MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate, MCSessionDelegate>
{
    MCNearbyServiceBrowser *nearbyBrowser;
    MCNearbyServiceAdvertiser *nearbyAdvertiser;
    MCSession *session;
    NSString *peerId;
    NSDate *playerIndexTimestamp;
}

The last part in BTBluetoothManager.h is the code below. Here we are creating the NSString property peerName” and the NSInteger property playerIndex. By defining these properties as nonatomic and readonly, we are stating that properties are not thread-safe and that they cannot be changed.

@property (nonatomic, readonly) NSString *peerName;
@property (nonatomic, readonly) NSInteger playerIndex;

Then we have two class methods and also one instance method being declared that we will be looking at further in the implementation file.

+(BTBluetoothManager*) instance;
+(BOOL) hasConnection;
-(void) sendDictionaryToPeers:(NSDictionary*)dict;

Now we are done with the header file and will go through the implementation file. First we import the BTBluetoothManager header file and just below that we are simply setting a constant for the BTAppId. Setting constants is a good idea because it ensures a simple typo won’t leave you complete baffled and searching through all of your code for one tiny mistake. Now, we can use the kBTAppID alias any time we actually mean @bluetoofdemo.

#import "BTBluetoothManager.h"
#define kBTAppID @"bluetoofdemo"

static BTBluetoothManager *sharedInstance = nil;

@implementation BTBluetoothManager

+(BTBluetoothManager*) instance
{
    if( sharedInstance == nil )
    sharedInstance = [BTBluetoothManager new];
    return sharedInstance;
}

Here we are assigning the delegate methods, MCNearbyServiceBrowser, MCNearbyServiceAdvertiser and MCSession to self and allocating and initializing these methods. We start by searching for the appID, advertising the appID and finally we kick of the session, which returns self.

-(id) init 
{
    self = [super init];
    if( self ) {
       // Capture the user-defined device name
       MCPeerID *myId = [[MCPeerID alloc] initWithDisplayName:[[UIDevice currentDevice] name]];
       // Search for a 15-character max appID
       nearbyBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:myId serviceType:kBTAppID];
       nearbyBrowser.delegate = self;
       [nearbyBrowser startBrowsingForPeers];
       // Advertise a 15-character max appID
       nearbyAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:myId discoveryInfo:nil serviceType:kBTAppID];
       nearbyAdvertiser.delegate = self;
       [nearbyAdvertiser startAdvertisingPeer];
       session = [[MCSession alloc] initWithPeer:myId];
       session.delegate = self;
   }
   return self;
}

While the below three methods are not required for the app to run successfully, leaving them in keeps Xcode from throwing an non-blocking warning. Let’s keep Xcode happy.

- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress
{
}

- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID
{
}

- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error
{
}

Any method that begins with (BOOL) is declaring that it will return either a YES or a NO. This method is just checking to see if a connection has been made between you and a peer and it returns that information.

// Confirming that a connection has been made between you and a peer
+(BOOL) hasConnection
{
    return (sharedInstance != nil && sharedInstance.peerName != nil);
}

Now we will create a method that uses NSKeyedArchiver to pass encoded data, in our case it is our dictionary “dict,” to any session-connected peers. This method also checks for any connection errors and will print to the console if this occurs.

-(void) sendDictionaryToPeers:(NSDictionary*)dict
{
    NSError *error = nil;
    NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:dict];
    [session sendData:encodedData toPeers:session.connectedPeers withMode:MCSessionSendDataReliable error:&error];
    if (error) {
        NSLog(@"Bluetooth connection error %@", error);
}

The first line of code you see below may look a little out of place. #pragma mark is used to divide your code up and make it more readable. While, #pragma mark may just look like a comment in the code, it also has the added benefit of adding visual cues to the Xcode source navigator, as seen in the image below. On the right hand side are shortcuts or jump-links to placeholders in your code – many of these set based on #pragma marks.

Pragma Marks in Xcode

Pragma Marks in Xcode

MCNearbyServiceBrowser is searching for nearby devices using the same service type (in our case this is the constant we defined as (kBTAppID @"bluetoofdemo"). Once nearby devices with this service type are located, the class gives the ability to invite those peers to a multi-peer connectivity session.

As of iOS 7, this utilizes network Wi-Fi, peer-to-peer Wi-Fi and Bluetooth. For instance, if Bluetooth was not available, connectivity would still be possible by either of the other two methods mentioned above.

In our method below, we are immediately inviting any found peers to the session.

#pragma mark - Nearby browser delegate

-(void) browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info
{
    [browser invitePeer:peerID toSession:session withContext:nil timeout:0];
}

-(void) browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID
{
    NSError *error;
    NSLog(@"Peer lost. Error: %@", error);
}

This class method is advertising our service (remember our service-type “bluetoofdemo”?) which enables nearby peers to invite you to connect. When an invitation is recieved, MCNearbyServiceAdvertiser notifies its delegate.

In this method we are confirming that we recieved and invitation from a peer and are immediately accepting that invitation. Note: We do not need to automatically accept the invitation, typically this would be where the advertiser is given the option to accept or decline.

#pragma mark - Nearby advertiser delegate

-(void) advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler
{
    invitationHandler( YES, session );
}

Ah, now we’re getting somewhere! In the below (required) delegate method, (session:peer:didChangeState), is being called when the state of a nearby peer changes. State changes can be MCSessionStateConnected or MCSessionStateNotConnected and in our case if a “connected” state change occurs we are sending a dictionary to the peer.

#pragma mark - Session delegate

-(void) session:(MCSession*)theSession
           peer:(MCPeerID *)peerID
 didChangeState:(MCSessionState)state
{
    if( state == MCSessionStateConnected )
    {
        NSDictionary *handshake = [NSDictionary dictionaryWithObjectsAndKeys:
        @(BluetoothCommandHandshake), @"command",
        [[UIDevice currentDevice] name], @"peerName",
        nil];
    [self sendDictionaryToPeers:handshake];
    }
    else if( state == MCSessionStateNotConnected )
    {
    }
}

Now that we have a connection and this method is indicating that we have received data from a peer. In the broadest overview, this method will now connect the two (or more) peers and a short battle will ensue for who connects the fastest. Consider this a race that declares the users in 1st or 2nd place. Note: In our example we only connected between two devices, however the maximum number of connected peers is eight. The playerIndexTimestamp declares the winner and that peer is set to an index of 0.

We do all this by using a switch statement that evaluates the peerName and timeStamp and then assigning the index. We’ve also prompted an Alert View to appear which tells the user their index value.

- (void)session:(MCSession *)session
    didReceiveData:(NSData *)data
    fromPeer:(MCPeerID *)peerID
{
    NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSLog(@"Dict: %@", dict);
    NSInteger command = [dict[@"command"] intValue];
    switch( command )
    {
        case BluetoothCommandHandshake:
        {
        _peerName = [dict objectForKey:@"peerName"];
        // start negotiating player index
        playerIndexTimestamp = [NSDate date];
        //Log player timestamp (that's you)
        //NSLog(@"Log of player timestamp %d", playerIndexTimestamp);
        NSDictionary *negotiation = @{@"command":     @(BluetoothCommandNegotiate),
        @"playerIndex": @0,
        @"timestamp":   playerIndexTimestamp};
        // Logging negotiation
        NSLog(@"Negotiation for playerIndexTimestamp: %@", negotiation);
        [self sendDictionaryToPeers:negotiation];
        break;
    }
    case BluetoothCommandNegotiate:
    {
        NSDate *otherTimestamp = [dict objectForKey:@"timestamp"];
        // Log otherTimestamp
        NSLog(@"Log of other player timestamp %@", otherTimestamp);
        NSInteger otherPlayer = [[dict objectForKey:@"playerIndex"] intValue];
        // Log other player index
        NSLog(@"Log of other player index %ld", (long)otherPlayer);
        if( [otherTimestamp compare:playerIndexTimestamp] == NSOrderedAscending )
        {
            // other timestamp was earlier, so it wins
            _playerIndex = 1 - otherPlayer;
            NSDictionary *negotiation = [NSDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithInt:BluetoothCommandNegotiateConfirm], @"command",
            [NSNumber numberWithInt:_playerIndex], @"playerIndex",
            nil];
            NSLog(@"Another log of the negotiation %@", negotiation);
            [self sendDictionaryToPeers:negotiation];
            dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Set Player Index"
            message:[NSString stringWithFormat:@"Other timestamp won, setting my index to %li", (long)_playerIndex]
            delegate:nil
            cancelButtonTitle:@"OK"
            otherButtonTitles:nil];
            [alert show];
        });
    }
    break;
    }
    case BluetoothCommandNegotiateConfirm:
    {
        NSInteger otherPlayer = [[dict objectForKey:@"playerIndex"] intValue];
        _playerIndex = 1 - otherPlayer;
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Set Player Index"
            message:[NSString stringWithFormat:@"Peer confirmed my timestamp won, setting my index to %li", (long)_playerIndex]
            delegate:nil
            cancelButtonTitle:@"OK"
            otherButtonTitles:nil];
            [alert show];
        });
        break;
        }
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"bluetoothDataReceived" object:dict];
}
@end

So there you have it! Again, the full repo is located at https://github.com/mxstrand/iOS_Bluetooth_App.

CONCLUSION
Obviously this is a monster-length blog post. I hope you’ve enjoyed it and found value. If so, hit myself or Christian up on Twitter.

Once again, big thanks go to John Bender, John Clem, and Christian Hansen for their significant contributions to this work.

In my previous post, Ruby Version Manager (RVM) Overview for Rails Newbs, I outline RVM’s architecture and fundamental features. That post is also very focused on RVMs role when running rails new.

BeforeAfterToday, I’d like to cover a few more common scenarios Rails developers will encounter after the initial install of RVM. More to the point though, we’ll be focused on how RVM can be used to optimize workflow in these scenarios.

1.  USE A DISTINCT GEMSET FOR EACH PROJECT
In my own development journey, it wasn’t initially clear to me when I should be creating new gemsets. If you too have pondered this question, here’s my suggested answer…create a new gemset for every project you are working on. This approach is not only clean and orderly but more importantly reduces the chance that gem dependency errors sidetrack your work.

As a refresher, here’s the necessary commands to create and use a new gemset:

$ rvm gemset create new_gemset_name

$ rvm gemset use new_gemset_name

Hopefully you’re starting to get some clarity on the use-cases for global, default, and custom gemsets. Basically, global and default are largely used to influence what you get from rails new. Custom gemsets are then used to manage all gems related to a project from that point forward.

RVM_architecture

2.  AUTOMATICALLY CHANGE RUBY VERSION AND RUBY GEMSETS WHEN MOVING BETWEEN PROJECTS
Like all devs, I’ve got lots of active projects in various stages on maturity on my machine.  Before I came across this little nugget of knowledge (just keep reading!), I was frequently running:

$ rvm use ruby_version_here

and then

$ rvm gemset use gemset_name_here

It worked pretty well, but when moving between projects in my command line I often got gem-related errors when trying to run rails s or rails c. The problem was that if I forgot to tell RVM to change gemsets when I moved across projects in my command line, the gems that project expected to be available weren’t there.

Before I get to the solution here, humor me with a quick aside…

In a previous life, I was an Excel junky. I really loved Excel and what it could do. Just like development, it offers an incredible combination of logic and creativity. Also like development, the mouse is not necessarily your friend. Learning to do things without leaving the keyboard can be a HUGE time saver. People who were more mouse-dependent would sometimes look over my shoulder as I worked and say, “dude, you need to teach a class on Excel!”. It was a nice compliment and while I was interested in sharing both my love of Excel as well as its features, I would often respond with,

“if you are ever working in Excel and thinking ‘there has to be a better way to do this’. There is. You just need to figure it out.”

The point is that even though I espoused awareness of this phenomena in the context of Excel, I lamely continued with my error-prone use of RVM for some weeks. It wasn’t until my good friend @megharastogi noticed what I was doing and said, “why don’t you use an .rvmrc file?”.

Eureka! An .rvmrc file sits at the root level of your application and basically tells RVM which Ruby version and gemset to use. RVM is smart and interprets these files as you navigate project folders in the command line.

Below is an actual .rvmrc file in one of my apps. It’s stored at your_project_name/.rvmrc or in the below case social-playlist/.rvmrc.

Screen Shot 2013-08-26 at 8.15.50 AM

Your .rvmrc file should be in the same location as your .gitignore, Gemfile, and README.

Boom! No more gem-related errors. Time saved. Happy dev.

3.  CREATE AND USE A NEW GEMSET WHEN RUNNING GIT CLONE
If you haven’t yet, at some point you’ll clone an existing repo. After doing so, likely your first task is to ensure you can get the app running locally in your development environment. For a Rails app, having the required gems present locally is a critical step in the process.

While you’ve cloned the repo, the repo likely doesn’t contain the actual gems. It merely contains a statement of what gems are necessary, via the Gemfile.

Here’s my recommended order of operations:

1. Review the repo’s README file.

2.  Check the Gemfile of the target repo to see if a Ruby version and or gemset name is explicitly stated. (If it’s a Rails app, a Rails version will surely be stated).

3. Check the target repo for a .rvmrc file at project_directory/.rvmrc. If yes, this often also tell you which version of Ruby as well as the gemset name being used.

NOTE:  As per the Typical RVM Project Workflow, other potential locations where Ruby version and/or gemset dependencies may be stated include files named: .versions.conf, .ruby-version.

4. If a Ruby version is explicitly stated, ensure that Ruby version is installed locally on your machine with $ rvm list

a. If that version is already installed locally on your machine, make it active with $ rvm use ruby_version_here and go to step 5.
b. If that version is not installed locally on your machine, get it with $ rvm install ruby_version_name                                       c. If no version of Ruby is explicity stated, I recommend using the latest stable version.
d. Make the target version of Ruby active with  make it active with $ rvm use ruby_version_here

5. Run $ git clone target_repo_location_here

Note: Both of the above commands clone the same repo, they just use different security protocols. For the truly adventurous reader, here’s a deep dive on the hows and whys of each protocol.

6. $ cd newly_created_directory_name

7. $ rvm gemset create new_gemset_name

Note: If the repo already contained a .rvmrc file with a gemset name, consider naming your local gemset the same as what’s being used by the other dev(s) pushing to the repo.

8. $ rvm gemset use new_gemset_name

9. $ bundle install

If no .rvmrc file is already present in the app, create one! It’s up to you if you include the .rvmrc in the .gitignore (I strongly suggest you do not! This as an important file for ensuring consistency across collaborators).

While not RVM specific, for good measure I’ll also offer up the other following steps to get the newly cloned app running locally.

10. $ rake db:create

11. $ rake db:migrate

12. $ rake db:seed (optional – only run if seeds.rb contains seed data).

Unless there’s database or server specific requirements, that should suffice to get the app running locally with rails s.

Looping back to the big picture before closing out on this topic. Now we have a distinct gemset just for this project (meeting the objectives of best practice #1) – and automated instructions for RVM to use this gemset whenever this project is active (meeting the objectives of best practice #2) in the command line. And we can be confident we are mirroring the Ruby and Ruby gem configuration of the other devs on the project.

4.  CREATE A “RAILS 4 SCAFFOLD APP” FOR QUICK REFERENCE
In my other post, Reading Rails 4: MVC and Scaffolding for Rails Newbs, I go deep on some of the code generated when running rails generate scaffold.

My original title and concept for the post was not Rails-version specific. I thought it would mostly be about MVC and scaffolding – but be agnostic of Rails version. However, by reviewing the output of rails new and rails scaffold (while having RVM use Rails 4), I quickly and easily learned a lot about Rails 4 versus the Rails 3 versions I was more familiar with.

The point here is that RVM (combined with rails generators), is your assistant in having multiple boilerplate/clean versions of working Rails apps side-by-side on your machine. This makes it easy to access, evaluate, compare, and understand fundamental changes in Rails versions. Personally, I found reviewing the output of a Rails 4 scaffold more educational on mass-assignment in Rails 4 than any online documentation.

If helpful, here’s specifically what I’m suggesting. Say you’ve been hesitating getting onto the Rails 4 bandwagon because you are up and running and proficient in Rails 3. Maybe you feel too busy right now to slow down and learn the “gotchas” in Rails 4. Well, I think 5 minutes spent on the following will probably get you past that hurdle

  1. Create a new gemset called “rails4scaffold” with $ rvm gemset create rails4scaffold
  2. Make the new gemset active with $ rvm gemset use rails4scaffold
  3. Install Rails 4 in that gemset by running $ gem install rails 4
  4. Create a new app by running $ rails new rails4scaffoldapp
  5. Scaffold a basic MVC in that app with rails generate scaffold books title author
  6. Run rake db:migrate
  7. Now go inspect key files like app/controllers/books_controller.rb and run $ rake routes to see how Rails 4 handles basic CRUD.

If you haven’t yet, consider moving Rails 4 into your default gemset!

SUMMARY
As always, I really appreciate you reading my post. I hope it’s been useful for you in getting more value out of RVM. Your comments and feedback are welcomed.

One other quick point is that there are other tools and approaches for doing what RVM does (quite well in my opinion). However my goal is not to promote RVM, but to promote knowledgeable, confident, and satisfying development experiences. As such, I want to share a post titled “Vendor Everything” Still Applies by Ryan McGreary. In it, he makes some interesting and compelling arguments for an alternative approach to gemsets and gem management.

I’m personally still using RVM, but that doesn’t mean I will forever.

Truth fears no questions.
-Napoleon Bonaparte

Reading between the lines of Mr McGreary’s post as well as some of the comments, I think the main point is that consistency in approach to gemset management within a collaborating group is critical to developer happiness and productivity.

Here’s some of my other posts you might like:

Peace.

In my previous post Top 10 Gems for new Rails Devs, I covered both the Devise and Twitter Bootstrap gems. Each of these gems is great at what they respectively do (authentication, design/styling). In this post, I’ll bring @plataformatec and @seyhunak‘s gifts together and easily put Devise sign-in and sign-up forms into Twitter Bootstrap modals.

defaults

What is a modal? If you aren’t familiar with modals, they are basically “pop-ups” or “prompts” that take a priority position in the user experience. If you’re interested in more theory regarding when and how to use modals, check out this post.

Getting sign-in and sign-up modals working in your application is not only a great introduction to using modals, but I think this feature creates a quality “first impression” for site visitors as well.

Want to see this code in a working repo? I’ll be orienting this post around a working implementation of this feature at www.social-playlist.com. This is a site I built with my good friend @lostincode. The project is open-source, so if you want to see everything in-context you can do so at https://github.com/lostincode/social-playlist.

Okay, let’s get started…

STEP 1:  BUILD THE MODAL PARTIALS
Partials are basically re-usable pieces of code falling into the the View portion of MVC. (For a Rails 4-specific explanation for MVC, check out my other post Reading Rails 4: MVC and Scaffolding for Rails Newbs.

Partials in Rails are easily identifiable based on the preceding underscores _ in file names (Example: _partial.html.erb). If you’ve ever run a rails g scaffold, you’ve created a partial named _form.html.erb. This single form is used in both the new and edit views for your scaffolded model. Whether you are creating a new record in the database or editing an existing record, you likely want access to all the same fields. Given the overlap, a single partial can serve in both conditions.

Okay, now let’s build modal partials for today’s feature…

We’re going to need to create some new files and there’s no hard requirements about where they go in your app. I think you definitely want them somewhere in your app/views/ hierarchy, but exactly where after that is up to you.

In many of my projects I use a “welcome controller” and associated views for things like the home page or “about us” page. As such, I think app/views/welcome/ makes a great spot for the below two files.

_login_modal.html.erb

_sign_up_modal.html.erb

Here’s a copy-paste of what I place into each file:

app/views/welcome/_login_modal.html.erb

<div class="modal hide fade in" id="login">

<div class="modal-header">

<button class="close" data-dismiss="modal">x</button>

<h2>Sign in</h2>

</div>

<div class="modal-body">

<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>

<div><%= f.label :email %><br />

<%= f.email_field :email, :autofocus => true %></div>

<div><%= f.label :password %><br />

<%= f.password_field :password %></div>

<% if devise_mapping.rememberable? -%>

<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>

<% end -%>

<%= f.submit "Sign in", :class => 'btn btn-small btn-success' %>

<% end %>

</div>

<div class="modal-footer">

<%= render "devise/shared/links" %>

</div>

</div>

Newb Note! The studious reader will have identified a sub-partial embedded within the partial we just created. Inspect the following statement:

<%= render "devise/shared/links" %>

That’s calling a partial into our partial! Don’t worry if you don’t fully understand just yet, it will all get clearer before we’re done.

Let’s get back to building our own partials. The second and final file we’ll need to create is:

app/views/welcome/_sign_up_modal.html.erb

<div class="modal hide fade in" id="sign_up">

<div class="modal-header">

<button class="close" data-dismiss="modal">x</button>

<h2>Sign Up</h2>

</div>

<div class="modal-body">

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>

<%= devise_error_messages! %>

<div><%= f.label :email %><br />

<%= f.email_field :email, :autofocus => true %></div>

<div><%= f.label :password %><br />

<%= f.password_field :password %></div>

<div><%= f.label :password_confirmation %><br />

<%= f.password_field :password_confirmation %></div>

</div>

<div class="modal-footer">

<p><div><%= f.submit "Sign up", :class => 'btn btn-small btn-success' %></div></p>

<p><a href="#" class="btn btn-small" data-dismiss="modal">Close</a></p>

</div>

<% end %>

</div>

NEWB NOTE! When creating modals in Twitter Bootstrap, make sure to use their built in classes for header, body, and footer. These control margins/padding that help things look just right.

Okay, back to business. Let’s get those partials working for us.

STEP 2: RENDER THE PARTIALS INTO APPLICATION LAYOUT
Remember above when I highlighted the partial-within-a-partial? The sub-partial was invoked using:

<%= render "devise/shared/links" %>

The reason I belabor the point is to establish a universal trend – and here it is…To render any partial, simply call render along with the location of the partial.

In our case, we have sign-in and sign-up buttons in the navbar on every page of our web site. As is the Rails way, we place app-wide View content in app/views/layouts/application.html.erb. Similarly, we want our new pop-up modals available (visible or not) on every page of our site. Accordingly, we put the below code into app/views/layouts/application.html.erb also:

<%= render "welcome/login_modal" %>

<%= render "welcome/sign_up_modal" %>

Newb Note! You might be thinking, “hey, that looks like a typo…aren’t partials pre-fixed with an underscore like _partial.html.erb ?” That’s not a typo, that’s simply the Rails convention for refering to partial location. Also, we do not need to supply the app/views/ elements of the directory path when refering to the location of partials. Rails confidently expects them to be in the V of MVC!

Where exactly should this render code be placed in app/views/layouts/application.hmtl.erb? Again, there’s not much of a hard and fast rule. Personally, I put mine immediately under the  <body> open div.

STEP 3: UPDATE YOUR LINK_TOs
We’re not leaving app/views/layout/application.html.erb yet. Now we need to update our sign-in and sign-up buttons to engage our newly created modals as opposed to their historical forms. We can do this by simply changing the relevant link_to‘s to look like the below.

<%= link_to "Login", "#login", "data-toggle" => "modal", :class => 'btn btn-small' %>

<%= link_to "Sign up", "#sign_up", "data-toggle" => "modal", :class => 'btn btn-small btn-success' %>

Newb Note! The first time I implemented this feature, I placed the above code next to the existing link_to‘s. I did this to make sure everything was working with the new before getting rid of the old way.

One of the critical pieces of any link_to is the second argument – in our case, #login and #sign_up. The values provided here must match the id in the parent <div> of the associated partials. To make sure I’m clear, the relevant code from the parent <div>s are shown here again.

<div class="modal hide fade in" id="login">

<div class="modal hide fade in" id="sign_up">

STEP 4: ADD SOME JAVASCRIPT MAGIC
Everything is just about ready to rock. When I first got this working in my app, I was disappointed that while the modals were popping up, they were dark like the subordinated background. Luckily, this StackOverflow post suggested adding the below into app/views/layouts/application.html.erb

<script type="text/javascript"> $(function ()

{ $("#myModal").modal({show:false }); </script>

If you’re like me, you’re thinking “where exactly should I put that code?”. Kindly the SO post also suggests putting it “right before the </head >” close tag.

STEP 5: UPDATE YOUR APPLICATION HELPER
Okay, so we’ve forms that users want to see. We’ve established a call to render them on every page of our application – next we need to make sure a new resource (the Devise term for user) is instantiated when our modal is engaged.

Thankfully the esteemed Pablo who originally wrote this entry (the birthplace of some succinctly powerful methods and now hosted on the official Devise wiki), provides us the below helper methods to place in app/helpers/application_helpers.rb.

def resource_name

:user

end

def resource

@resource ||= User.new

end

def devise_mapping

@devise_mapping ||= Devise.mappings[:user]

end

STEP 6: ENJOY!
You’re done! Fire up a rails s and check it out in the browser before you git push.

Hopefully you’ve enjoyed and found value in this post. If so, drop me a comment or a tweet @mxstrand! Also, here’s a few other posts you might like:

Thanks for reading.

imagesIn my previous blog post Easy Does IT: Top 10 Gems for Rails Newbs, I highlighted the Brakeman gem for its ability to easily identify, interpret, and resolve security issues in a Rails app. Today I want to offer a few more security best practices for the new Rails developer. Here goes…

STEP 1:  IDENTIFY SENSITIVE INFORMATION
Depending on the feature set, your application might leverage any one of hundreds of internet-based services. Below is a list of some of the most commonly encountered by new Rails developers.

For your rails application to interact with any of these services, a set of credentials (username, password, developer key) must be accessible to your code base.

When I first started working with these tools, I foolishly didn’t consider that I was putting sensitive information on the public internet with every git push. That said, I know I’m not alone. It’s easy to find StackOverflow posts where newer devs are publishing their credentials for the whole internet to see.

One additional sensitive piece of information that is auto-generated during rails new and necessary for every Rails app to function is its secret_token (also known as “secret_key_base”), which can be found at app/config/initializers/secret_token.rb. What is a secret_token? Well, looking into the file’s own comments we see:

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
# Make sure your secret_key_base is kept private
# if you're sharing your code publicly.

Okay, that’s enough discussion – let’s get into some code and discuss how to make it secure. Here’s an example of what I commonly include in app/config/environments/development.rb to configure ActionMailer to leverage Gmail for sending email in dev to see things like the Devise confirmable or Devise_Invitable (a separate gem – check it out!) working before pushing to production.

config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.perform_deliveries = true
config.action_mailer.default :charset => "utf-8"

ActionMailer::Base.delivery_method = :smtp

ActionMailer::Base.smtp_settings = {

:address => "smtp.gmail.com",
:port => 587,
:authentication => "plain",
:user_name => "my_actual_username@gmail.com",
:password => "my_actual_password" }

Now this code works, but I definitely don’t want to be sharing my Gmail credentials with the world. Let’s talk about what to do.

STEP 2:  MOVE SENSITIVE INFO TO A .YML FILE
Before we can move our sensitive info to it, we need to create a new file at app/config/application.yml. Inside that file, we’ll declare our “environment variables” with the following styling.

GMAIL_USERNAME: "my_actual_username@gmail.com"

GMAIL_PASSWORD: "my_actual_password"

If you’re interested, here’s the Wikipedia page about the .yml file history and purpose.

Moving on, now we can move our credentials out of the app/config/environments/development.rb file by revising the last 2 lines of the code block below:

config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.perform_deliveries = true
config.action_mailer.default :charset => "utf-8"

ActionMailer::Base.delivery_method = :smtp

ActionMailer::Base.smtp_settings = {

:address => "smtp.gmail.com",
:port => 587,
:authentication => "plain",
:user_name => ENV["GMAIL_USERNAME"],

:password => ENV["GMAIL_PASSWORD"] }

Newb Note! It’s standard practice to use ALL CAPS for environment variable naming.

Starting to feel more secure? You should! But we aren’t done yet.

STEP 3:  LOAD DEVELOPMENT ENVIRONMENT VARIABLES
Now, we need to tell Rails to load the locally-stored environment variables during application start-up. We can do this in app/config/application.rb with:

if Rails.env.development?

ENV.update YAML.load(File.read(File.expand_path('../application.yml', __FILE__)))

end

That’s it for step 3!

STEP 4: EXCLUDE YOUR .YML FILE FROM YOUR REPO
Next, we need to put the project’s app/.gitignore file to good use. Let’s go ahead and add the following lines to it:

# Ignore environment variable during "git push"
/config/environments/application.yml

If you haven’t noticed or used the .gitignore file before, it does just what the name implies. It tells Git, what files not to push to the remote repository.

Newb Note! Because you are not pushing your app/config/environments/application.yml file into your repository, should you or another developer ever git clone the repo, the clone will not include the necessary environment variables for the application to function properly. This is of course “by-design”, but can be an area of confusion for newbs trying to get a cloned app up and running.

STEP 5:  CORRECT PAST MISTAKES
So we’re secure moving forward, but what if you’ve already pushed a commit to a public GitHub repository that included sensitive info? Here’s a few options in order of complexity.

  • Change your sensitive info (like passwords or secret_tokens) after implementing the best practices outlined above. While the old credentials may still be visible, they’ll no longer work
  • Clone the repo to a new directory, change your sensitive info, implement these best practices, and delete the original repo.
  • If you are wondering if you can delete a commit, the answer is sort of. Here’s more details for the adventurous.

STEP 6:  MANAGE PRODUCTION ENVIRONMENT VARIABLES
Everything discussed above has been focused on environment variables for development. Because the .yml file containing these values is stored locally on your machine, your app can read them. But Heroku (a.k.a production) doesn’t have access to that .yml file on your machine. Don’t worry, setting environment variables with Heroku is easy.

Say for instance we want to set our secret_token with Heroku. When can do so via:

heroku config:set SECRET_TOKEN=123456789012345678901234567890

Or maybe we’re interacting with the Twitter API. In this case we need to set both:

heroku config:set TWITTER_CONSUMER_KEY=1234567890

heroku config:set TWITTER_CONSUMER_SECRET=1234567890

Obviously you can see the pattern. Basically, anything you are storing in your .yml file that your application depends on needs to be configured at Heroku as well.

For a complete description of how to manage environment variables with Heroku, check out this article.

Newb Note! As with all common Rails scenarios, you can probably guess a gem or two is out there to help. In the case of environment variables, I recommend checking out both the Dotenv gem and the Figaro gem.

STEP 7:  SECURE YOUR STAGING ENVIRONMENT (if you have one)
By default, Rails will give you test, development, and production environments. While it’s generally safe to assume that what works in development will also work on the internet (production), for mission critical applications you will likely want to set up a 4th environment called “staging”. Staging is intended to be a mirror of production (also on the public internet) – it’s just not actually open to the public. By first determining that things are working as intended in this production-like environment, you can have a much higher confidence that changes will not negatively impact your end users.

Newb Note! Staging environments are also a great place to do performance testing and reproducing customer-reported issues without actually impacting production services.

So we’ve discussed the importance of staging, but specifically how do you put something on the public internet, but not have it public?

Rails to the rescue again! Rails has a nice, little built-in method that you can drop right into your application_controller.rb. Here it is:

before_filter :http_authenticate if Rails.env.staging?

def http_authenticate

authenticate_or_request_with_http_basic do |username, password|

username == "some_username" && password == "secret_password"

end

end

Oops! Did you notice what I did there? Once again, I’ve got my sensitive information embedded in my code and being pushed to the repo. Thankfully, I know how to move these values to an environment variable – leveraging a .yml file for development and/or setting them directly with Heroku through the command line.  Here’s the revised code.

before_filter :http_authenticate if Rails.env.staging?

def http_authenticate

authenticate_or_request_with_http_basic do |username, password|

username == ENV["STAGING_USERNAME"] && password == ENV["STAGING_PASSWORD"]

end

end

Don’t forget to add the actual values to the app/config/application.yml file!

Now, any visitors to your staging URL will be prompted for credentials before being allowed to even see the home page.

As it’s outside the scope of this post, I’ll forgo instructions on how to set up a staging environment. And an even better reason not to cover the topic here is because this Heroku article explains the steps quite nicely. (Should you decide to you’d like to run a local staging environment, Mr. Bates has developed a great RailsCast on the subject here.)

STEP 8:  LEVERAGE PRIVATE REPOSITORIES (when appropriate)
GitHub is a great resource and heavily used by the Rails community. While they do offer private repositories, they are not free. Another option to check out is BitBucket. BitBucket offers free, private repos – allowing up to 5 collaborators on each repo.

As a bonus, if you invite new users to BitBucket and they use the service, you can earn privileges for more than 5 collaborators on your repos.

Newb Note! Once you’ve got your first freelance gig, consider having your client create their own repo at BitBucket and make you a collaborator. This way, they “own” the source code – if that’s how your contract is structured.

One final word of wisdom to the Rails newb regarding private repos. While BitBucket is a great security solution and arguably removes the need to concern yourself with some of the “overhead” like .yml files described above – don’t rush to move all your projects there. As a new developer, potential employers will want to see that you are an active “commiter” – and most employers will look to GitHub for such evidence.

STEP 9:  KEEP LEARNING
If you’ve got your arms around everything covered here – you are off to a great start. But like all rabbit holes, this one goes deeper. A great resource for continuing your security education, is a free, one month email course on securing your Ruby apps provided by Code Climate. To sign up, you’ll want to hit http://railssecurity.com.

So once again, thanks for reading! Security may not be sexy, but good developers are. If you haven’t checked them out, here’s some of my other posts you might like:

If there’s a topic you’d like me to cover in a future blog post, don’t hesitate to add a comment.

babydev

Whatever your reasons are for choosing to learn Ruby on Rails, they were the right ones! Rails is an excellent framework for quickly building feature-rich, scalable, and secure web apps.

In the forward of The Rails 3 Way (required reading for all new Rails devs) Mr. Fernandez states,

 …Rails frees you to kick off your project with a bang, getting a working prototype out the door quickly. This makes it possible to build an application with some meat on its bones in a few weekends, making Rails the web framework of choice for people with a great idea and a full time job.

Whether you are building a prototype or an enterprise-level application; whether you are a full-time dev or a weekend hacker, the key message is that you can get a QUALITY Rails app up FAST. Gems are a cornerstone of this fact.

In my other post, Ruby Version Manager (RVM) for Rails Newbs, I discuss how Rails itself is a Ruby gem. While Rails is the king of gems, there are many more the Rails newb should get acquainted with early in their career.

The purpose of this post is to introduce the Rails newb to a handful of gems offering low cost (time) and high return (features!). Another important characteristic of all the below gems is their licensing terms. These gems can be used freely – including commercial use.

Newb Note! The “Ease of Implementation” guidance given below is not intended to be exhaustive. It’s intended to highlight the  ease with which a given gem’s base functionality can be enabled. Many of these gems have a rich capability set that requires further reading to completely unlock. This post will get you started and give you some perspective, but plan to read the source docs to get the most from the gem.

Knowing all that, let’s talk gems. Here’s a table of contents for this post if you’d like to jump to a particular gem.

    1. Devise
    2. Twitter Bootstrap
    3. PostgreSQL
    4. Pry Debugger
    5. Better Errors
    6. Launchy
    7. Rails ERD
    8. Brakeman
    9. Faker
    10. Font Awesome

1. DEVISE     (source code)

What does it do? Any modern web app, must have user “authentication” – meaning users can create credentials (e-mail and password) and have those credentials stored in the application’s database for future use. Given the importance of authentication, it’s included first in our list.

Ease of Implementation: Beyond the usual Gemfile inclusion and bundle install, Devise requires just a bit of configuration to get running. The good news is that these instructions are well documented in the README.

Environments: Place it at the root level of your gem file so it’s available across dev, test, and production.

Newb Note! Devise’s default configuration is good, but you can make it great by turning on some additional built-in features. For example, you might want to add a “username” field (the default for sign-in is e-mail + password). Or you might want to use the “confirmable” option so users are required to confirm ownership of their provided e-mail address by clicking a link in a system generated e-mail. These options too are well documented.

Recommended Resources:


2. TWITTER BOOTSTRAP     (source code)

What does it do? Twitter Bootstrap provides clean, modern, and professional CSS styling for a number of common web app elements like navigation bars, buttons, icons, fonts, and much more.

Ease of Implementation: Installation and base configuration are quite easy and well documented in the README. Depending on your familiarity with HTML and CSS, the harder (but not hard) part is choosing which elements to use and getting them properly embedded in your Views. If you are confused by that statement regarding “Views” have a read of my post Reading Rails: MVC and Scaffolding for Rails Newbs.

Environments: In Rails 3, you’ll want to place Twitter Bootstrap in the “asset” group in your gemfile. In Rails 4, there is no asset group so go ahead and place it at the root level so it’s available in all environments.

Newb Note! I’m embarrassed to admit this, but in my own newb-ness at first I was confused about how to implement Bootstrap’s examples in my own projects. I followed the gem instructions, but then what? Where was my beautiful carousel and navigation? One of my first, very patient Rails mentors @lostincode told me to just right click and “View Source” on the target example’s web page. Then just copy the relevant code and drop it into your Rails app. After you’ve done this a few times, you have a library and favorite code that you can move between projects.

Recommended Resources:


3. PG also known as POSTGRESQL     (source code)

What does it do? Just about any web app you build needs to ultimately move off your development machine and onto the internet. Thankfully for Rails newbs, Heroku makes this very easy and free. Heroku’s only requirement is that you run a PostgreSQL database in production instead of Rails’ default of SQLite. The PG gem is the ticket.

Ease of Implementation: It’s really quite easy to set your production DB to PostgreSQL via the gemfile. Instead of the gem’s own README, I suggest having a read of Heroku’s guidance at Getting Started with Rails on Heroku.

Environments: You’re definitely going to want it in your group :production do  group if deploying to Heroku. Whether you also use it in dev or test, is up to you.

Newb Note! While purists will argue you should run PostgreSQL locally in development to ensure a mirror with production, many (not all!) Rails app scenarios will handle SQLite in dev and PG in production just fine. It’s acceptable for newbs to start with this approach and as you get further along in your Rails journey, then you can go about getting PostgreSQL running locally via instructions like these. Once you have PG running locally, when creating future Rails apps (that you plan to deploy to Heroku) I recommend telling Rails that you want a PG database from the get go. Here’s how to modify your $ rails new accordingly:

$ rails new myapp --database=postgresql

Recommended Resources:


4. PRY-DEBUGGER     (source code)

What does it do? Pry-Debugger can be used in both development and test environments to “pause” your application mid-stream at a point you specify. Once paused, you can interrogate and evaluate variables or params. For example, if you want to see what information is being passed from a view’s form into your controller, pause the app in the controller action triggered by the form submit button.

Ease of Implementation: It’s so, so easy to install and requires effectively no configuration. After including in your gemfile and running bundle install, simply drop binding.pry into your codebase (likely in your Controller or Model) just after code you want to evaluate after the application “pauses”. Then, trigger the target action in your browser (or via your test spec) . When the application hits your binding.pry, go to your terminal/console and go crazy!

Environments: I recommend creating a gem group for both dev and test with something like group :development, :test do. Pry-Debugger should go here.

Newb Note!  Pry-Debugger is built upon the original Pry but also includes some additional commands such as step, next, finish, and continue. Check out the README for a quick explanation of these commands.

Recommended Resources:


5. BETTER ERRORS     (source code)

What does it do? No matter what, your app is going to puke from time to time. The least you can do for yourself is to have easy-to-clean-up puke. This is where Better Errors comes in. It provides cleanly formatted errors with log details in the browser just a click-away.

Ease of Implementation: So easy, there’s really no excuses not to use it. Put it in your gemfile and bundle install. That’s it.

Environments: I recommend group :development do for Better Errors.

Newb Note! As per the README, make sure to check out the complementary gem “binding_of_caller“, which gives you functionality similar to Pry-Debugger (described above) – but this functionality is inside your web browser when a better_errors’ error is thrown.

Recommended Resources:


6. LAUNCHY     (source code)

What does it do? Sometimes when your test specs are failing, the error messages just aren’t informative enough – you need to see what the test is seeing in the browser. This can be especially maddening when everything appears to be fine in the browser in the development environment, but your tests are failing. Here comes Launchy to the rescue!

Ease of Implementation: Put it in your gemfile, bundle install, and include save_and_open_page inside your test spec where you want to browser to open.

Environments: As per the description, you only need Launchy in your group :test do block.

Newb Note! Dont’ forget to remove save_and_open_page after you’ve resolved your issue.

Recommended Resources:


7. RAILS-ERD     (source code)

What does it do? Rails-ERD generates a visual representation of your database schema – including tables, fields, and relationships. Personally, there’s a few scenarios where I like to use this gem.

    1. Getting up to speed on an existing project when I’m a new team member
    2. When I want to get another dev up to speed one of my existing projects
    3. For planning purposes when I know I need to change my database architecture in a material way
    4. To facilitate design discussions with more-technical clients and project decision makers
    5. Returning to project that may have been dormant for some time

Ease of Implementation: In addition to the requisite inclusion in your gemfile and bundle install – you’ll need to install Graphviz. It’s all quite easy and laid out here. After setup, you can run rake erd at any time to generate an up-to-date diagram.

Environments: I put Rails-ERD in my group :development do block.

Newb Note! Personally, I like to use this gem once my project is up and running and the schema starts to get more complicated. However, a related best-practice that I recommend is to use a similar tool to create a draft of your intended schema before you write a single line of code. Personally, I’ve been mostly pleased with the Sea Quail Database Diagram Tool. What it lacks in features, it makes up for in ease of use. I don’t have deep experience with the multitude of options that are just a search engine away. Please comment on this post if you recommendations for other ERD design tools!

Recommended Resources:


8. BRAKEMAN     (source code)

What does it do? I’m no security expert, so I really appreciate a tool that helps me easily identify, interpret, and resolve security issues in my Rails app. Enter Brakeman.

Ease of Implementation: In addition to the requisite inclusion in your gemfile and bundle install – you just put brakeman into your command line from the application root directory.

Environments: I put Brakeman my group :development do block.

Newb Note! As per the README, don’t forget to include :require => false in your gemfile when inserting Brakeman. Also, if you’d like to go deeper on Rails security, check out my other post Security is a Feature: 9 Newb-Friendly Steps to Securing Your Rails Apps

Recommended Resources:


9. FAKER     (source code)

What does it do? Sometimes having a robust set of data in your development database makes the testing and development process go much smoother. Entering it through the browser is a fool’s errand (and it’s retained if you reset your DB). Seeds.rb files are a big help, but you still have to come up with the actual values to be entered. Not anymore with Faker. Faker provides random values for names, cities, addresses (physical and internet) – even lorem ipsum text.

Ease of Implementation: You know the drill – put it in your gemfile and run bundle install. Next, incorporate the Faker syntax in either your seeds.rb or a rake tasks. Here’s some sample Faker syntax so you can see just how easy it is.

Faker::Name.name #=> “Christophe Bartell”

Faker::Internet.email #=> “kirsten.greenholt@corkeryfisher.info”

Environments: I recommend creating a gem group for gems used in both dev and test with something like group :development, :test do. Faker should go here (you can use Faker in in your tests!).

Newb Note! Check out the README for a full inventory of the fields Faker provides.

Recommended Resources:


10. FONT-AWESOME     (source code)

What does it do? These guys take icons really seriously. They use them stand-alone, but also embed them with buttons, navbars, and form inputs.  Remember,

a picture is worth a thousand words

Ease of Implementation: Just like Twitter Bootstrap, just add Font Awesome to your gem file, run bundle install, and start embedding the syntax for the desired icons and styling into your html.erb Views.

Environments: Place it at the root level of your gem file so it’s available across dev, test, and production.

Newb Note! Font Awesome plays well with Twitter Bootstrap (#2 in our gem list). Use the two together to build a highly polished product!

Recommended Resources:


SUMMARY
As with most of my posts, if you’ve gotten this far – congratulations and thank you! If I’ve left out any low cost, high benefit gems of note – please comment!

Here’s a few other posts of mine you might like: