Status

Looking forward to installing the iOS 12 beta on my iPad Air 2, iPhone 5S, and maybe iPhone 6S. I’ll report as to whether or not I notice any performance improvements (I realize the early betas aren’t really optimized). 🤞🏻 #WWDC

Regarding Free Trials in the App Store

With the recent launch of The Developers Union there has been renewed discussion about whether or not Apple should allow developers to offer free trials of their apps on the App Store. I wanted to offer a few thoughts from a beginner’s perspective.

My app, Snapthread, is a utility. In general, utilities aren’t great candidates for subscription pricing. So while devs do have the option to offer a free trial for their subscription-based apps, the only way to offer a trial experience for paid upfront apps is to implement some type of in-app purchase to unlock full functionality or upload a separate, “lite” version to the store. There’s really no good way for non-paying users to experience your app in its full glory without significant compromises.

The in-app purchase method works well enough for a lot of folks, especially if they implement it from the beginning. Unfortunately, Snapthread has been a paid app since it launched, meaning it has a chunk of users who have already paid for its features in full.

If I want to switch to a reduced functionality, in-app purchase model, I have a lot of hoops to jump through. First, I have to decide what goes behind the paywall. Do I add a watermark to the videos? Do I limit the number of clips the app will merge at one time? Once I choose and implement some restrictions, I then have to write a bunch of in-app purchase code to remove them.

But what about those users I mentioned who have already paid for Snapthread? For them, I have to perform receipt validation. There are two options: to validate receipts locally on device, which requires some sort of cryptography-related mumbo jumbo that I don’t understand, or validate using my own server.

Look, I don’t have any computer science background. I can barely describe to you in my own words what a server even is, let alone set up my own. I’m not saying Apple should make this easier just for someone like me. I’m under the impression that all of this is a pain in the butt even for people who understand it perfectly well. (A quick note: this isn’t a request for explanations regarding receipt validation. If you have a beginner level tutorial you’d like to send my way, that’s fine, but otherwise I’ll be okay. Really.)

What I’m saying is: Apple could make this a heck of a lot easier on everyone by allowing for time-limited free trials. There could be a simple list in Settings of all the trial apps you’ve downloaded, and how much time you have remaining on each. When a trial expires, maybe you’d see a pop-up when you launched the app asking if you’d like to buy or delete it. If you chose to delete it and later returned to its App Store page, there would no longer be a trial option.

Developers could choose from some pre-set trial lengths, and trials in general would be completely optional. It would take a lot of work on Apple’s end to do this—to bolt this on to the App Store’s crusty old backend. But holy cow would it be helpful for folks like me!

An interesting question for discussion: if Apple did something like this, should users be allowed to submit app ratings or reviews during the trial period? Can they do so now, with subscription trials?

Status

The great promise of blogging hasn’t failed. The freedom of expression, of owning your creative work, and the notion that if you persist in sharing good quality writing (photography, poetry, etc.), you too can achieve the success of someone like John Gruber—is still true today.

A Micro.blog App Idea

Yesterday I realized that I would really love a standalone app for publishing to Micro.blog that was focused on WordPress. The app itself would be structured very simply: it would open to a list of posts that you have published to Micro.blog (so, this could be all of your posts, or just your “microblog” category depending on how you have it set up). From there, you could edit or remove posts, with the option to remove them from both WordPress and Micro.blog. You could also filter the list by drafts, published, and scheduled, and, of course, write a new post.

The post editor would be very WordPress-centric, allowing you to add tags and assign categories and post types.

Basically what I want is the official WordPress app’s post editor combined with a list of my own Micro.blog posts. No timeline, no replies, just my own personal stuff.

I don’t have time to make this, and I’m not sure the audience for it would be very big. I’m sure most people prefer the combined publishing/timeline viewing experience. I think there could be a place for a focused, clutter-free blogging app though. Preferably with a sweet dark mode, Markdown support (for people who use it–I don’t), rich text or HTML support, and a way to get photos/images to and from your WordPress site’s media library.

Actually, now that I read through that list of features, I’m pretty sure my iOS development skills aren’t advanced enough to even make something like this. But, a girl can dream, right?

Status

Snapthread to-do list:

  • Fix scaling/rendering/exporting issues that users have reported
  • Overhaul data model in preparation for improved title cards
  • Design new titles
  • Add support for still photos (may not ship with Ken Burns effect…hoping to add it eventually once I figure it out)
Status

Thanks so much for all the congrats and well wishes, everyone! If this were Twitter, I would fave all your replies to acknowledge them. Since that doesn’t work on Micro.blog, I’ll simply say: thanks! ☺️

A Happy Announcement

I’m very glad to finally be able to share this good news publicly: my husband and I are expecting our second child in October! 😄

We’re so excited to become a family of four (plus corgi). We keep telling Charlie he’s going to be a big brother, but he hasn’t quite grasped it yet. However, whenever he sees a baby he says “awww,” so that’s promising. 😆

So then, the reason I haven’t been around as much is because I’ve been sleeping. A lot. Like, every chance I can get. For some women, one of the primary characteristics of the first trimester is a sort of soul-crushing exhaustion. Kinda like when you take a NyQuil and you can’t fight off that heavy, drowsy feeling, except all day long.

I haven’t made any progress on Snapthread, but that’s okay. I’m still hoping to get another crash fix update out as well as a big revamp of the title cards before the baby arrives. We’ll see how it goes!

I got to see our little jellybean via ultrasound this morning and was reminded anew of all the positive ways technology can enrich our lives. There’s a lot of crappy things going on in the tech world right now, but something about watching a tiny heart beat in hazy monochrome on a beige-bezeled hospital monitor makes it all melt away. I’m grateful for that.

Status

