Matt MacDonaldStatus Rejected: You Should Create A Canary Build For Your iPhone App

Matt MacDonald posted on Friday, March 15th, 2013 | Android, iPhone, Mobile | No Comments

Submitting your shiny new iOS app to Apple for review is anxiety provoking. We’ve built a number of apps for both iOS and Android and the review and approval process for iOS still makes me worry. We spend time developing apps, prepping marketing materials and coordinating press releases with PR firms on larger projects. You don’t want to see this message just before your targeted launch date:

iTunes Connect rejection notice

iTunes Connect rejection notice

Enter the “canary build”. We’ve do our best to adhere to code and UI guidelines that Apple publishes, they change, we try to keep up. Still, we’ve found that the only way to really know if your app is going to be approved is to actually submit it for review. We call these “canary builds”. When we hit critical milestones in our development process we often will submit a build to Apple that we have no intention of releasing to the public. The approval process is a pain, but you really don’t want to find out that you have an issue just days before your app is released. We use the setting “Release Control Hold for Developer Release” when submitting these updates so that we can get an app into the approval queue, have the Apple review team ferret out any potential issues and then make our changes.

After having a few apps rejected a little too close to a deadline we started using these as a way to catch things earlier in the process.

Hope that helps someone else.

That is all,
Matt MacDonald

Chris RhodeniOS 6.0 Causes CDN Overages

Chris Rhoden posted on Wednesday, November 14th, 2012 | iPad, iPhone, Mobile | 26 Comments

We received a report from the folks at This American Life of extremely high bills from their CDN for the month of October. It is our belief after researching the problem that this is caused by bugs in the iOS 6 Audio Playback frameworks resulting in files being downloaded multiple times – this could result in dramatic overage charges for both content distributers and data plan customers.

Background

We had seen a pretty intense spike in traffic on 99% Invisible and The Moth (both of which we host) last month, and had a pretty good idea of the when the spike began as a result. At the time, we had chalked the rather extreme increase in bandwidth (seen below) to the release of Apple’s new Podcast app, which featured 99% Invisible prominently at release. We figured that Apple had brought 99% Invisible and The Moth some new subscribers, and were pretty happy once we had battened the hatches a bit.

But when we heard from This American Life that they were seeing an order of magnitude increase in their bandwidth usage, we needed to ensure that there wasn’t a problem with our apps that was causing unusual download behavior. Based on our research, it looks like the issue is iOS 6.

The Behavior

To begin, we wanted to know if there was a way that we could differentiate traffic originating from one of our apps from traffic originating from other apps. Because we are using the AV Foundation framework, it turned out that we couldn’t (the User Agent String is the OS Standard one, not app specific). We were able to see that the version of iOS was 6.0 but not the name of the app playing the audio. However, the Apache logs we looked at suggested something unusual. In the following screenshot, the file being downloaded is 8614457 bytes long.

Click to view full size.

What you can see is that the first 2 bytes of the file (in most cases, this will be ID, as in ID3) are downloaded in one request and then what appears to be the file being downloaded multiple times on iOS 6 and only once on iOS 5. (This appears to be an artifact of the way that Apache logs range requests, and we have reason to believe that the file was not downloaded many complete times, but there are still clearly problems.)

Following this, we set up a proxy so that we could watch requests as they were coming from the app. The player appears to get into a state where it makes multiple requests per second and closes them rapidly. Because the ranges of these requests seem to overlap and the requests themselves each carry some overhead, this causes a single download of an MP3 to use significantly more bandwidth than in iOS 5. In one case, the playback of a single 30MB episode caused the transfer of over 100MB of data.

We saw this behavior start after a period of behaving correctly (in some cases behaving correctly for about 5 minutes before the issue appeared) in both our own apps and the Apple Podcast app. We were able to reproduce the issue with several podcasts in the Podcast app, including podcasts using Limelight and Akamai CDNs. We have been unable to reproduce the issue using iOS 5 or using iOS 6.0.1, but there are still many people using iOS 6.0.0. We believe that this issue, combined with the bug causing the phone to behave as though it is connected to WiFi even when it is not, could account for the significant data overages reported with the release of iOS 6.

The strangest bit of behavior happens when the ranges on these requests reach the end of the file. We were able to consistently see that when the file has completed downloading, it begins downloading again from the beginning of the file and continues for as long as one is streaming the file. This means that, for as long as one is listening to audio being streamed with iOS 6, it is using significant amounts of data. Watch the range headers in this video, which is monitoring the HTTP activity of the stock Podcast app (v1.1.2) on iOS 6.0.0 playing back an episode of This Week in Tech. The file finishes buffering and is completely downloaded at around 0:36.

