Using Parse to Power Up Your Framer Prototypes (Part I)

Morpheus

At Parse, prototyping plays a crucial part of how we craft our products. Read on for a great tutorial to make your prototypes as realistic as possible with the help of Framer. Brought to you by our resident design expert, George Kedenburg III, and originally posted here on Medium.

Have you ever wished your prototypes could be just a bit more realistic? Are you tired of prototypes resetting back to their initial state when you close them? Maybe you just want an easier way to integrate real data without dealing with obnoxious blobs of JSON.

In this series of tutorials, I’m going to be exploring some interesting use cases for integrating Parse with Framer. Hopefully they’ll help you think of new ways to use data to enhance your own prototypes with the awesome power of a real mobile backend.

In this first guide, we’re just going to go through some basic things you can do with Parse. We’ll set you up with an account, create your first app, set up a class full of data, and then pull that in to the prototype. We’ll also link up a simple “like” interaction that will save data back to Parse.

Our app concept is simple: we just want to display a list of locations (that have their own background images) and store a total like count per location.

Play with the completed prototype


What is Parse?

Let’s take a step back. Parse is a cloud platform that lets app developers quickly and easily integrate a lot of complicated, scalable server-side functionality into their products.

Parse has three main products:

CoreStore data and run code on a remote server.

PushSend push notifications to your users via an API or the web composer.

AnalyticsTrack events in your app and gain valuable insights.

It’s important to note that Parse is built for real, production-level apps — so it has a lot of power under the hood. Thankfully, it also has a simple and easy-to-use API and a JavaScript SDK, so it’s the perfect addition to Framer prototypes. With Parse + Framer, you’ll be able to do almost anything: read and save data, create users and let them log in, remember app states, track events, and so much more.

Seriously, look at the documentation — you can do pretty much anything.


Let’s get started

 Screen Shot 2014-12-16 at 9.32.38 AM

Get an account

In order to use Parse, you’ll need an account. Head over to parse.com and click the “Sign up” button in the top right. Create your account with an email and password, and name your first app (“Framer Prototype” is a good choice, but feel free to name it whatever you like). If you’re just doing simple data storage, you can use the same app for as many prototypes as you want. If you end up using more of what Parse has to offer, you may want to create a new app for each prototype.

Screen Shot 2014-12-15 at 3.18.58 PM

Grab your keys

From your Parse dashboard, hover over the gear icon and click keys. We’ll only be using the Application ID and the JavaScript Key so feel free to copy them somewhere easy to get to (like an empty text file) or just leave this page open in another tab. Keys are unique strings of characters that act as your password when communicating with Parse. It tells Parse what app you’re trying to connect to, and proves that you are allowed to make that connection.

Plan your data

We’ll need some data to pull in to our prototype. Looking at the designs, we’ll probably need a city, a state, a like count, and an image URL. It also might be nice to have a way to toggle certain locations on and off. It’s important to think through this as best as you can before you start prototyping to prevent any messy data issues.

There are a few different special types of data that you can store in Parse. It’s important to make sure you choose the right one for each field. Here are the most common data types you might use in prototyping:

String:
Any kind of text. Whatever you put here is exactly what you’ll get back. We’ll use this type for the city, state and image URL.

Number:
This type is specific for numbers. Using this allows you to do math operations with out any kind of type conversion. We’ll use this type to track the like count in our prototype.

Boolean:
This can be either true or false. It’s helpful for toggles and states. We’ll use this to determine if a location is shown or hidden.

Create your class

In Parse, a set of data is called a class. This is very similar to a sheet in your favorite spreadsheet app. From your dashboard, hover over the app and click on “Core” at the bottom. This will take you to the Parse data browser.

Here, we’re going to create a new class called “Locations” and add columns for the different types of data that we planned for. Once you’ve created the class, click the “+ Col” button to add a new column (remember to use the right types that we defined in the previous step). Once you’ve made all the right columns, go ahead and add some rows of data. Here’s a screenshot of the complete class I made for this example:

Note: Column names are case-sensitive, so be sure you are consistent. I prefer to use camel case (i.e. likeCount vs LikeCount) and that is how the code in this guide is written.

