Categories

TestFlight: Flooded

Getting flooded with notifications?

We’re here to help! As the developer community scrambles to adjust to iOS 6, we’ve had to make some changes here at TestFlight as well. Here’s a few tips to help your testers get over pesky hurdles and get your SDK up to date.

Device re-registration fixes for iOS5 and iOS6

We’ve seen some errors surface with device re-registration due to our SSL certificate update changing from www.testflightapp.com to a wildcard cert *.testflightapp.com. These steps will help get problematic devices back to testing in no time:

  1. Remove the TestFlight webclip profile (settings>general>profiles)
  2. Clear the cookies and cache
  3. Restart Device
  4. Login to https://testflightapp.com/dashboard/ on Mobile Safari.
  5. Touch register and complete the registration process.

For more information, read our related support article

Get iOS 6 compliant! SDK 1.1

Now armed with armv7s and iOS 6 support! Download TestFlight SDK 1.1 and get better control of your tester feedback, log customization, and more. Don’t have our SDK implemented yet? Check out our documentation here.

Download TestFlight SDK 1.1 Now

Desktop App Updates

We’ve just released Desktop App Version 1.01 (294) to accommodate iOS 6. This fixes variable exports related to Apple’s new codesign_allocate tool and SDK not found errors. Update to the latest version now!

In short, performance has improved but we still have some work ahead of us. Specifically, TestFlight should be much faster but TF SDK / TF Live improvements are still in progress.

Below is a list of completed improvements and upcoming items.

New Faster, Simpler SDK front ends

We are primarily a python shop, in wanting to stick with what works and add some simplicity to our stack we built a raw gevent based server. These servers depend on a local redis instance that slaves off our redis cache master. The complete server role looks like stud -> nginx -> gevent -> local redis. TestFlight core updates the cache master and redis takes care of synchronizing the front end caches. We are really pleased with this approach. It has decoupled the SDK from Web nicely and it has given us the ability to burst to the cloud when necessary.

For developers interested in other details here is a hit list of some of the less obvious things we ran into:

  • [Improvement] nginx did not handle our SSL traffic, moving to Stud showed significant improvements.
  • [Improvement] one of our bare metal SDK boxes keeps up 4 SDK VMS. Bare-metal ftw!
  • [Cool] “fab deploy.sdk:production,git tag”, now pings a deploy server which packages the git tag and each SDK front end periodically checks in with the deploy server to get the latest package.

Faster TF Core

TestFlight users are first and foremost distributing betas. Not only do we take pride building tools developers love to use, we also strive to provide a seamless experience for your testers and stakeholders. In the last few weeks we have made strides in improving the reliability and performance of TestFlight core.

The addition of the new SDK front ends isolated SDK web traffic and database read traffic. This has had the biggest impact on the perceived performance of TF core. Here are are a few of the other things we addressed:

  • [Fixed] Turns out our continuous deploy process since migrating our infrastructure caused failed requests . Formerly we had gunicorn operating on two ports behind nginx, so nginx masked this issue by kindly directing the request to the second port. We’ve resolved this.
  • [Improvement] Switched from meinheld to gevent as our gunicorn worker class. This improved performance by virtue of it having more consistent behavior and better logging so we could actually see the issues that come up.
  • [Fixed] Killed a few slow queries that brought us to our knees.
  • [Improvement] Changed our mysql replication strategy to reduce IO.
  • [Improvement] Decoupled our message queues so TF Core and TF SDK, isolating failures.
  • [Improvement] Decoupled data source dependent features (SDK Debugger, Activity Feed, TestFlight Live). Decoupling these introduces some isolated failures.

No More Failed Uploads

Uploads fail for a variety of reasons. Mostly they fail because the upload IPA does not make it past our validation checks. But more recently they started to fail simply because it was taking way too long to upload and the clients browser would give up, or by the time the binary passed through nginx to our front ends, our front ends were overloaded dealing with other things.

The good news is that those problems are now behind us. So, failed uploads due to system reliability should no longer be an issue. If at any point you do have upload errors, please let us know.

Current Focus