Conclusion

There appears to be a system-wide problem with the AV Foundation framework in iOS 6.0.0, resulting in significantly higher data costs to iPhone users and internet distributors. Users who have not done so should immediately upgrade iOS 6.0.0 devices to iOS 6.0.1, which we can confirm appears to fix the issue on Wifi. While some carriers are offering concessions to customers who may have been affected by this problem, Apple does not appear to have acknowledged the specific issue. The release notes for iOS 6.0.1 mention a change related to Wifi (likely referring to the problem with devices that reported that they were connected to Wifi while connected to 3G and LTE networks), which may be related to the change which fixed this issue.

Caveats

Our tests did not cover 3g or LTE data, as we relied on connecting to Wifi to perform them. Because of the server logs we have access to, it appears that this issue exists over mobile broadband as well.

Rebecca NessonGrowing the Ranks of Female Devs

Rebecca Nesson posted on Thursday, September 6th, 2012 | Rails, Ruby, Ruby on Rails | 1 Comment

At PRX I am the only woman on a team of six.  With a team that size, it could be a coincidence that I’m the only one.  But it is not.  In most companies with six developers, zero would be female.  I’m here at PRX because of my skills but also because PRX cares about having and encouraging a diverse workplace.  We took that beyond our office a few weeks ago when we participated in a full-day free workshop focused on teaching Ruby on Rails development to interested women.  In one evening and one long day we taught 44 students enough so that by the end of the workshop they had each deployed their own web application live on the Internet.  You can read an interesting and thorough recap of the event, replete with pictures, feedback, etc., here.  Also, if you’re interested in participating, we plan to do another workshop with the same format later this fall.  You can find out more on our site.

PRXers had roles in every aspect of the workshop.  Dan Choi, a former PRX employee and contractor and permanent PRX friend, was the driving force behind the workshop and the main organizer.  We developed the curriculum with a team of volunteers from BostonRB including Andrew K., Chris R. and me from the PRX team.  I was the main lecturer/teacher for the workshop,  Andrew was a teaching assistant and lecturer, and Kathryn Bennett, a tech intern at PRX, also TA’ed. Genevieve, who works on the content side of PRX and does a lot of work in our content management system, participated as a student.  And PRX backed the event financially as one of the sponsors.

The main goal of the event was to encourage people with no previous experience to get involved with Ruby/Rails development, and I believe we succeeded.  But for me there was another positive outcome.  In putting on the event we pulled together a team of volunteers, teachers, and sponsors who all see the importance of an inclusive, diverse community of developers.  At this one event I met and worked with over ten other female Ruby/Rails developers many of whom work in places where they are the only girl.  I had only met two of them before, and I was frankly but happily surprised that there were so many of us.  It helped show me that the community we were envisioning is already nascent among the women who are working as developers and the colleagues, companies, and organizations that are supporting us.

I’m proud of what we accomplished and of PRX for having a strong hand in it.

Chris Rhoden99% Invisible Countdown to 5000 Backers

Chris Rhoden posted on Tuesday, August 7th, 2012 | Uncategorized | No Comments

1) Go to the 99% Invisible page on Kickstarter (http://www.kickstarter.com/projects/1748303376/99-invisible-season-3)

2) Copy and paste this whole string into the address bar and press enter:

(note: Google Chrome seems to strip the “javascript:” from the beginning if you paste it into the address bar, so make sure it’s there before you hit enter or else this won’t work!)

Matt MacDonaldKCRW Music Mine app on Spotify

Matt MacDonald posted on Tuesday, June 19th, 2012 | KCRW | No Comments

When PRX worked with KCRW last year to design and develop the Music Mine app for iPad, we knew that there was a reason we spent time and effort building a reusable API — we just didn’t know that we’d be building a Spotify app with it.

Last fall, the popular music-streaming service Spotify announced that they were creating a platform for developers and music-focused companies to create apps that would be available in their desktop music software. Basically it’s the ability to have an app inside of an app — in our case Music Mine inside of Spotify.

KCRW recently reached out to PRX, and within a week, we had conceptualized, designed, built, and delivered a fully functional Music Mine Spotify app to KCRW. We got the word from KCRW late last week that the app had been approved. We’re excited to be the first public media app on the Spotify platform and are even more excited to see the analytics and numbers once they are available.

If you use Spotify you can click on this link and it’ll install the app for you.

Matt & The PRX Tech Team

Chris RhodenPBS Frontline QR Code Hack

Chris Rhoden posted on Monday, May 7th, 2012 | Javascript, Mobile, Node.js | 1 Comment