You can see the data is pretty straight forward. If you’ve ever used any kind of spreadsheet application, this will feel very familiar. The only columns you really need to worry about with prototypes are the ones you’ve created. You can safely ignore all the Parse columns (like objectId, createdAt, etc.).

For the images, all I’ve done is dropped in a direct link to some photos from Instagram. If you want to use your own images, you can use something likeImgur or even just a public Dropbox folder. I’ve also preset a couple like counts, but you could leave these as all zeroes too.

(this is where the magic happens)

Integrate with Framer

If you’re in a rush and want to save some time you can download this blank Parse + Framer template that has the Parse SDK pre-installed and skip to the next step.

Now that we’ve got a class and some data, we can finally start our Framer integration! Luckily, this part is super easy. Start a new Framer Studio project and paste in this code:

# Initialize Parse with the app keys corresponding to your app
Parse.initialize("APPLICATION ID", "JAVASCRIPT KEY");

# Write your Framer Code below this
success = new BackgroundLayer backgroundColor: 'green'

Now you’re probably getting an error in Framer Studio, which is OK. This is because Framer doesn’t know what Parse is yet. We have to add the Parse JavaScript SDK to the index file for your Framer project.   Save your project and close it. Open up Finder, navigate to where your project is, and click on it. You should see something like this:       Open up the “index.html” file in your favorite code editor (I preferBrackets) and add this line as the first script in the script block:

<script src=”https://www.parsecdn.com/js/parse-1.3.2.min.js"></script>

Your index file should look like this now:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		
		<meta name="format-detection" content="telephone=no">
		<meta name="apple-mobile-web-app-capable" content="yes">
		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
		<meta name="viewport" content="width=device-width, height=device-height, initial-scale=0.5, maximum-scale=0.5, user-scalable=no">

		<link rel="apple-touch-icon" href="framer/images/icon-120.png">
		<link rel="apple-touch-icon" href="framer/images/icon-76.png" sizes="76x76">
		<link rel="apple-touch-icon" href="framer/images/icon-120.png" sizes="120x120">
		<link rel="apple-touch-icon" href="framer/images/icon-152.png" sizes="152x152">

		<link rel="stylesheet" type="text/css" href="framer/style.css">

		<script src="https://www.parsecdn.com/js/parse-1.3.2.min.js"></script>
		<script src="framer/coffee-script.js"></script>
		<script src="framer/framer.js"></script>
		<script src="framer/framer.generated.js"></script>
		<script src="framer/init.js"></script>

	</head>
	<body>
	</body>
</html>

Once you’ve added the line, save the file and close it. Now re-open your project in Framer Studio, and your device should have a green screen. Congrats, you’ve successfully initialized your Parse app!

Write a query

Everything in Parse that relates to reading data is centered around the query. Luckily, queries are pretty easy to write and it’s a piece of cake to sift through the data you get back. Let’s get our list of locations from the class we made earlier:

# Initialize Parse with the app keys corresponding to your app
Parse.initialize("APPLICATION ID", "JAVASCRIPT KEY");

# create an object that extends the class you want to pull data from
Locations = Parse.Object.extend("Locations")

# create a query against the object you just created
queryLocations = new Parse.Query(Locations)

# we're looking for rows that have show set to true
queryLocations.equalTo "show", true

# we're going to sort the response by state and then by city
queryLocations.ascending "state", "city"

# now we actually run the query and get back results
queryLocations.find
	success: (results) ->
		# if the query is a success, we'll get back a results object. 
		# this for loop lets us do something to each result in that larger "results" object
		for result, i in results
			location = new Layer width: 750, height: 300, y: 300 * i
			location.html = result.attributes.city + ", " + result.attributes.state
			location.image = result.attributes.image
			location.name = result.id
			# ^^^ super important! the result.id is the ID that Parse 
			# uses to find that entry. we need to associate it with this 
			# layer if we ever want to interact with this data in the future
	error: (error) ->
		# if there was an error, we'd print it
		print error

You can see on lines 23–25 how we access data thats returned from Parse. We get a big “results” object back that we then loop through and act on each “result.” Each column in your class is exposed as an attribute of a result, so for example if you had a column called “cuteKittens” you would get to it by looking at result.attributes.cuteKittens.

If you’ve followed along correctly so far, you should end up with something like this.