I know I’ve been kind of MIA lately, but I have a good reason (that I’m not quite ready to discuss). There have certainly been a lot of fun Apple rumors swirling around lately and I wish I had time to blog about them, but alas, I do not. I’m enjoying all of your hot takes though!

Status

It’s been another rough week of receiving bug reports that I can’t seem to reproduce. Don’t ever make a video app, folks. There are just too many variables.

Saving Abandoned Projects

I keep the Xcode project for every app that I start, even if I abandon an idea, because my old projects are often good sources of useful code snippets. Here are a couple projects I started a long time ago that will never see the light of day:

Bear in Mind

 Bear in Mind was the first personal (non-tutorial) project I ever started working on. It was going to be a visual reminder app. Instead of a table view with a list of phrases, its main screen was a collection view of circular photos. My primary reasoning behind it was that a photo might trigger a more vivid, emotional response in my brain, making me more likely to remember whatever it was I wanted to remember. Photos could be categorized by setting a colored border around them. In the future I wanted to add a voice reminder option, so that if you tapped on a photo, you’d hear yourself talking. For example, I could put a photo of my mom and a voice message that said “remember Mom’s birthday!” or something.

I could barely get the app to compile due to a million Swift conversion errors, however after commenting out a bunch of error-filled code, I was able to get it to run long enough to grab a screenshot.

Cloudburst

Cloudburst
Cloudburst was going to be a weather app for photographers. It would include the day’s conditions, when you could catch the best light, as well as daily tips and tricks. I abandoned Cloudburst after considering 1) the cost of maintaining a weather app and 2) the proliferation of similar apps on the App Store that were already pretty polished.

Lessons Learned

Both apps were great learning experiences. Bear in Mind was my first introduction to Core Data and scheduling notifications. Cloudburst was my first experience working with web APIs, UIPageViewController, and stack views. I also learned how to animate the opacity of views. Perhaps my most useful abandoned project was LiveRotate, my app for rotating Live Photos that I removed from sale prior to the release of iOS 10. I was able to use huge swaths of code from that app in Snapthread, saving me from reinventing the wheel.

You’ll notice I didn’t include my game, Corgi Corral, in this list. That’s because I refuse to acknowledge it as abandoned. I’m determined to get it on the App Store someday. I just need to completely re-do its core mechanics and make its icon and menu screen not look terrible, that’s all. Piece of cake! :)

Snapthread and the Terrible, Horrible, No Good, Very Bad Data Model

I may not have been a complete novice when I sat down to create Snapthread, but it’s obvious I didn’t put much thought into its data model.

Basically, I created a class called “Video” which had properties like “asset” (for its AVAsset), “orientation,” whether or not it should be muted, its start time, duration, etc.

The flow from selecting videos to seeing a preview of them threaded together goes like this:

  1. User taps on one or more videos and taps the “done” button
  2. The PHAssets for the selected videos are passed to the main view controller by means of a delegate and stored in an array called “videoAssets.”
  3. The videoAssets array is used for two things: 1) generating thumbnails for the video timeline and 2) fetching the actual AVAssets for all of the selected videos and wrapping them in the Video class. The Video objects are stored in a new array called “clips.”

You can already see a big problem here. I have two arrays to maintain: an array of PHAssets and an array of Video (containing the AVAssets). If a user re-orders videos in the timeline, I have to re-order both arrays. It’s mind-numbingly stupid.

It gets even dumber. I decided to add titles to Snapthread, so I added an enum called “VideoType” and just shoe-horned all the title stuff into the Video class. Now my “clips” array could have Video objects that were of type “.video” or “.title.” But wait, what about the array of PHAssets? I can’t create a PHAsset for a title card.

So, I shrugged and decided users could only add a single title at the beginning of the movie so that I could do stuff like “clips.remove[indexPath.item + 1],” taking into account the title card. It’s so, so gross.

Going Forward

My proposal for a new data model is to create a protocol called “Threadable,” which will cover any component of a user’s movie that can be added to the timeline. Whether it’s a video, title card, or still photo (which I may add support for in the future), it needs to give me two pieces of data:

  1. a thumbnail representation of itself
  2. an AVAsset to insert into the composition (for titles, this is a short blank video that’s included in Snapthread’s bundle)

All of the rest of the media-specific details will go in Video, Title, and (maybe) Photo classes. Then, I’ll have a single array of type “Threadable” which will be a million times easier to deal with.

I never really understood the benefit of protocols until this idea hit me the other night. Now I totally get it!

February Whirlwind

I realize February is the shortest month of the year, that it’s not even over yet, and that saying things like this is super cliché, but: holy cow this month went by fast.

Snapthread was featured on the App Store on the 12th and it still doesn’t seem real. It’s definitely been a fun couple of weeks. Every morning my husband waits anxiously for me to wake up so he can report Snapthread’s current ranking on the charts. At its peak, it hit #14 in the Photo & Video category and #51 on Top Paid Apps (it’s now around #104 in Photo & Video).

It’s not like I made tons of money in the last two weeks but I did make some money, which is more than I can really say for the past four years of learning iOS development. According to App Annie, in the last 30 days Snapthread was downloaded 1,424 (!) times. As soon as it’s no longer featured, I expect those numbers to fall right off a cliff; still, I’m super happy with how well it’s doing and am enjoying these feelings of success, however fleeting they may be.

As I type this, Application Loader is churning away on the first archived build of version 1.6, which adds iPad support. It’ll probably be a few days before it gets through beta review, but if you’re interested in testing Snapthread on iPad, please get in touch!

After iPad support, I hope to finish a revamped title card system before taking a break for a little while. Thanks to everyone who has shared Snapthread, left ratings/reviews, helped me out with programming questions, or just sent kind words and encouragement. This is such an awesome community and I’m proud to be a part of it!