Hey everyone! I recently built a system which was designed to turn your phone into a sort of smart remote control which works over the internet. This is the first part of a two-part post about that system, where I discuss what I built. In a future post, I will discuss how everything was put together from a much more technical side.

A couple of weeks ago, I participated in a hackfest which was thrown by the folks at Frontline. The goal was to spend a few hours putting together a glimpse of the future of documentary storytelling. Four projects came out of the day, but I would like to talk about the project I worked on.

As far as I could tell, I was the only developer resource on the team I was on, which resulted in a bit more focus on the technical aspects of things than is typical. As such, I can tell you that the documentary I worked with was:

  1. Already slated to receive some level of interactive work.
  2. About the abuses of our economic system by Wall Street.
  3. A Frontline documentary.

There’s really not much else I could say. I did end up watching the trailer a bunch of times, but even that started blurring, as my primary goal was to get something that sort of worked ready for demo.

The point of all of this context is that it seems very clear to me that this could be used in a variety of situations – not just those where a documentary is concerned. Anyway, on to the demo.

The first interaction you will have with the system is a QR code, which you are invited to scan with your phone. This QR code points at a mobile-optimized website.

When the website loads in your mobile browser, the QR code disappears and a video begins playing on your computer. The video on the computer screen is deliberately uncluttered, as the point is to allow you to watch the video in a lean-back manner, with no need to interact with your computer.

In your mobile browser, you are given a big green button which also acts as an indicator for your progress through the film. Pressing the button causes a bookmark to be saved of where you are in the film, including context for the segment you were watching and, in some cases, additional content and research. During our demo, one segment of the film, when bookmarked, provided access to watch additional raw footage.

When the bookmark button is pressed, a small indication is shown on the main screen that the bookmark has been saved.

The goal for the project was to provide a way to augment a viewing experience while in no way compromising the narrative created by the filmmaker. There were a number of additional features which I would have loved to have implemented, such as controls for the onscreen content, and a dashboard showing your bookmarks on the main screen when the video has finished. That having been said, I believe that the goals for the project were shown off well, and am proud of what we walked out with.

Next time, I’ll go into the actual guts of how this system worked, and maybe some other uses for the technology.

Rebecca NessonHacking Open Education with the Berkman Center

Rebecca Nesson posted on Monday, April 30th, 2012 | Uncategorized | 1 Comment

On April 13th PRX sent me to represent at the Berkman Center Open Education Resources hack day.  The hack day was a one-day event on the final day of a three-day conference about Open Education Resources among the Hewlett OER grantees.  SJ Klein and Erhardt Graeff led a crew of ~60 OER enthusiasts–perhaps only 10-15% of whom were coders–through a process of generating and winnowing ideas, planning, execution, and an ultimate two-minute presentation to a panel of judges.  Although I’m no expert on hackdays, the relatively low ratio of coders seemed notable to me.  It resulted in a selection of hacks that mostly did not involve running code but comprised a set of projects with potential for real future value in the OER community.

SJ and Erhardt divided us into four groups and asked us to winnow the big list of ideas brainstormed the night before down to our top ten, adding any new ones we had on the way.  Once we’d done this we combined with another group and did another round of winnowing.  Then we joined all together and did two rounds of straw polls on the remaining projects to help us self-select into working teams.  I’m not sure I can recall every project, but here’s my best stab:

* Revising the Wikipedia page about OER.

* Designing a Webby- or Oscar-like awards contest for the best OER of the year.

* Designing software to help present a personal gallery/portfolio of OER accomplishments.

* Creating an online course to teach strategic thinking using Poker

* Using git as the basis for a collaborative OER repository

* Creating an open-source web application that works like Free Rice but can be implemented with local standardized test questions and local sponsorships

The open-source Free Rice project was an idea I contributed in the first round.  It’s an idea that my father and I have been interested in for years and it seemed like a good fit for the day.  I was happy to see it progress through the rounds of winnowing.  Ultimately Matthew Battles of Metalab and Jeff Mao of the Maine Department of Education chose to work on it with me.  We spent some time discussing how we could make the project into something that school systems would be able to use and decided that ideally the system would be able to hook into an API provided by the testing company with which a school system contracts.  While Matthew and Jeff worked on ideas about the API and a presentation of the idea, I started to hack.  The time for actual hacking was short: about two and a half hours.  So I was happy to have gotten enough up and running just to do a short demo.  You can see the results of that here:  http://freepencils.herokuapp.com.  Jeff and Matthew did an excellent presentation while I clicked around the app on the big screen behind them.  And lo and behold we were selected as winners of the day along with the Academy Awards for OER project.