Obviously we have a lot of styling and overall prettifying work to do, but hey you just pulled some dynamic data in to your prototype!

High five!

Write some data back

Now that we’re able to read data in, we might want to save something back to our database. For this example, we’re going to create a like function that increments the like count in our app and save it back to Parse.

# Initialize Parse with the app keys corresponding to your app
Parse.initialize("APPLICATION ID", "JAVASCRIPT KEY");

# create an object that extends the class you want to pull data from
Locations = Parse.Object.extend("Locations")

# create a query against the object you just created
queryLocations = new Parse.Query(Locations)

# we're looking for rows that have show set to true
queryLocations.equalTo "show", true

# we're going to sort the response by state and then by city
queryLocations.ascending "state", "city"

# now we actually run the query and get back results
queryLocations.find
	success: (results) ->
		# if the query is a success, we'll get back a results object. 
		# this for loop lets us do something to each result in that larger "results" object
		for result, i in results
			location = new Layer width: 750, height: 300, y: 300 * i
			location.html = result.attributes.city + ", " + result.attributes.state
			location.image = result.attributes.image
			location.name = result.id
			# ^^^ super important! the result.id is the ID that Parse 
			# uses to find that entry. we need to associate it with this 
			# layer if we ever want to interact with this data in the future
			
			location.on Events.Click, ->
				# same as when we initially pulled the location list, 
				# we need to retrieve the item we want to increment from Parse 
				# so we will need to query our Locations class
				likeGet = new Parse.Query(Locations)
				
				# the @ symbol is coffeescript's equivalent of "this"
				# so here we're telling our new Parse.Query to fetch the
				# row that corresponds with the ID we set back up on line 25
				likeGet.get @.name,
					# if our call is successful, we'll get back a single row which I've named 'location'
					success: (location) ->
						# since likes is the number type we can
						# use this handy Parse helper called increment 
						# which will take the specific column 'likes' of 
						# our 'location' and increment it by 1
						location.increment('likes')
						
						# and now all we have to do is call 
						# save() on our location and the new like count is stored
						location.save()
			
	error: (error) ->
		# if there was an error, we'd print it
		print error

Now nothing will happen visually in our app because we’re not actually displaying the likes anywhere yet, but if you refresh your Parse data browser you’ll see the like counts going up by one every time you click a location. You’re now reading and writing to a cloud database, all from inside your own Framer prototype!

Keep going

By now, you should have a semi-functional prototype and basic mental idea of how Parse works. I’ve completely built out this example prototype below, so download it and take a look at how it works. Also, there is a ton of documentation on Parse that can teach you how to take this example even further. Take what you’ve experimented with here and use that knowledge to enhance your own prototypes!


Explore the finished project

Check it out in Framer Studio or download the source.

Thanks for reading! Please give me a shout on Twitter if you have any questions or if you have ideas for future guides you’d like to see.

George Kedenburg III
December 18, 2014

Vevo Takes On the Mobile Stage with Parse Push

Vevo

With countless players entering the music technology space each day, one has remained the absolute leader in bringing musical experiences to life: Vevo.  Serving up millions of views in video music content in countries across continents each day, Vevo offers the largest collection of premium official music videos possible.

Vevo’s online and mobile channels serve as key content sources for artists worldwide, and especially serve major record labels including Universal Music Group and Sony Music Entertainment.  With the Vevo app, it is easier than ever to discover premium official music videos.  Users can stream live music performances and original shows, in addition to exploring Vevo TV’s hand-curated music video channels.  For an enhanced listening experience, the Vevo app is even able to provide recommendations via a user’s iTunes music library–a phenomenally personal tool consistently focused on bringing the musical world to life.

Given its vast user base in countries like Australia, the U.S., Poland, Brazil, and beyond, Vevo looked for ways to maintain high levels of engagement without sacrificing any piece of their app experience or functionality.  For this, Vevo turned to Parse Push, the perfect solution for the widely popular, cross-platform nature of the Vevo app.  Found on Android, iOS, Window 8, Roku, XBOX 360 devices, and more, Vevo required a service that could handle sending push notifications to many different audiences and across different platform mediums.  According to Argam DerHartunian, VP of Product,

