Assigning permissions in TestFlight

TestFlight – “this device has not been given permission to install this build”

Have you seen that?  What a nightmare.  I haven’t seen this exact answer on the forums (SO) yet, so I figured I’d put it up here.

This one is so horribly obvious yet shockingly un-obvious it’s crazy.

When on the “Permissions” page in the TestFlight Dashboard, after uploading a build, you should see users in the “Teammates in the Provisioning Profile” list.  Seems good, right?  Only, they’re not actually authorized until they’re checked and you select either “Just Update” or “Update & Notify!!”

Are you kidding?!? I have three hairs left on my head, so I guess I got it just in time.

Leave a Comment

Stitcher Radio on Sonos / Using Facebook Credentials

I love my sonos.  In short, Sonos, along with iPhone and MBP are the only pieces of high-end consumer technology I use every day.  Unfortunately adding new services can often be tricky.  This is mostly the responsibility of Sonos, but also of the third-party providers a bit as well.  

  When integrating Stitcher to your Sonos, Sonos will ask for your Stitcher credentials.  Like most people, if you use Facebook authentication, there is an immediate bug in the UX flow.  You may try to enter your Facebook credentials (probably a bad idea already), but you already have a gut feeling that won’t work (which is confirmed shortly thereafter).

  In this case, the solution isn’t so bad.  Go to Stitcher’s beta online player at http://app.stitcher.com/  Make sure your account is authenticated through Facebook.  Now you can change the Stitcher password associated to your Facebook account.  In Sonos, use your Facebook email address and the new password you entered into Stitcher.

Enjoy a house full of podcast. 

Leave a Comment

Bootstrap Modal in MeteorJS

Meteor’s LiveHTML seems not to play nice with the standard Twitter Bootstrap modal.  When the content of the Modal is a reactive Meteor Template, the rerendering of the template would cause the modal to disappear.  Not sure exactly what was causing this.

While you create the modal content as ‘preserve’ or ‘contact’ type, this would limit your ability to use handlebar variables in your template.

My solution: create a function in the Meteor client.js code that shows the bootstrap modal one second after the page is complete.  See the example at the end of this post.

This gives Meteor enough time to load the modal template before rendering it.  If, however, the data elements in the modal template are “reactive” (meaning they are tied to data that should update their view), this again causes the modal to disappear.  I haven’t figured that bit out yet, perhaps someone out there has some thoughts.