The hack day organizers are working on a write-up of the day for the conference blog that will give more information about all the projects.  In preparation for that Jeff wrote up a short text version of our pitch.  Here it is:

Many states (48 including DC and 2 US Territories) have adopted the Common Core State Standards for English Language Arts and Mathematics. This is the first time in the history of US Public Education that we will see common learning standards across so many States. Part of this effort is the development of a shared assessment platform that seeks to provide an open source adaptive assessment system that will support formative and summative assessment for classroom, school, district, and state-level use.

Building upon the success of the World Food Programme’s FreeRice.com site, we proposed to build a tool that would mimic the style of FreeRice’s educational and fundraising process. Answer questions correctly, and earn tokens that would have real-world value toward a local or national good cause. We called our effort “FreePencils”, and would use the pencil as a token similar to FreeRice’s 10 grains of rice per question. The tool would sit between the end user and the Smarter Balanced Assessment Consoritia (SBAC) adaptive testing engine, and use released items shared through that system. Schools would be able to localize this tool so that as students answered questions correctly, they earned pencils. These pencils would have an equivalent real world value based on the school’s local fundraising efforts. For example, a school could get local sponsorships from families, local business, and others. These funds would be distributed to the school or any identified good cause based on correct answers to actual released items from the SBAC assessment engine. This would provide practice to students and at the same time, provide a method of fundraising.
In addition, the tool could be set up at a national level with national sponsorships. Funds from this effort could be directed to a national cause, educational or otherwise.

Chris RhodenAnnouncing PlayerHater. Hate the Player, not the Game.

Chris Rhoden posted on Tuesday, March 27th, 2012 | Android, Mobile | No Comments

TL; DR: Happy Tuesday! I wrote a library for working with background audio in Android apps. PRX is letting me give it away. Yay Android! Yay PRX!

Let’s talk a little history, shall we?

PRX makes mobile apps for public radio programs and stations. When we were asked to make an Android app for This American Life, we found that the Android ecosystem was just a little bit fractured. We built a very large and somewhat messy chunk of code to help us work through the issues of supporting 4 different major versions of an operating system, including handling weird and widely covered bugs and device/os interactions.

But no more! We found that by dropping support for the very very old versions of Android, we were able to lock into a much more stable API. There’s still a whole bunch of work that needs to be done in order to start playing audio in the background properly, though (think foreground notifications, the prepare/play api, and handling audio session changes). So I set to work building something completely from scratch which tackles these problems. We even thought long and hard about what should happen if your audio is interrupted with a phone call (we start back up again when you hang up if the call took less than 5 minutes. Otherwise, we kill the session.)

There are a whole bunch of goals for the player moving forward, including a default player widget and notification with play/pause buttons where they’re supported. For now, we hope that the dramatically simplified API and sensible default behavior will be useful to some people, and we can gain enough traction to make PlayerHater the de-facto way to play background audio on Android.

Check out PlayerHater on GitHub and let us know what you think!

Chris KalafarskiOut with the Flash, in with the flashy

Chris Kalafarski posted on Tuesday, March 20th, 2012 | Audio, HTML5, Javascript | 9 Comments

FlowPlayer has been PRX’s audio player of choice (ok, not really a choice) for a very long time. Even without a mobile-specific version of PRX.org, we’ve seen a dramatic increase in the number of requests for a way to audition pieces on an iPad. It’s simply a matter of people’s usage habits changing. While an HTML5 audio player has been on our radar since browsers began supporting the technology, demand finally reached a point where the transition became necessary.

There are several fairly robust open source projects out there to help with the switch. MediaElement.js and jPlayer were the two main contenders, with jPlayer winning out do to internal familiarity. Both work by having a Flash fallback option when the native HTML5/JavaScript handling in a given browser can support the file. jPlayer allows you to define multiple source files to help with browser coverage. Currently our catalog is mp3, which IE8 (and lower), Firefox, and Opera do not support natively. We would need to re-encode our entire catalog to ogg or WebM to provide native support there, which may happen at some point, but for now relying on the Flash fallback in jPlayer is a perfectly acceptable solution.

One major advantage of having a single player UI and having it built in HTML that will be consistent across all platforms and browsers regardless of what’s handling the audio is extensibility. Whereas previously we had slightly different Flash widgets for the main player, the popup window player, and the embeddable player, we now need to only maintain a single HTML file. The player is fluid, so it will resize to fit whatever space it is given. Adding additional features or elements to the player down the road will be an extremely simple process.