Parse is good for pushing notifications to users and specifically getting data on those we are engaging with.

With the seamless connection between Parse Push and Parse Analytics, Vevo is able to develop a comprehensive understanding of what kinds of push messaging resonates with their app users, and thus encouraging improvement for their engagement and retention.

Vevo continues to grow its offerings in new countries and with more artists each day.  Download the app in the Google Play Store, Apple App Store, or Windows Store.

Nancy Xiao
December 12, 2014

Parse Local Datastore for iOS

Local Datastore for iOS

Too often, we’ve seen bad reception or lack of connectivity become the downfall of what could have been an incredible user experience. Many mobile apps are simple clients that display data straight from a server, losing all functionality without an internet connection. Because of this, people who use these apps face painful loading screens and broken features. The developers who build these apps want a better experience, but it’s not easy to build all the underlying logic to handle local data storage gracefully.

Parse Local Datastore makes it a lot easier, and today we’re excited to announce that it’s available in our iOS/OS X SDK. You can now create a seamless, uninterrupted user experience free from connectivity constraints.

It’s the same functionality found in our Android implementation, but now for iPhones , iPads, and Macs everywhere. [PFObject pin] persists PFObjects to the Local Datastore and [PFObject unpin] removes them. Once pinned, you can access them anytime with a normal PFQuery:

PFQuery *query = [PFQuery queryWithClassName:@"Feed"];

// Pin PFQuery results
NSArray *objects = [query findObjects]; // Online PFQuery results
[PFObject pinAllObjectsInBackground:objects];

...

// Query the Local Datastore
[query fromLocalDatastore];
[query whereKey:@"starred" equalTo:@YES];
[[query findInBackground] continueWithBlock:^id(BFTask *task) {
// Update the UI
}]];

Pinned PFObjects will remain accessible while offline — through app exits and restarts — until they are unpinned. Subsequent saves, updates, or deletes will keep your Parse Local Datastore results up-to-date.

You can also choose to update your object using the PFObject method saveEventually. This will first update its instance in the Local Datastore and then do so remotely, so any changes can be kept up-to-date while offline:

feedItem.starred = YES;

// No network connectivity
[feedItem saveEventually];

...

PFQuery *query = [PFQuery queryWithClassName:@"Feed"];
[query fromLocalDatastore];
[query whereKey:@"starred" equalTo:@YES];
[[query findInBackground] continueWithBlock:^id(BFTask *task) {
// "feedItem" PFObject will be returned in the list of results
}]

This also means that if you’re already using the PFObject method saveEventually to protect your app against network failures, you’ll get most of this without any additional work–simply by updating to the latest iOS/OSX SDK and enabling Local Datastore.

With Parse, it’s easy to take your app offline! Check out our guide and API docs to get started now.

Grantland Chew
December 9, 2014

Introducing Parse Crash Reporting

Crash Reporting

We at the Parse London office are happy to announce Parse Crash Reporting: the simplest way to register, track, and resolve crashes in your apps. Being able to capture and fix crashes efficiently means fewer frustrated users and better retention–one of the most important metrics to any developer.

In the past, we’ve seen Parse developers use third-party crash reporting tools, but this approach required developers to manage several different SDKs, learn new APIs, and monitor many dashboards at once. We wanted it to be simpler. Part of Parse’s core mission has always been to abstract away common tasks and streamline the developer’s experience — so we built a way to manage crash reports right within Parse.

Crash Reporting

Say you’ve released a new version of your app that unfortunately “features” a newly introduced bug. Have no fear! All you have to do is enable Parse Crash Reporting, making the experience of handling crashes in your app much smoother than ever before. We’ve updated our iOS and Android SDKs to provide a simple and intuitive interface that detects the bug, pinpoints the issue, and generates a report allowing you to resolve problems quickly and easily. With this update, our SDKs automatically cache and resend your crash reports if connectivity is spotty. And, our backend tracks bugs on a per-version basis, so that if you’ve reintroduced an old bug in a new version of your app, Crash Reporting still ensures you’ll notice and fix it as soon as possible—even if you’ve previously marked it as “resolved.”

Here’s an example snippet showing how you can enable Parse Crash Reporting for Android:

ParseCrashReporting.enable(context);