$(window).load(function(){
var request_id = (RegExp('request_ids' + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
if (request_id) {
Session.set('fb_request_ids', request_id);
window.setTimeout( function() { $('#my_facebook_request_modal').modal(); } ,1000);
}
});

4 Comments

Phonegap solves your rapid mobile development needs

Phonegap solves your rapid mobile development needs

See the PowerPoint version of this post here - http://www.slideshare.net/jesses16/mobile-development-with-phonegap-and-ruby

Overview

Today I gave a short talk on how PhoneGap with Ruby provide a great system for rapid mobile development.  What do you gain by combining these technologies?

  • Accessibility & exposure – Get your mobile app into the various app stores, which is where your users will likely find them.
  • Familiar programming languages – Develop with your favorite backend system and familiar web technologies (HTML, CSS, JS).  Minimal or no knowledge of Objective C needed.
  • Access native capabilities – Access native features of the platform such as the camera and nav tools.
  • Unified code base – Use one project to power all your various platforms, such as iPhone, Android, and the mobile web.
  • Plugin Library – Not yet an overly active community, but there are some very good PhoneGap plugins ready to enhance and ease your development process.  https://github.com/phonegap/phonegap-plugins/

The clearest way to think about PhoneGap:

It’s a native code project that manages and exposes native functions to your web apps via JavaScript.

What a lovely idea.

Creating a project

There are a number of good resources for stepping you through your first PhoneGap project.  If you’re new to native development (xcode – iOS projects) there will probably be some gotchas.  However, this is fairly straight forward.

The PhoneGap “Getting Started” guide is a fine place to start. - http://phonegap.com/start#ios-x4

Structuring your git repos for PhoneGap

Perhaps the toughest part of the infrastructure setup is designing and configuring your git repos.  Again, the goal is to keep a single project for the application code base.  To do this, you will want to have a separate git repo for each platform-specific code base (free of core application code), and one for the core application itself.

Git Repo Structure

Git Repo Structure

In order to achieve this optimally, consider making your core application code a git submodule and importing it into your various platform projects.  In the figure to the left, there is a git repo for the iOS / xcode, which holds your MyApp.xcodeproj file, as well as all other xcode (and PhoneGap) libraries and code.  This stuff isn’t part of your application, it’s platform overhead, so it goes in its own bundle.  Same goes for Android project code (and Android PhoneGap libraries as well).

Your backend web data-serving application that powers the content of your mobile application is in a third repo.  This may or may not include your core app submodule depending on if you want to bundle in a mobile web version of your app.  Users will generally find your app through an app store, but if they hit the url with their mobile phone, it can be a nice perk if they go straight into the app.

The steps for setting up these repos is tricky, and requires that you think about it ahead of time.  The following post has a good set of instructions, which I based mine on.

See http://deadprogrammersociety.blogspot.com/2010/01/crossing-phonegap-for-multiplatform.html

Create the Repos

  1. mkdir MyApp
  2. mkdir MyApp/MyApp_IOS (could do the same for Android)
  3. Create XCode project in MyApp_IOS directory.  This means the XCode project files (such as your MyApp.xcodeproj and main project folder) live directly in this folder.
  4. Once you have gone through the PhoneGap Getting Started steps, a www folder will be created for you in this folder.
  5. Create a new repo (git init) in the www folder.  You probably don’t want a repository called “www” in your git account, so give this a better name in git.  Go to your new repo on github, and Admin page -> Settings, set a new “Repository Name.”  I used ‘MyApp_WWW.’
  6. Clone that www repo into the parent dir of a new shared location.  For me, I put this directly into the MyApp folder.  So now I have a MyApp folder containing two folders, one called “MyApp_IOS” and one called “MyApp_WWW.”
  7. Delete the folder MyApp_IOS/www.
  8. Create a git repo for the iOS / xcode in folder MyApp_IOS.  This is your second git repo, and remember, doesn’t contain a www folder at this time.
  9. In MyApp_IOS, run the command `git submodule add git@github.com:yourGitID/MyApp_WWW www`
    This will pull down the MyApp_WWW project as a submodule here, and name the local folder ‘www.’
git_submodule

This is what a submodule will look like

 

To pull down the code into the new ‘www’ folder for the first time, run `git submodule update init –` from the parent folder of ‘www.’  Now you can repeat step 9 for any project that has been designed to use a ‘www’ folder that contains the whole project.  This takes some configuration work on your end.  I’ll talk more about how a Ruby application might look that supports this below in the section Mobile Web App and Backend Server.

Updating the Submodule Repo

When you make updates to the shared submodule, you need to go to the folder of each platform-specific project and pull down the latest submodule code.  Do that with the following commands.

  1. `cd` into the ‘www’ folder.
  2. git checkout master
  3. git pull – this pulls the newest code down into your local code for this platform
  4. cd ..
  5. git commit ./www -m “pulling newest www code” – This step pushes back up to git the fact that your platform project is using the updated version of the www submodule.

Some more information – http://stackoverflow.com/questions/5828324/update-git-submodule?answertab=active#tab-top

Mobile Web App and Backend Server

Flat File Structure

Flat File Structure

The goal of this approach is to enable fast, friendly mobile app development.  With this system, you can have one code base for multiple platforms.  However, that means your different platforms should use the core app code repo in the same format.

In order for this to work for the majority of platforms, keeping a flat code structure is key.  For instance, the asset pipeline in Rails 3.1 is great, but won’t work well under the xcode / PhoneGap project.  See the image to the left as an example.

I used a simple Sinatra app to serve the mobile web application, as well as the backend project that actually served data to the application.

Private Git Submodule with Heroku

Heroku will accept your project with submodule, but it will fail during deployment if your repo is not public.  Importing gems has the same restraint: private gems cause issues in Heroku as well.  Below is a link with some ways to get around this issue.  I believe the quickest / easiest solution is to do the following:

  1. Create a new account in github, probably called something like MyAppServiceAccount.
  2. Add this account as a collaborator in the MyApp_WWW repo.
  3. In the MyApp_Mobile folder, modify the .gitmodule file.  Change the URL to the submodule to the format:
    `url = https://yourGitID:password_for_yourGitID@github.com/yourGitID/MyApp_WWW.git`

Now, Heroku can successfully access your submodule!

http://stackoverflow.com/questions/4840680/how-can-i-specify-a-gem-to-pull-from-a-private-github-repository/8949955#8949955

JavaScript Configuration Code Snipit

JavaScript Configuration Code Snipit

Custom Configuration

You may find that you need to do some (hopefully minimal) configuration of your application depending on the platform being used by your user.  There are a few options for you here, but nothing great.  I have yet to find an easy way to read xcode plist files into PhoneGap javascript code, but hopefully this is something the PhoneGap peeps implement soon.  See the below code snipit as an example.

Finally – A Theme

Don’t forget to use ThemeForest.net to find a great mobile theme for your app.  Spending $7 is a lot easier than getting good at PhotoShop!

Leave a Comment

Great Set of Slides on Designing Large Javascript Applications

Read through this today, and found it quite useful.  Not something I’m chomping at the bit to try, but insightful nonetheless.

http://speakerdeck.com/u/addyosmani/p/large-scale-javascript-application-architecture

1 Comment

Learning about memory in Ruby/Rails

Today I realized an error in my railsy ways.  It seems obvious the cause of my server crashing (something I had until recently been blaming on Phusion Passenger, sorry guys!) is actually an out-of-memory situation.  Memory usage goes up (as seen in passenger-memory-stats` and `top`) and doesn’t come back down.  What’s going on here?!?

I first feared a memory leak, or something of the sort.  I installed the Ruby debugger (ruby-debug gem) and began stepping through the application.  This was somewhat helpful in pinpointing where the vast memory grabs where coming from, but was a bit too low level.  It did make apparent that they weren’t all coming from a single request.

After fearing a memory leak, and doing some associated searching, I found the following post that apparently nails my issue on the head.

http://www.engineyard.com/blog/2009/thats-not-a-memory-leak-its-bloat/

So, I’ll be installing Oink or Memory Logic and following the instructions seen on that site.

The point in particular I fear is hitting me the hardest is:

<code> @posts = User.find(:all, :conditions => {:activated => true}).posts </code>

“This could feel ‘safe’ to you, because you only have 50 users and maybe a total of 1000 posts, but the include specified on the has_many will load in all related comments – something you probably weren’t expecting.”

Wow! Are you kidding me!  I know rails is a language of convenience, but that’s a bit ridiculous.

A comment on the above post was also helpful in giving a brief review of Garbage Collection and memory management in Ruby.  See below:

—-

” ‘On top of that, Ruby is greedy with memory—it doesn’t hand the memory back to the OS after the request.’

Just to elaborate on the above statement :

Basically the GC allocates an initial heap space of 10k slots.Each slot is large enough to hold an object.Whenever the first heap is maxed, a GC run triggers, attempts to free more space and eventually allocates another heap area if free slots is less than 4096.

The second time this happens, another 10k slots is made available.Additional heaps from this point onwards is allocated in slabs of ( last heap size allocated * 1.8 ).This is why jumps from 70MB RSS to 120MB RSS etc. is so common.

Ruby uses the libc memory allocation functions malloc, realloc, calloc etc.Stock malloc implementations don’t return allocated memory back to the OS until the running process exits.This is an optimization to save on syscalls (brk) and to ensure relatively fast alloc/dealloc during the process lifetime.

The JVM for example allocates a memory region of 168MB with mmap on startup, which pretty much assigns all memory management tasks to the various GC implementations for the runtime.This platform, and JRuby for that matter, doesn’t have this ‘greedy’ behavior and it’ll just be able to return memory allocated during an intense spike back to the OS. “

I think I have a new-found respect for JRuby, without even having used it.  I’ll likely be giving it a try, once I get my per-request memory usage down ;) .

- Jess

Leave a Comment

Follow

Get every new post delivered to your Inbox.