The move hasn’t been without issue. jPlayer has a few shortcomings that we’ve had to work around. The most significant being an issue with the way in which the Flash player reports file duration when the file is loading. It often fails to accurately estimate the total duration before the entire file loads. This can cause some unexpected behavior with large files. It was fairly trivial to work around, but it shows that supporting two vastly different technologies at the same time is not an exact science. There are a handful of finicky UI limitations with jPlayer as well. Want a vertical volume bar? Get ready to fork.

Performance as a whole, though, has been good. Even on some of our playlist pages which load up dozens of individual players, results from our testing has on par with or better than FlowPlayer.

We’re very excited about the prospects of having this new player out in the wild. Aside from the obvious benefits of iOS support, and the boost in street cred for having using more HTML5, there are likely some advantages we haven’t even considered yet. PRX hopes to help drive innovation in this space, so expect to see any improvements we make flow back into the community.

Old vs New:


Demo

Rebecca NessonA graphical pseudo-3D environment in an Android app

Rebecca Nesson posted on Tuesday, March 13th, 2012 | Android, iPhone, Mobile | 2 Comments

At PRX we’re lucky to get to work with creative, fun-loving clients who want their apps to be more interesting to play with than the average app made from iOS standard components or Android widgets.  In one app we’re currently developing, we’re creating an engaging and fun pop-up book style environment in which the user encounters the program content as she navigates through an imaginary world.  It’s beautiful and fun and a real programming challenge.  On the iOS side, Devin created the 3D-ish environment using native iOS layers positioned in 3D space.  It’s my job to create the same effect in the Android version of the app.  The native views in Android don’t support this kind of positioning in z space and there isn’t a build in “camera” that can be transformed to give the illusion of depth.  OpenGL could provide the 3D environment, but it would be a steep learning curve for me and it would make it harder to use the usual Android widgets and activities for performing the basic functions of the app like presenting lists of content and playing audio.  Enter AndEngine.

AndEngine is a free 2D game engine for Android.  It allows the creation of a game activity that I could combine with other Android activities to present content.  (I use Android Fragments via the Android Support V4 library to incorporate traditional Android views into the game environment.)  Although AndEngine is intended for 2D games, a forum thread demonstrated how to do the same perspective trick to the camera we’re doing on the iOS side:

 private void setFrustum(GL10 pGL)
 {
    // set field of view to 60 degrees
   float fov_degrees = 60;
   float fov_radians = fov_degrees / 180 * (float)Math.PI;

   // set aspect ratio and distance of the screen
   float aspect = this.getWidth() / this.getHeight();
   float camZ = this.getHeight()/2 / (float)Math.tan(fov_radians/2);

   // set projection
   GLHelper.setProjectionIdentityMatrix(pGL);
   GLU.gluPerspective(pGL, fov_degrees, aspect, camZ/10, camZ*10);

   // set view
   GLU.gluLookAt(pGL, 0, 0, camZ, 0, 0, 0, 0, 1, 0); // move camera back
   pGL.glScalef(1,-1,1); // reverse y-axis
   pGL.glTranslatef(-CAMERA_WIDTH/2,-CAMERA_HEIGHT/2,0); // origin at top left
}

What’s happening here is that the camera is being pulled back away from the scene and a perspective transform is being applied that causes things in the distance to appear farther away.  I can’t explain it any better than the cryptic m34 transform that is applied to the camera on the iOS side, but the effect is the same.

The only other modification I had to make to AndEngine was to create a 3D sprite class that wraps the provided Sprite class and allows the user to set the z position of sprites as well as their x,y position.  In our app world the user doesn’t interact directly with the scene but rather with an scrolling mechanism that moves the scene “on rails” as the user scrolls.  The effect is beautiful but also somewhat hard to capture in screenshots.  You’ll just have to buy the app when it comes out!

The good news is, the app is shaping up beautifully and AndEngine has really come through for what we needed to do.  But there’s a big remaining issue that I’d like to solve.  AndEngine takes care of all of the touches on the scene and passes them to the sprites.  But it does it based on their x,y coordinates.  Unfortunately, the x,y coordinates it calculates based on the touches of the screen do not correspond to the location of the sprites within the scene because of the perspective transformation based on depth.  Under the covers OpenGL knows where the sprites are because it drew them correctly on the screen, but AndEngine itself does not know.  Additionally, I can only get access to a GL10 instance which does not provide the functions I need to project and unproject coordinates.  For now I’m working around this issue, but theoretically I should be able to do the math to convert 2D screen coordinates into 3D scene coordinates using the ratio of the scene size to the screen size, the position of the camera, the angle of view, and the distance of the object in question from the camera.  So far I haven’t succeeded in doing it, but when I get a few days to step back from the project I’ll turn to it again.  If you think you know how it should be done, please comment!

Support Us!

PRX

Categories & projects

Archives