Here’s an example snippet showing how you can enable Parse Crash Reporting for iOS:

[ParseCrashReporting enable];

As you may have expected, the sending of crash reports from the client is asynchronous and takes place automatically in the background.

We’re always looking to improve our products and would love to hear your feedback. Check out our guides, try it out, and let us know what you think!

Islam Ismailov
December 9, 2014

Migrating from Urban Airship

Making mobile development as easy as possible has always been our mission at Parse. And ensuring your data is portable and remains yours is an important part of that mission. We’ve worked hard on improving the accessibility of your data on Parse and are committed to ensuring our customers can access their data at any time.

In that spirit, we also want to make sure new customers are able to easily migrate from other providers to Parse. We noticed that the push notification provider Urban Airship recently made their product paid only. So, a few of our engineers spent a weekend building a very simple migration tool. This tool will import all of your Urban Airship push subscriptions for iOS and Android (GCM) devices to Parse. Simply enter your Urban Airship app key and secret and we’ll take care of the rest!

Parse Push allows developers to send unlimited push notifications to up to 1 million devices for free every single month. Beyond that, the pricing is simple: you’ll pay $0.05 a month for every 1000 extra devices. That’s $50 for another million devices, and you can send them as many pushes as you want.

image

After the import is complete, check out the Data Browser to see all of your data. You can then immediately start sending pushes to existing devices without requiring an update to your app. Until you require an update, you can continue using the migration tool to import any new devices. Don’t worry, we’re keeping track of which ones you’ve already imported, so there won’t be any duplicates. Once you’ve integrated the Parse SDK and updated your app, new devices will start showing up in Parse. You can then start taking advantage of our powerful analytics features. To learn more about the steps of migrating to Parse, take a look at our tutorial that will guide you through the whole process.

We’re excited for you to experience all that Parse has to offer. With Parse Push, you can now enjoy device targeting, in-depth analytics, and timezone and badge increment support for your push messaging. Plus, don’t miss our brand new A/B testing feature — engage with your users more intimately and effectively than ever before.

If there’s any other importer you’d like to see, let us know!

Mattieu Gamache-Asselin
December 8, 2014

Parsing All Over the Globe

View this post in:  中文(简体)   |  中文(台灣)   |    한국어    |    日本語    |    Русский

Parsing All Over the Globe

My cofounders and I started Parse in 2011 to solve our own problems. We were frustrated with all the repetitive work needed to build great cross platform mobile apps. Our first customers were our friends who also built apps and they mostly lived near us in San Francisco. Over time, we started attracting more customers that weren’t just our friends — first in Silicon Valley and soon throughout North America. Today, over 500,000 apps have been created on Parse, and hundreds of thousands of our developers hail from outside of the United States. Our team is incredibly honored that so many developers across the globe have trusted Parse with their businesses and apps. Here are some cool stats about our global presence:

  • Active apps in Asia grew nearly 90% in the first half of 2014.
  • Apps in APAC that use all three Parse products—Parse Core, Parse Push, and Parse Analytics—grew by more than 90% in the first half of 2014.
  • 6 of Parse’s 15 largest countries (by number of active apps) are in Asia: India, Japan, Australia, China, Taiwan, Korea.

We are extremely excited about how much our community has grown since 2011. As that growth continues to accelerate, today I’m pleased to share the efforts we have made to make Parse even more friendly to our international community:

  • Localizing our content — We have localized our technical documentation and customer success stories into Chinese ( Simplified & Traditional ), Japanese, Korean and Russian.
  • Creating a truly global team — When we joined Facebook, our entire team moved from San Francisco to Menlo Park in California. Since then, we’ve expanded our horizons quite a bit. We’re now a global team with dedicated folks in London, Dublin, Paris, and Singapore. And we’re excited to continue expanding wherever mobile developers need help!

We hope you’re as excited as we are about these announcements and we appreciate you being part of our global community.

– Ilya Sukhar, Parse Founder and CEO

Ilya Sukhar
December 1, 2014

Learn How to Build Fast and Ship with Parse

Parse is excited to be a part of the mobile development Deep Dive course from Brooklyn’s HappyFunCorp this March. Find out how Parse can be a great learning tool in this guest post from HappyFunCorp co-founder Ben Schippers:

At HappyFunCorp, I often get asked the question, “Should I use Parse to build my startup?”

This question generally leads to a much larger discussion about the best ways to build startups and to manage the inevitability of the unknown post-launch. In today’s development climate, bandwidth is cheap, and developers can find massive reservoirs of free information on best practices. Thus, building for mobile and web has become much more accessible—which means user acquisition and distribution has become the new game.

For entrepreneurs starting mobile or web businesses today, it’s critical to build the smallest, most focused subset of features to prove to the market that the idea has viability. It is equally critical to push forward, pivot, or move on to the next idea when necessary. Data is king in making these decisions, so shipping the product as quickly as possible should be the goal when getting started. It’s crucial to use tools that enable you to maneuver quickly, especially during the infancy of the business.

That’s why, when I’m asked “Should I use Parse to build my startup?” I say yes. Parse takes much of the complex web services layer out of the scenario. This allows you to focus on the actual mobile experience. User authentication, push notifications, and storage, just to name a few, are taken care of for you right out of the box. Just as many startups use Heroku to manage dev-ops, Parse takes care of the communications link between your phone and the server. It enables you to focus on the client experience, and perhaps just as importantly, the distribution, while Parse manages much of the heavy web services layer for you. This is perfect for our students at HappyFunCorp, many of whom are just beginning to learn app development; with Parse, they’re up and running with a new app in just minutes.

In addition to Parse’s development offerings, entrepreneurs can take advantage of FbStart, a new program tailored directly to startups and larger companies looking to build amazing mobile application experiences. The beauty of this program is that Facebook and Parse help solve the distribution problem for you by offering application level deep linking, custom analytics, and a whole suite of tools dedicated to user acquisition and distribution. So you can build fast and ship, collect data and iterate, quickly and easily.

Have an idea and want to talk shop? Drop by our Brooklyn offices or sign up for our Parse mobile class.

HappyFunCorp is an engineering firm dedicated to building the very best mobile and web experiences.

Nancy Xiao
November 24, 2014

Parse Push Experiments: A/B Testing Best Practices and the Screencast

We recently launched Push Experiments, which lets you conduct A/B tests on push notification campaigns to identify the most engaging message variant. With Push Experiments, we wanted to make it easy to run successful A/B tests. In this post, we’ll discuss some of the statistical techniques we’re using behind the scenes. And, catch a screencast showing you the ins and outs of the new tool below.

Parse Push Experiments in Action

Ready to try Parse Push Experiments?  Watch the screencast here.  Or, read on for A/B Testing best practices.

 

What makes an A/B test successful?

We can say that an A/B test succeeds whenever we get a precise, correct answer to the question that originally motivated us to run the test. In other words, a good platform for A/B testing should try to prevent two kinds of failure:

(1): We should rarely get a result that leaves the answer to our question in doubt.
(2): We should rarely get an answer that seems precise, but is actually incorrect.

Parse Push Experiments uses three strategies to prevent these two kinds of failure:

  1. Encourage developers to ask precise questions that can be answered unambiguously.
  2. Prevent developers from reaching wrong conclusions by always reporting results along with a margin of error.
  3. Ensure that most A/B tests will give a precise answer by suggesting the minimum number of users that must be included in an A/B test in order to reasonably expect accurate results.

Step 1: Asking Precise Questions

Here’s one of the most important things you can do while running A/B tests: Commit to the metric you’re testing before gathering any data. Instead of asking questions like, “Is A better than B?”, the Push Experiments platform encourages you to ask a much more precise question: “Does A have a higher open rate than B?”

The distinction between these two questions may seem trivial, but asking the more precise question prevents a common pitfall that can occur in A/B testing. If you allow yourself to choose metrics post hoc, it’s almost always possible to find a metric that makes A look better than B. By committing up front to using open rates as the definitive metric of success, you can rest assured that Push Experiments will produce precise answers.

Step 2: Acknowledging Margins of Error

Once you’ve chosen the question you’d like to answer, you can start gathering data. But the data you get might not be entirely representative of the range of results you’d get if you repeated the same test multiple times. For example, you might find that A seems to be better than B in 25% of your tests, but that B seems to be better than A in the other 75%.

