Skip to main content

Mobomo webinars-now on demand! | learn more.

If you've spent any time building iOS apps using tools like Cordova or PhoneGap, you'll know that one of the biggest time-sucks is in viewing new changes to existing pages. The most common example of this would be building a Single Page Application using libraries like Backbone, Angular, or Ember.

The awful way

My flow, until recently, has been to start up the simulator from Xcode, test out my pages, stop the app from Xcode, then select Reset Content and Settings... from the iOS Simulator menu. This process is painfully slow, especially if you work iteratively like I do.

"Reset Content and Settings"

A better way

With the most recent updates to Safari, there's now a way to refresh your app from the Web Inspector (the functionality has been around for a little while via keyboard short-cuts, but the explicit UI is new).

You can access this once your app is running by opening up Safari, selecting the Develop menu, iPhone Simulator (or iPad Simulator), then index.html.

"Safari Developer Menu"

Once there, select the Resources tab and you'll see the index.html page selected, with a refresh icon to the right of the column. Click on that and you'll get a proper page reload. Alternately, you can press cmd + shift + r to trigger the reload.

Please Note: If you need to run the cordova run ios command, you may still need to re-start the emulator/re-build your app to see the changes you have made.

"Reload Interface in Safari"

 

Categories
Author

Working from home can be incredibly rewarding but equally challenging, mentally and physically, especially if you're new to it. With a few small changes in both outlook and setting, you can improve your health and productivity dramatically.

Don't Work from home

A big part of working from home is not having to. Exploit that flexibility. Cabin fever is a surefire way to burn yourself out, fast, so change up your environment regularly. Work out of a coffee shop or rent a seat at a co-working space for a day or two a week. Sometimes working from home can feel like solitary confinement, especially if you're deep in the trenches. The best thing about working from home is that you don't have to.

Listen to yourself—you're more aware than you realize

Mental health is to physical health as physical health is to mental. This isn't a diatribe about Cartesian ideologies—just listen to yourself. Are you feeling "hangry" (hungry + angry), incapable of solving something, or stuck? Train yourself to recognize when you're spinning your wheels and take a break. Please, take one because no one likes a hangry coworker. Go outside, rack up those FitBit steps, grab a banana and come back with fresh eyes.

Do something productive first thing in the morning

I've recently found that doing something that I can complete, regardless of the size, first thing in the morning is a huge productivity booster. For example, my roommates aren't the best about their dishes so as part of my "morning commute" to the kitchen, I take care of the them. In turn, my day starts off with a feeling of having knocked something off my internal list. I'm also a huge fan of Dots and will play a few games as soon as I wake up, before I even get out of bed. Nothing like a few wins to start off the day.

Create a separate space for your workspace

Another "work from home killer" is working out of your bedroom or living room. Stop that. If you can, do your best to create a well-lit, preferably sun-lit, space that is separate from your living space. It's incredibly important to be able to "leave the office" by physically leaving the area you work from. In doing so, you'll feel a little more at ease when hanging out in another part of your home as it won't feel so familiar.

Be realistic about your expectations for the day

#realtalk - Working from home can feel like longer days but in reality the time spent home is relative to that spent commuting and working in an office. Just check out how many hours we saved collectively last year by working from home—over 9,000. Be realistic about what you can achieve in a day. Communicate with your project manager, establish realistic delivery timelines and deliver on those promises. By establishing these goals for the day you've setup a mental contract for what to expect out of yourself. At the end of the day you'll feel accomplished rather than overwhelmed.


Have some of your own work-from-home-tips?

We're always on the look out for new ways to improve our day. Whether it's an activity, application, or process, we love living efficiently. Comment here or mention us on twitter, @intridea, and share your remote working tips.

Categories
Tags
Author

As a designer, part of my job is creating assets for blog posts, case studies and user profiles amongst other things. More often than not that means reaching out to someone, especially when it comes to head-shots, and being asked "What size image do you need?" The answer is simple—as big as you can give me.

Size Matters