With all of the effort and improvements on the SDK front ends we have pushed the bottleneck back to the SDK workers and persistence. A new backend for both the data processing and persistence has been under way for the last couple weeks, and should get integrated this week. If you see some oddities with the site please let us know. We are putting in the effort to make the transition seamless but very much appreciate the heads up in the event we’ve missed something.

Next Focus

Once we have the improvements to the SDK workers and persistence flying we will turn our focus to TestFlight Live. We look forward to resolving the issues and appreciate your patience.

SDK Networking Bug!

There has been quite a few reports of the TestFlight SDK conflicting with AF Networking (https://github.com/AFNetworking/AFNetworking/issues/307). If you are having this issue please send a sample app that can replicate to http://help.testflightapp.com. We’d like to resolve it immediately but so far have not been able to reproduce the issue.

The TestFlight Crew

P.S. We’re hiring! (https://testflightapp.com/jobs/)

When: Sunday, April 30 at 3PM PST (Sunday, April 30 at 22:00:00 UTC)

Estimated downtime: 20 minutes

Continuing our efforts to bring you a faster more stable TestFlight we are migrating the primary TestFlight database to new bare metal hardware.

This system maintenance should result in less than 20 minutes downtime.  The procedure is to lock the current database to prevent writes, swap the host records and DNS, and rejoice.

This beefier setup will also give us additional capacity to begin the next round of improvements that we are making to the overall system architecture and infrastructure.

Thanks,

TestFlight Crew

We are introducing production SDK rate limiting in an effort to address stability across TestFlight. Our goal is to give ourselves a little air cover while we work to improve overall scalability.

This will not have any impact on your application or your users. If your app starts to skyrocket on the charts, you can simply request a rate limit increase from the notification area.

When SDK traffic hits the TestFlight servers we detect if the traffic was from a production application or a beta application. In the event that your production traffic crosses a particular threshold TestFlight will stop processing the inbound data. The initial SDK always included this functionality, but up until now it was only used to remotely disable the SDK upon developer request.

The limits themselves are dynamic based on how you currently use the service.  An example, TestFlight Live users have higher limits than non TestFlight Live users. We tried our best to implement limits that would have the least impact on the current level of use.

This is one step we are taking to ensure TestFlight can continue to grow without having a negative effect on our users and your users. Again, our goal is to provide a little air cover since we are hard at work improving stability throughout the entire site. We appreciate your understanding and we look forward to lifting the rate limit soon. If you have any questions or concerns please let us know.

Thanks,

TestFlight Crew

We usually love Mondays, but today was an exception. We apologize for the downtime. It was unexpected. There was maintenance scheduled for today at 12 AM PST. This should have resulted in minimal service interruption. Unfortunately it turned into a 6 hour recovery of our primary database.  

In short, pacemaker sigkilled MySQL caused massive corruptions (fortunately no data loss). Due to the extended length of downtime the SDK message queues backed up to the point where we OOMd (resulting in SDK data loss). The team worked through the night to correct the issues. It’s become our priority to move towards architecture and infrastructure changes that will prevent this from happening again.

We have been heads down trying to improve the service but need to make sure we communicate with you asap when something goes wrong. We should have done a better job with this today as well.  

Thank you for continuing to help TestFlight grow.  We can’t apologize enough for the issues of late, we are working as fast as we can to resolve them.

Today TestFlight will be switching everyone over to our new UI. A lot of elbow grease went into the new polish, while keeping the great features you expect from us. We’re investing more resources into these tools so it will grow to meet everyone’s needs.

Some of you may have already experienced the new UI as you ventured over to account settings and flipped on the v2 switch in Area51. Kudos to everyone’s curiosity and excellent feedback!

For those of you who haven’t seen the new UI, you’ll see a few notable changes:

  • Build options can be accessed by selecting the build of your choice from the build table
  • Build history can be accessed by clicking on the More button for apps with multiple builds
  • Once in build context, find your way back with a helpful breadcrumb to give you context as you navigate between apps
  • Managing your teams and testers got an overhaul with user details now launching into a modal window. Manage your users, distribution lists, and invites just as you did before






We’re excited about these improvements and hope you find them valuable.
Thanks again for all your support and great feedback. Please continue to share that with us. Enjoy your next flight.

- the TestFlight crew

By now you’re probably aware that Apple has started to reject applications that access the UDID. The only reason that the TestFlight SDK accesses the UDID is to provide the best possible information about your testers. When we made the decision to provide a single SDK for beta testing and production applications we did so because we want your beta and release builds to have as close to the same code base as possible. Now that the UDID is no longer allowed in production applications we will still continue to use a single SDK for both Beta testing and Live releases.

In order to accomplish the goal of a single SDK for all release types we have introduced a new method into the SDK, +setDeviceIdentifier:(NSString)deviceIdentifier. This method is always optional and never needs to be set. However, we feel that during beta testing most of you would like to see which members of your team have seen and tested which parts of your applications. To enable that we allow you to use the +setDeviceIdentifier:(NSString)deviceIdentifier method to set the device unique identifier. We recommend that when you choose to set +setDeviceIdentifier:(NSString)deviceIdentifier to the current device’s unique identifier that you wrap the method in a preprocessor directive that only enables the call when you are building for ad-hoc release.

For further information and code samples please see our online documentation. If you decide that you do not wish to set +setDeviceIdentifier:(NSString)deviceIdentifier, we will still collect all of the usage statistics that you are used to seeing but the data may be anonymized.

Following our SDK release schedule we have released TestFlight SDK 1.0 BETA 1. As mentioned this new version of the SDK no longer accesses the device unique identifier and as such is App Store safe. Following our SDK release schedule we forsee that this version will be bumped up to full release status no later than March 30, 2012. When SDK 1.0 BETA becomes the official release we will begin deprecating all previous SDK releases.

As of May 31, 2012 we will no longer accept uploaded builds that contain an SDK version lower than 1.0. We will continue to accept data from previous versions of the SDK indefinitely.

Today TestFlight moves to its new home. The new home is a bare metal infrastructure which brings you a faster more scalable TestFlight. In a follow up post we will discuss some of the technical pieces and the decisions made, for now we just wanted to tell you guys that we are moving, and why.

Ghost Hunting

Cloud hosting has some fantastic benefits, we were specifically attached to the cost and the speed at which we could bring up new instances. What we were not attached to was the inconsistent performance and lack of predictability.

Tracking down bottlenecks in the infrastructure felt like hunting ghosts. There were times were the system locked up hard and the only explanation we walked away with was resource contention. We already consumed the majority of the shared resources available so there was nowhere to go but down.

Hello Anchor

While trying to figure out an ideal load balancing situation for TestFlight I stumbled on this article http://www.anchor.com.au/blog/2009/10/load-balancing-at-github-why-ldirectord/.  Turns out the Anchor team helped scale GitHub. After a few conversations with Anchor, it was clear their team was phenomenal fit for TestFlight.

We would love to take credit for everything involved with this migration but the reality is that Anchor brought a wealth of experience to the table. They took our stack, analyzed it and came up with a plan of attack which involved some fantastic technologies only well-bearded individuals should touch.

The New Infrastructure

Once things have settled down we will post a follow up with some more technical details. This new infrastructure will not only help us scale as we grow, but it should provide immediate performance improvements. We hope that everyone is as excited as we are.

The TestFlight crew is growing! If you are interested in working with us, please apply!

A Real-time Dashboard for Actions and Revenue

B + TF = TF Live

We are excited to announce that TestFlight was acquired by Burstly, and we are jointly launching TestFlight Live today! TestFlight Live is a real-time dashboard that highlights actions and revenue for iOS apps. The TestFlight Live feature set is broken down into four segments: engagement, audience, revenue, and stability. The goal of the product is to provide a real-time display of the important factors happening in your app right now. It is available via Safari and Chrome on the desktop, and on the go on your iPad and iPhone.


For those of you unfamiliar with Burstly, they are a team that shares our vision of improving the ecosystem for developers. Burstly has been working to help some of the biggest apps in the industry including Words with Friends, Angry Birds, PaperToss, and Tetris. They know how to support partners at scale. They are also good friends who we are excited to work closer with. We are thrilled to be joining forces with their team, and feel this is the best place for us to continue building the tools that developers love.

TestFlight has experienced phenomenal growth since we launched last year.  We now have over 70,000 developers sharing more than 130,000 apps with a group of 280,000 testers! While the widespread adoption of our product has been humbling, we know we need to continue investing in features and performance to meet the needs of our expanding client base. This is where the investment dollars and scaling guidance from Burstly will be invaluable. With performance and support issues, and tremendous customer feedback, we are aware of what we need to improve upon. We are committed to tackling these issues to enhance the TestFlight experience and the additional resources provided by this acquisition are vital to that effort’s success.  We are about to roll out major updates with the help of some new resources provided by Burstly in addition to the great work by our team.

Coming to TestFlight in March:

  • Better performance - we are putting the finishing touches on an infrastructure overhaul that includes moving to managed dedicated hosting led by Anchor Systems (http://www.anchor.com.au/blog/2009/09/github-designing-success/)
  • New UI for both desktop and mobile - completely revamped with improved workflows and more flexibility so we can continue to expand the product
  • Desktop app + expanded API - screaming fast uploads, local IPA validations, and the most important bits of TestFlight on your desktop. The side effect of a rich desktop app is a rich API. We are excited to see what you will create with an expanded API
  • Faster customer response times and an improved knowledgebase – we have grown our support team to make the TestFlight experience more enjoyable
  • We’re hiring! If you’re excited to create amazing products that solve problems in all of the areas of the mobile app lifecycle, please let us know

TestFlight and Burstly will continue to be independent products. TestFlight remains a free service and optional paid features will be introduced in the future. TestFlight will continue to build the best developer tools and will include Burstly features only to improve product functionality (as in the case of adding revenue to TestFlight Live), and vice versa for Burstly products.

If you are not completely familiar with Burstly’s business, you are not alone since we did not fully grasp it when we first met back in April, 2009. Burstly offers developer’s tools to help better monetize their apps. The toolset allows mobile developers to run any type of content or messaging to its users, track in-app purchases from buttons or banners, cross-promote other apps, and to work with a wide variety of 3rd party ad partners to improve revenue.  Burstly’s mission is to empower developers by providing data and visibility into their business, along with a toolset to act on that data. This is very similar to how our mission at TestFlight. We provide developers with the tools they need to be in control of their beta testing experience. With the launch of TestFlight Live we are starting to help with their business after their app has launched as well. 

Mobile App Lifecycle

Both companies solve complex problems within the app lifecycle. TestFlight handles the beginning with beta testing tools, while Burstly manages the final stages with monetization options. Together, we are working to solve everything in between. A good first step in this direction is TestFlight Live. 

TestFlight Live

We have been planning on launching a production version of TestFlight for some time, but we wanted to push ourselves to start solving production problems and not simply copy the beta feature set. Along with help from the Burstly team, we think we have taken a great first step with TestFlight Live. Our goal with TestFlight Live is to provide a real-time dashboard that displays real-time usage statistics, actions, symbolicated crash reports, and revenue. For the first time, developers will have a single dashboard that provides enough information to derive insights into Revenue Per User (RPU) and Customer Lifetime Value (CLV) to better understand your app business. Previously, this level of information would be from multiple sources and there was no easy way to collect it.

Burstly was the key contributor to the revenue portion of TestFlight Live, as they developed the APIs that make it possible. The revenue source options in TestFlight Live enable developers to include app sales data, in-app purchase data, and ad network revenue from multiple partners. You do not need to work with Burstly to pull in any of this data. If you do not want the revenue segment in your dashboard, we have provided a way for you to hide it.

Learn more about the features of TestFlight Live.

History

Almost three years ago, it took a well-connected Portland iPhone maven, Raven Zachary, to introduce two mobile guys who could not find each other in LA. Thank you @ravenme! Through this introduction we became one of Burstly’s first customers when we agreed to be their guinea pig with our app, Gigotron. They even put us in their launch video as their first customer (jump to 1:40). We were actually debating building something similar at the time to enable local bands to promote their shows, but it was clear Burstly’s toolset and thinking was a few steps ahead of ours when it came to promotion/monetization. Ever since then, our teams have been working together.

We are looking forward to waking up everyday to work with our friends and build better products than we are able to build alone.

Privacy

While we are thrilled to join forces with Burstly, we won’t be surprised if not all of our customers are equally enthusiastic. After internal discussions, we felt like the two biggest reasons for a negative reaction would be: (1) TestFlight would change for the worse and (2) privacy concerns and trust with your data. Since we hope it is already clear by this point that TestFlight is only getting better, we want to address the trust issue.  TestFlight handles top secret developer projects, Burstly handles top secret financial data for some of the largest apps in the world. Both companies are responsible for safeguarding their customers’ precious data  and can be successful only by maintaining the highest standards in this regard.

We are committed to improving and growing the TestFlight experience. If anything about our new partnership with Burstly causes you concern we hope you will visit TestFlight Live and see this effort as a first step towards building better tools for all developers.

We have strong convictions in our future roadmap and the benefits to our community of trusted TestFlight developers. We hope you will give us enough time to execute so the products and our actions speak louder than anything we could possibly write in this post. If, for any reason, you don’t want to continue using our toolset due to our new relationship you can use the “remove account” button under “account settings” and erase all of your data and delete your account.

Ready to get started with TestFlight Live? Simply insert one line of code into your production app or leave the SDK you have been using for beta testing. We could not be any more excited about the opportunity to solve developer’s problems and help drive the app ecosystem forward.

TestFlight SDK 0.8 is live!

The TestFlight team has been hard at work trying to bring you an updated SDK. We’re happy to say it’s arrived! Here are a few of the highlights.

Signal Safe Crash Reporting

The main focus of the 0.8 update to the SDK was our crash reporting mechanisms. Our uncaught exception and signal handling has gone through extensive improvements since the 0.7 release. Part of this effort was removing any Objective-C and non-signal safe code from the crash reporting functionality of our SDK. Our users have also helped us identify that we were missing the SIGTRAP signal in our signal handler which has been added. The other changes involve using a signal safe implementation of MessagePack that allows us to save all of your data safely to files as we gather the crash report. This means that if, for any reason during the signal or exception, there is an interruption the data that we have gathered thus far is safe and will be transmitted on the next launch of the application.

Realtime Crash Reports

We feel that having crash reports being reported as they occur is extremely important. In order to maintain this it requires that we run some potentially less signal safe code in our crash reporting mechanisms. Initially we were using the same asynchronous networking code that we use in the main part of the library. This is Objective-C based and we feel that it is an extremely effective networking solution and we will continue to use it in the main portion of our SDK. However, it has the potential to allow the rest of the application to continue running during a signal which could lead to corruption of data. We now use an entirely C-based approach to networking while sending crash reports. If, for any reason, we are unable to send the report we will send it the next time that the application is launched with an active connection to the network.

Stack Trace Improvements

In some circumstances we noticed that the stack trace for exceptions was incorrect. This was caused by obtaining the stack trace from inside the NSUncaughtExceptionHandler. This method, which used to work correctly, no longer works as of iOS 5. We now use the call stack provided by NSException which, during our testing, accurately reports the call stack from iOS 3 to iOS 5.

iOS 3 Support

One issue a few people have pointed out was that we did not handle iOS 3 very well. We are happy to say that we have resolved any issues with and now support our full feature set with iOS 3. While this does not affect all of our users, it is important to us to provide you with the tools to fully test your products across all devices and OS versions.

Remote NSLogs

We have tried hard to maintain our current feature set while implementing our improved crash reporting, but there were a couple of features that did not make the cut for version 0.8. The first of which is capturing NSLogs during a crash. We currently get your NSLogs from the Apple System Log, which is very slow and not signal safe. We are aware that capturing NSLogs are especially important during a crash and we will be bringing back a way to obtain the log during a crash. The other feature we have removed during this process is crash logs from the iOS Simulator. We feel that, while the Simulator is a useful tool, it is used with Xcode most of the time and it is less useful to record the exceptions from the Simulator inside of TestFlight.

Future Improvements:

  • A new logging system. We no longer feel that NSLogs are the best way to record logging information going forward. They have been useful in showing us that our users really like the ability to have their logging statements sent to them remotely. We are working to provide a way to do this without any negative impact to your application.
  • Low memory exit recording. We currently do not report anything when a low memory exit occurs. This type of exit is just as important to our users as crash reporting and we will be addressing this in upcoming versions.

You can grab the updated TestFlight SDK at https://testflightapp.com/sdk/