As such, when reporting the difference between the A and B groups (we’ll call this difference the lift), it’s important to emphasize the potential for variability in future results by supplementing the raw result with a margin of error. If you have an A/B test that has a lift of +1% and a margin of error that is between -1% and +3%, you should report that your A/B test’s results were inconclusive. If you simply reported a +1% change, your results would be misleading and might set up unrealistic expectations about the success of your push strategy in the future. By reporting a range of values that should contain the true answer to your question (this range is what a statistician would call a 95% confidence interval), you can help to ensure that anyone reading a report about your A/B test will not reach premature conclusions.

At Parse, we determine margins of error for open rate data using a calculation called the Agresti-Caffo method. When you’re working with push notification open rates, the Agresti-Caffo method produces much more reliable margins of error than naive methods like normal approximations.

In addition to automatically calculating margins of error using the Agresti-Caffo method, the Push Experiments platform only reports results after it’s become clear that either A offers a lift over B or that B offers a lift over A — helping to further protect you from reaching premature conclusions. Until there’s enough data to determine a clear winner, the Push Experiments dashboard will report that there’s still uncertainty on whether A or B is more successful.

Step 3: Choosing the Right Sample Size

Given that the Push Experiments platform will always report results with a margin of error, you’ll want to try to make that margin smaller in order to draw definite conclusions from more of your tests. For example, if you think that your A group will show a lift of 1% over your B group, you’ll want to make sure you gather enough data to ensure your margin of error will be smaller than 1%.

The process of picking a sample size that ensures that your margin of error will be small enough to justify a definite conclusion is called power analysis. The Push Experiments platform automatically performs a power analysis for your A/B test based on the historical open rates for your previous push notifications. To simplify the process, we provide suggested sample sizes based on the assumption that you’ll be trying to measure lifts at least as large as 1% with your A/B tests.

Only running A/B tests with carefully chosen sample sizes makes it much more likely that your A/B tests will succeed. If you select a sample size that’s much smaller than the size we suggest, you should expect that many of your A/B tests will lead to inconclusive results.

Putting It All Together

We believe the combination of precise questions, clean statistics and careful choice of sample size is essential for running a successful A/B test. You can achieve that with Parse Push Experiments, and we hope this look into the statistical methods behind our platform will help you do it.

 

johnmyleswhite
November 20, 2014

Attack of the Clones

A long time ago, developers had to painstakingly create multiple versions of their Parse apps in order to manage development and production environments; but no more! After long hours of research, we’ve cracked the app genome and we’re happy to announce the brand new ability to clone apps.

From the newly redesigned Parse dashboard, you’ll now be able to quickly clone an app that you’ve made or that has been shared with you by a colleague. This will clone the schema, cloud code, security and white-labeling settings, and config parameters; everything about the app except the data and the background jobs schedules. (We know cloning data is a highly requested capability, and we’re exploring ways to do it in a limited fashion.)

clone-dashboard

If you want to customize what goes into your new app, you can head over to the settings page and select exactly what you need in your clone — a clone to order, if you will!

Screen Shot 2014-11-13 at 1.01.39 PM

We’re excited to see how you’ll use this new feature and how we can improve similar workflows in the future. After all, large apps require a lot of effort from many developers, and we want to make this as easy and simple as possible with Parse.

If there’s a feature that would make development on Parse easier for your team, join the discussion here!

Mattieu Gamache-Asselin
November 17, 2014

Let the Browser Handle Your UI Logic for You

At Parse, we’re in the middle of refreshing our frontend stack, and much of that has meant reevaluating the way we write browser-bound code. We’ve begun developing new custom inputs such as date pickers, dropdowns, or toggles in a way that leverages default browser behaviors to let us write less JavaScript (and reduce opportunities for bugs). Nearly every web developer has seen or implemented a date input that looked like a calendar, and chances are it contained plenty of logic to ensure that only one day could be selected at a time. This is the exact type of logic we’re trying to let the browser handle as we rebuild our interfaces.

It all starts with a simple checkbox