We've all been here before, right? Someone is crafting up your company's next blog post and an image needs to be created using either stock or an existing photo. Save yourself an email or two by remembering that size matters, bigger is better and it's not the motion of the ocean that counts in this situation. Send your designer the largest picture you can muster up.

Here are some pro tips to keep in mind the next time you're asked.

Do's

  • PNG, JPEG or TIFF - All are okay, just send away, we'll deal with it.
  • Always error on the side of larger vs. smaller, always.

Don'ts

  • Crop.
  • Add effects.
  • Adjust or "enhance."
  • Scale it down or save it in a compressed format—let your designer do it.
  • Send anything smaller than 500x500—error on the side of larger and putting more work on the designer. Cropping in photoshop is > than an email chain.

Logos

AI or EPS only please. Sending a JPEG, PNG, or GIF of your companies logo is a great way to add a little frustration to your designer's day.

Icons

Hopefully you're using an icon font like symbolset but if you aren't then purchase the largest option and send them the vector versions.

Stock photos

If you're purchasing stock—go big, unless of course big means $$$$$. But let's get real, you're probably using istockphoto.com if you're purchasing stock, so use the extra credits and get something xx-large—your designer will thank you later. If you're not using iStock, or the like, then you'd probably want to discuss image options before even having this conversation.

Camera Raw

Again, send away. Unless it's some crazy obscure format we've probably got it covered.

Retina and hi-res

There are a ton of methods for dealing with this situation of which your designer and dev team have hopefully worked out. This is exactly why you should go bigger than the destination size. The designer will most likely want to work with the image a bit to ensure that it meets the needs of the device landscape and the more room you give them, the better the results will be.

But, but, but...

Surely there has to be more, right? Nope, designers are usually really good at working with images. Let them do what they're good at and save yourself the back and forth. The next time you're asked for a headshot or something just remember #biggerisbetter and give them the biggest mugshot you can find. I guarantee you'll see a greater return on your investment and an improved relationship between you and your designer.


Parting Thoughts

In all my years as a designer I don't think I've ever asked anyone to send me a 500x500 image for anything. Come to think of it, I don't think I've ever asked for anything smaller than 1024px wide. Why? Because bigger images mean more flexibility. The closer the image is to the destination size, the less room I have to work with. Sometimes I want to crop an image to a specific area or grab a smaller section for texture or something. Tiny images make this more difficult. More-so, sending small images could lead to a time-consuming email thread that leaves both of you sighing.