Let’s consider the scripting that might go into implementing a checkbox-style switch. When we click a switch that’s “off,” we change its state to “on” and get some visual feedback. We’d probably store its state in a boolean variable somewhere, add a click handler that updates the boolean, and then add or remove CSS classes based upon its current value. From a logic standpoint, it’s a duplication of something the browser can already do with <input type="checkbox">, but we put up with it for years because it let us have pretty switches.

Then the technique of using checked state to style checkboxes hit the mainstream. Using a combination of new CSS selectors and older browser behavior, it was possible to have visual elements that were tied to invisible inputs without writing a single line of JS. We use this same technique for many of our basic toggle switches today, but we’ve also taken it to new extremes with many of our UI components.

When building components, examine their core behavior

When we build new UI components for Parse.com, we follow a simple strategy: use the most similar browser element as a starting point. This goes beyond the obvious cases — such as using an anchor tag for something the user clicks — and looks at the inner behavior of a complex element. Remember the date picker we discussed earlier? The core interaction relies on being able to select a single day out of the month and visually represent that selection. Your browser already knows how to handle this: it’s behaviorally identical to a set of radio buttons! In fact, you’d be amazed by how many complex elements boil down to the radio button’s select-one-of-many behavior. They’re at the core of our own date picker, our fully styled dropdown menus, and a number of other switches and toggles. Knowing that the browser will ensure a single element is selected at any time allows us to eliminate a concern from our client logic.

uie_blog_2

Simultaneously, we avoid having to synchronize our data with our visualization, because a single interaction within the browser updates both. Along those same lines, at Parse we refrain from storing any data within a component that could be reasonably derived from its inner elements. For our specialized numeric inputs, we get the value by parsing the contents of an inner text input on demand, rather than returning an in-memory value that we update with an onChange handler. This guarantees that our JS component and its visual appearance never get out of sync.

Enough talk, let’s see a demo

My favorite implementation of this technique is found in our Hosting product. It’s a file tree that features complex interactions with absolutely no JavaScript.

uie_blog_3

When I designed the tree, I broke it down into its core behaviors: it has folders that open and close to display contents, and an overall set of files that can be individually selected. If you’re following along, it should make sense that the folders are backed by checkboxes while the files themselves are a single set of radio buttons.

<!-- Files are a set of radio buttons with the same name field -->
<input type="radio" name="hosted_files" id="f_myfile_js" value="MyFile.js">
<label for="f_myfile_js">MyFile.js</label>

<input type="radio" name="hosted_files" id="f_another_js" value="Another.js">
<label for="f_another_js">Another.js</label>

<!-- Folders are checkboxes that toggle the visibility of divs -->
<input type="checkbox" id="f_myfolder">
<label for="f_myfolder">My Folder</label>
<div class="dir_wrapper">
  Folder contents...
</div>

In CSS, we simply provide default styles for labels, and additional styles for when they follow a checked input.

label {
  color: #ffffff;
}
input[type=radio]:checked + label {
  color: #5298fc;
}

For folders, we also toggle the display property of a .dir_wrapper element that comes after a selected checkbox.

.dir_wrapper {
  display: none;
}

input[type=checkbox]:checked + label + .dir_wrapper {
  display: block;
}

With these styles, I don’t need to worry about having numerous click handlers to open or close folders, and a single change handler on the radio buttons can tell me when a new file is selected.

You can examine a slightly modified version of our file tree at this CodePen.

So what?

As web developers, we tend to lean a lot on JavaScript to build fancy interfaces and effects. I know I certainly do. But the next time you set out to build something new, look at its core behaviors and ask yourself if there is some pre-written, standardized part of the web browser that can handle some of the work for you. Yes, there is a bit of a tradeoff with markup instead of code, but I’d rather write code to generate HTML than deal with synchronizing data and visualization, handling a plethora of clicks, taps, and keyboard inputs, and ultimately replicating behavior that’s already embedded in the browser.

With these methods, you can build custom inputs that play nicely with the existing web. They fire native change events, they don’t risk side-effects in your view logic, and in many cases they even improve screen reader accessibility. If you take a look at the HTML5 spec for radio buttons, you’ll see that it only talks about behavior, not appearance. It’s no long stretch to reuse that behavior in new and creative ways, and I look forward to seeing how others employ it for interface construction.

Andrew Imm
November 10, 2014

Archives

Categories

RSS Feed Follow us Like us