As a side note, destination size is kind of irrelevant as images need to accommodate a sea of devices nowadays. Like the logo, make the image bigger (but don't actually make it bigger, just get the largest you can find.)

Categories
Author

Recently, I was looking for a way to do a task N times in JavaScript (like Ruby's N.times method), which I found (_.times) in the Underscore.js library. This discovery exposed me to an alternate way to call the Underscore methods, using its chaining syntax.

If you do a lot of work with Backbone, this syntax will be familiar. In Backbone, you can call many of the Underscore methods on models and collections:

bookCollection.each( function(model) {   console.log( model.get('name') ); }); // >> 'American Gods' // >> 'Anansai Boys' // >> 'Coraline' 

But what might not be obvious is that if you want to iterate over an object with Underscore, you can do the following:

_(["American Gods", "Anansi Boys", "Coraline"]).each( function(book) {   console.log(book); }); // >> 'American Gods' // >> 'Anansai Boys' // >> 'Coraline' 

Which is the same as doing this:

_.each(["American Gods", "Anansi Boys", "Coraline"], function(book) {   console.log(book); } // >> 'American Gods' // >> 'Anansai Boys' // >> 'Coraline' 

This becomes beneficial if you're working on a Backbone project and have a non-Backbone object that you want to iterate over. Going from collection.each(function(){}) to _.each(objs, function(){}) can be jarring, while _(objs).each(function(){}) is less confusing due to its similiarity.

Ready to build an industry-changing product?

Let's talk about your project today >>

Categories
Author

As part of my work, I often create prototypes of Rails applications. My preferred tool for doing this is Serve. But as excellent as it is, it's a very thin application with no persistence layer. To be honest, I don't really want a persistence layer at this stage. But there are times when I want to be able to iterate over collections of objects the same way that I would in a Rails environment. Creating an index view of subscribers is a great example.

Now, I could just draft this all as html:

...but that's time consuming. Especially if you have more than a few. Sometimes you want to stress test a larger data set (to show pagination, for example, or to work out JavaScript performance on larger data sets) or just give a better match to real data.

To accomplish this, I use the Storable and Faker gems.

Enter Storable

Serve provides a views/view_helpers.rb file, which is where I will store my ruby code. Since Storable can read YAML files (and because I do often use fixture data in real Rails apps), I use YAML as my data store.

Let's set up the data store first, using a Subscriber model. You can go about this one of two ways:

  1. build your models by hand (the same way you would create fixtures for RSpec), or
  2. randomly generate a set number of models.

You should choose your approach based on what your end goal is; since I'm just trying to quickly populate a lot of data, I'll go with some random generation.

Enter Faker

The ERB loop uses the Faker gem to create a first and last name, which it then uses to create the object's key and describe the object's attributes. This setup will create 10 of these objects. I could even use this later to seed fixture data for tests; in that case, I'd define those objects manually.

Now that we have the data store in place, let's do something with it: create some ruby objects:

This creates a class that we can marshal our data in to, enabling us to create our collection. The field definitions default to being Strings, but (as you can see with :id) you can specify a type using Ruby's hash syntax.

Massage that fake data!

I've also added a full_name method to the class, since I know that I'll want to display a Subscriber's full name in the "first_name last_name" pattern. You can define any number of methods that you want here.

Next is a self.bootstrap method, which accepts a file path as a parameter. This reads in the specified YAML file, processing it through ERB (the load command with the ERB wrapper can be replaced by load_file if you're just using straight YAML), and then creates a new Subscriber instance for each object defined in the YAML file.

Finally, there's the self.all method, which similarly to the Active Record finder method of the same name, without the database call. It will search the active Ruby object space and return all of the objects of the Subscriber class.

This implementation of #all is a bit crude, but it works.

Voila

With all of that taken care of now, we can finally get back to our view and do this:

...which is much easier to maintain, especially if that bit of HTML code is rapidly changing. Storing the data in the YAML file (especially inside of a loop), means that adding/removing/modifying the object's attributes is much easier to do as well, and with a lot less typing.

Categories
Author

This past weekend I participated in Hack the Midwest, a Kansas City hackathon. The event was a huge success drawing a crowd of around 100 developers. As one of the visiting developer evangelists said, it was a great turnout for a New York hackathon, much less one in the midwest.

At the competition I built Qup.tv, a simple service that will send you email alerts when Netflix adds new titles to its streaming catalog. I was lucky enough to win top honors at the event, but this wasn't my first rodeo. With three Rails Rumbles, two Node Knockouts, and a Startup Weekend under my belt I'm beginning to get a sense of what works and what doesn't. So here's my list of things to keep in mind when competing in a hackathon:

1. Have a Layered Strategy

You will never accomplish everything you set out to complete at a hackathon. Something at some point will take ten times longer than it was supposed to, so you need to plan for having multiple goals any of which could end up being the final product. Your first stage should be something that you expect you can complete in well less than half the time allotted. For example, here was my layered plan for Qup:

  1. Users can sign in with their Netflix account and will receive emails of the latest Netflix releases
  2. Users can add items to their queue or watch them with one click from the email. For queueing, users should not have to be logged into Qup or Netflix
  3. Users can filter based on Netflix rating, Rotten Tomatoes score, and exclude genres they don't want updates about
  4. Track usage activity to be able to show which of the titles are most popular
  5. Add in support for Amazon Prime Instant Videos and/or Hulu

Even though my app won I only got through about half of what I thought I might be able to accomplish in 24 hours. I also ended up doing a decent amount of work tracking genres and usage activity which didn't show up in the final product at all because I didn't have time to polish and expose it. Which brings me to tip #2.

2. Cut Everything That Doesn't Work Well

It's a hackathon so judges will excuse a bug here and there, but regardless of how cool or important a feature is if it is likely to glitch more than 20% of the time you should cut it out of your final product. A smaller, less featured, but smoothly working project is going to win over a more featured but buggy project.

This applies to any kind of live demo in addition to a "go check it out" URL. Don't demo anything that the judges can't do themselves when they use the app (unless they don't get to use the app, in which case you'd better work hard to make sure your demo runs glitch free).

3. Style First, Substance Later

You can ignore this tip if you're working on a team with a dedicated designer (and how lucky for you if you are), but you should avoid the temptation to dive straight into the depths of coding when you start your project. Instead here are the things that you should do first:

  1. Create some kind of logo for your project
  2. Create the best looking landing page you can, even if it takes much longer than you'd like to spend on it
  3. Create accounts on Twitter, Google Analytics, UserVoice, etc. Anything you'll want to have at the end create at the beginning
  4. Buy domains, hosting accounts, etc. and get them all set up how they'll need to be

Why waste your time on all of these technicalities? Because the landing page is the first impression of your app that any judge will get, and if it doesn't impress them then you're already fighting an uphill battle. I spent perhaps the first hour and a half to two hours out of the 24 hour hackathon building the landing page for Qup, but that meant that I wasn't scrambling to make an ugly slapped-together mess pretty at the last second.

Integrate design and style as you go because when there's 45 minutes left you're always going to choose fixing a bug over polishing the interface.

4. Deploy Early, Often, Always

As soon as you have your pretty landing page and logo you should get your production environment up and running. If you can, use a Platform-as-a-Service like Heroku to take the operations burden off of yourself: you'll have enough to worry about on the app side.

Once you have a working production environment, make sure that you're deploying and smoke testing your code on a regular basis. There are almost always small (or large) problems that don't show up locally but do on a production box.

You'll notice that many of these tips have been about avoiding doing things at the end. That's because regardless of how carefully you plan you will be scrambling to fix earth-shattering bugs in the final minutes of the competition. It's tempting to put a tip like "don't deploy anything in the last two hours" because I've been burned multiple times by breaking something big while fixing something little at the last minute, but I won't. Instead you should be deploying SO FREQUENTLY that any fixes in the last minutes can be rolled back if they are deemed to be a bad idea.

5. In Presentations Show, Don't Tell, and Stop When You're Done

Your tech stack and the different ways you tackled the engineering challenges that your project presented are all very interesting. To you. Judges don't care, judges don't give a s**t. Instead keep your presentation focused only on the cool things your project does for the end user.

At Hack the Midwest we only had three minutes for presentations. Nearly everyone was running right up against the buzzer, so I was nervous. When it was my turn I gave maybe 20 seconds of exposition and then jumped right into the demo. I showed off my key features, anxious that any second I'd be cut off. In reality I probably still had a minute or more left. But rather than continuing to vamp about how I piped an RSS feed into an API queue fetch pool, I just stopped. I had already made my pitch, and I wouldn't do anything but hurt my chances from there.

Developers like to believe that code can speak for itself, and that's actually pretty true. However if your hackathon includes a presentation component you must speak for your code, so don't completely ignore a plan for presenting.

Do Something YOU Want

One last bonus tip is this: hackathons are about having fun, not winning. I've done seven of them and last weekend was the first prize of any kind that I've won. The beauty of the hackathon is that it gives you the opportunity to prove your mettle against yourself as much as against anyone else. It lets you say "what can I truly accomplish in X hours?". For me, this is a powerful drive and one that I'll gladly challenge myself with again and again. You can expect to see me in most every hackathon that comes around; I'm hooked.

Categories
Author

Ted O'Meara departs today for Salt Lake City, Utah where he'll spend the next few days immersed in the ever-evolving community of Ruby and Ruby on Rails developers. He's headed for destination: MountainWest RubyConf.

Ted came to Intridea two years ago as a designer and in just a short time he's proven to be a dextrous and pioneering leader. Not only has he become an accomplished project manager, he also plunged into the development world in an effort to become a more knowledgable and powerful designer. He did it. He crossed the streams.

While total protonic reversal was not a direct consequence of Ted's actions, he did actually learn a thing or two about the gaps between developers and designers and how small divergences in processes between the two groups effects the products they build. He'll be sharing his insights and solutions at MWRC this Friday.

In his talk, "UXDD (User Experience Driven Development): Build for your users, not your tests", Ted will propose practical and technological solutions to ways developers can increase the overall quality of their applications by aligning and testing their work against the user interface and flow.

In a candid example of why this is important, Ted posits the following user story:

Given that John has 30 pies
When he eats 3 of them a day
And he eats them for 10 days
Then he should not be hungry

And then adds "...but he might have gained 50lbs."

Throughout a project's lifecycle there may be several additions or changes to the overall user flow and back-end architecture. Following the principles of test-driven and behavior-driven development head-down might cause you to miss glaring errors in functionality for the user. So go see Ted's presentation this Friday at 4:30 pm for a Complete and Perfect Solution™ - he'll fix all your problems, ever. Just don't tell him I said so.

Categories
Author

One of my favorite aspects of Ruby is that just about everything is an object, even Class and Module. The ability to instantiate "anonymous" classes and modules can give you a great deal of power and help you out in situations where you otherwise might not have a clean solution.

What do Anonymous Things Look Like?

Anonymous classes and modules are just like other classes and modules but a little different. This can be seen best by example:

c = Class.new # => #<Class:0x000001009dea80> c.name        # => nil (normally this would be something like "Object") c.class       # => Class c.new         # => #<#<Class:0x000001009dea80>:0x0000010096b3c8> 

So what we did is create an instance of the Class class which is itself a class. Notice that by calling c.new I was able to create an instance of my anonymous class just like I would with a normal one. Now let's take a look at anonymous modules:

m = Module.new  c = Class.new c.send :include, m  c.ancestors # => [#<Class:0x000001028640b8>, #<Module:0x00000100849030>, Object, Kernel, BasicObject] 

Once you've created an anonymous module you can include it in a class just like you would with a normal module. Anonymous classes and modules behave just like the real thing, they just don't have constant names attached to them!

So now that you can recognize an anonymous class or module, how can you use them in the real world? Is this just a bunch of theoretical nonsense with no practical application?

Keep Specs Fresh With Anonymous Classes

Sometimes it can be difficult to test a module since you don't want to test it tied to a specific implementation. Let's say we have a module that looks like this:

module MyModule   def something?     true    end end 

How can we test it? One solution is to create a "test" class like this:

class MyModuleTest   include MyModule end  it 'should be something' do   MyModuleTest.new.should be_something end 

But there's a problem with that approach: since your test class lives outside the scope of your test, it doesn't get torn down at the end of each test run without manual intervention. So what can we do instead?

let(:fresh_class) do   Class.new{ include MyModule } end  it 'should do something' do   fresh_class.new.should be_something end 

Now we get a pristine class each and every test that we know doesn't have any state baggage. Anonymous classes to the rescue!

Anonymous Modules for Composite Functionality

So now we've seen an example of when anonymous classes can be used, but what about anonymous modules? Well here I'll show you a real piece of code from Grape, my framework for building REST-like APIs.

Grape allows users to define helper methods similar to Sinatra. When a user creates an endpoint for the API, Grape gives them access to all helper methods that were defined in the current context as well as parent contexts. We need a way to store all of the helpers that a user provides and be able to instantly create a module that is a composite of all of the helpers that were defined thus far. It sounds complicated (and it is, a little bit), but here's how we might use it in the end:

class MyAPI < Grape::API   helpers do     def user?; false end   end    namespace :authenticated do     helpers do       def user?; true end     end      get '/' do       user? # => true     end   end    get '/' do     user? # => false   end end 

Now here's the behind-the-scenes code that makes this possible (with some added comments to explain the usage of anonymous modules):

def helpers(mod = nil, &block)   # If a block is given or a argument passed the user is   # *setting* helpers.   if block_given? || mod     # Grab the existing anonymous module for this context     # or create a new one if there isn't one yet.     mod ||= settings.peek[:helpers] || Module.new      # Evaluate the block passed to the `helpers` method     # in the context of our anonymous module.     mod.class_eval &block if block_given?      set(:helpers, mod)    # If no block or argument is passed the user is   # *retrieving* helpers.   else     # Create a fresh anonymous module that isn't     # tied to any existing context.     mod = Module.new     settings.stack.each do |s|       # For each context in our stack, include the       # defined helpers in order.       mod.send :include, s[:helpers] if s[:helpers]     end     mod   end end 

Hopefully that isn't too dense to make sense, but anonymous modules allow us to create on-the-fly mixins that are included in the endpoint code to give you access to the helpers you've defined.

Go Forth And Be Nameless

These are just a few examples of the usefulness of anonymous classes and modules; they are powerful tools that can give you more flexibility in designing and testing your Ruby code. Do you have a cool use case for anonymous classes and/or modules? Let me know in the comments!

Image Credit: Astrojunta on Wikipedia

Categories
Author

As a QA Manager who often oversees more than a dozen projects at a time across both client/services and internal/product development I get an inside look at what helps projects succeed. Today I’m pulling my head out of the depths of QA Land to give you an important tip that’s been rattling around my brain cage for the last couple of weeks:

The squeaky wheel gets the grease

In other words, speak up. And keep speaking up until something is fixed.

Now I know that proverbs are silly to use since many of them are so contradictory: “good things come to those who wait”, right? Listen up folks — in the world of software development, good things do not come to those who wait. In fact, waiting around does absolutely nothing except tank your chances for successful delivery and implementation.

People have all different kinds of reasons for not speaking up: they’re too busy, they don’t want someone to think they’re complaining, they don’t want to feel like they’re a burden to the person who will have to make the fix, they don’t want to appear to be negative, etc.

Whether you’re a developer, a designer, or just someone who happens to be clicking around in an application it’s vital to speak up when you encounter things you aren’t expecting, or bugs, or undesired behavior from the application. The people that are working with the project are usually so deeply involved that it’s easy to miss surface-level mistakes that might seem so apparent to someone else. And if you don’t raise your voice about it, it might not ever get “greased”.

Here are some basic tips for “squeaking up” and getting heard:

Do:

  • Contact someone on the project and politely let them know what sort of ugly bug you’ve uncovered.
  • Be as specific as possible about the problem – give information about what browser (and version) you were using at the time, which OS, etc.
  • Take a screenshot if possible and annotate it, conveying the issue as clearly as possible.
  • Be proactive and create a ticket, including all of this helpful info about the bug in the ticket notes. This saves QA a step and ensures it gets (and stays) on their radar.
  • If the issue isn’t resolved, be sure to follow up with someone about it (politely, of course).
  • Explain the reasons you don’t agree with a certain type of functionality, citing helpful examples.

Don’t:

  • Yell about the problem from across the room, which will inevitably make the QA and dev team feel like you’re making a long-ranged attack.
  • Contact someone higher up in the chain than you need to – just report the issue to the person(s) that is working with the code daily and can help take care of the problem. Going above their head is an adversarial move.
  • Get angry if people disagree with your insights about a type of functionality – maybe you don’t see the reason for it, but the dev team insists, even after open discussions about it, that that particular functionality has to remain as-is.

In short, your product won’t be a great product if it’s chock full of holes, nasty bugs, odd functionality, and so forth. It’s everyone’s job to report the wonky things they come across, even if you don’t want to “bother” people. You can be “squeaky” without be “squawky.”

Categories
Author
Subscribe to Tips