I ran DaisyDisk the other day to reclaim some lost disk space and found some oddities. One of these was Google Chrome using over 4GB in my Applications folder.

A browser really shouldn't require 4GB of space. So I emptied Chrome's cache, but that didn't affect the overall size at all.

I peeked inside (right-clicking on Chrome and selecting Show Package Contents) and in Contents/Versions I found this:

So many Chromes!

Chrome was storing a backup of itself, presumably every time it did an auto-update. As far as I see tell there is no way to delete these backups from within Chrome or turning off this behaviour.

Deleting all of them but not the newest one didn't seem to make a difference — Chrome works fine and I got some disk space back.

Of course if this crashes your Mac and it bursts into flames that's on you :-)

Posted
AuthorPaulo Fierro

Last night I decided to get my toes wet with iOS 8 + Swift. There are so many, many goodies in iOS 8 as well as a whole new language to learn so I fired up the Xcode 6 Beta, put on the WWDC 2014 session on "Creating Extensions for iOS and OS X, Part1" (#205) and got to work.

A little while later I had an extremely simple app but most importantly a working Today Extension.

Oh yeah!

How many steps have you taken today?

This morning I cleaned it up and uploaded it to Github. These things really have the possibility of being awesome.

I'm very excited for the fall!

Posted
AuthorPaulo Fierro
TagsiOS

A little over two months ago we launched Brainfeed — an educational app for iPad that we built for a great client in the US.

We loved the idea behind the app and worked hard to sweat the little details striving to make the app fast, fluid and fun. We collaborated with Anne-Sophie Leens on the visual design front — we'd worked with her before and knew that she'd be a perfect fit for the project.

Post-launch the app was steadily getting some attention. Interestingly it did really well very quickly in parts of Africa and South-East Asia where it shot up the charts. It got into the top 10 in a couple weeks in countries like Nigeria, Kenya, Egypt and the Philippines.

Then Europe took notice. First it started climbing the charts in the Eastern countries and slowly moved westward. Then on a Saturday afternoon our client got an email from Apple requesting artwork as the app was being considered for promotion.

This could be huge.

It was on a weekend and I was away so we couldn't provide any help but they scrambled and got the material together and submitted it right before the deadline and then we waited. And waited.

And then this happened.

App Store banner

App Store banner

This banner started appearing in the App Store in some countries. First as a small banner, but then eventually the main banner at the top of the store. Placing our app alongside other apps and games from the likes of Disney, EA and Nickelodeon.

Main banner for Kids 9-11 in the UK App Store — April 27, 2014

This was absolutely amazing.

When an app is published you have to choose two categories that it should belong to that make sense. For Brainfeed this was Kids and Education, though for Kids you have to specify an additional age range — so it kind of gets three categories.

Reaching the #1 spot for Kids 9-11 was no mean feat (its done so in 64 countries thus far), but it also started rising slowly in the more general Kids category and then Education which is massive.

While this was happening the app started to get noticed in the States and landed on the #4 spot for Best New Apps in the US App Store.

US App Store: Best New Apps — April 27, 2014

As you can imagine this was huge for visibility.

And then this weekend, the app got another major spike when Apple featured it in the iTunes Education Spotlight (in the Canadian one too). Still there as of this writing and immortalized forever in the screenshot below.

iTunes Education Spotlight featuring Brainfeed — May 26, 2014

This is the first time I've worked on an app that's gained so much exposure.

One thing is rising up the charts and reaching:

  • #1 for Kids: Ages 9–11 in 64 countries
  • #1 for Kids in 23 countries
  • #1 for Education in 17 countries
  • reaching #4 in the US in Kids: Ages 9–11

However for me getting the app featured by Apple means much more. A prominent spot in a newsletter that goes out to teachers and parents means we definitely did something right, and that's certainly something I am very proud of.

Posted
AuthorPaulo Fierro

My main development machine used to be a 2010 MacBook Pro with a 512 GB SSD. Expensive, but way fast. Unfortunately the GPU died about a year ago so I've been using a 2011 iMac. Its also fast, if not faster than the MBP for many things but disk operations are not.

A few weeks ago on Dave Verwer's brilliant iOS Dev Weekly I found a blog post explaining how you could speed up Xcode (and AppCode) build times. This is done by moving Xcode's DerivedData folder as well as iOS Simulator Data to a RAM disk.

A RAM disk is taking a chunk of memory and treating it as a if it were a drive. Now SSD's are fast, but memory is still much faster. If you have extra memory lying around I recommend giving this a shot.

I didn't go the Terminal route but instead used iRamDisk from the Mac App Store. I was skeptical, but it definitely works.

Building and running an app I'm currently working on into a clean iOS Simulator used to take 20 seconds. Using iRamDisk it now takes 7. That's huge.

Regular builds are also much faster and very noticeable after doing a Product > Clean.

DerivedData gets a gig

The Simulator gets 512MB

The dropdown menu in the menu bar also lets you know how full each disk is and you can easily flush them via a menu option.

Menu options

Menu options

If you have extra memory lying around I'd give it a shot.

Posted
AuthorPaulo Fierro

Last week we shipped Brainfeed, an iPad app we've been working on for a client that presents educational videos for kids. We also developed a backend system for the curators to use to add and tag videos for the app.

This backend is built in Ruby with Padrino (on top of Sinatra) and runs on Heroku. Due to the nature of the app it only needs a single dyno and pushes content changes over to a bucket on Amazon S3 which is consumed by the iPad app. This means that the app can continue to work independently from the backend and any scaling issues can be handled on the S3 side of things, which has the added bonus of keeping the overall cost down.

Previously the app was consuming a JSON file provided by the backend via an API. When you're serving JSON (or any data) you really want to serve it compressed to save on bandwidth and overall load time.

In Apache you can add a line to your .htaccess file that indicates this like so:

AddOutputFilterByType DEFLATE application/json

This gzips JSON content on the fly automatically. This is normally already set in Padrino/Sinatra apps using Rack::Deflater.

However, when I started pushing the JSON over to S3 I needed a way to tell S3 to serve the content in a compressed fashion. Using the AWS SDK for Ruby you can do this like so:

Before the gzip compression we were serving about 960KB. Now that's down to 240KB which is much more manageable. Due to the nature of the app (watching online videos) we know the users are going to be on wi-fi so its not that big a deal, but every little bit helps.

For some reason this took way too long to figure out, so here it is for next time.

Posted
AuthorPaulo Fierro

This week we had the pleasure of shipping Brainfeed, an iPad app I've been working on the last few months aimed at providing educational videos for kids, 7-years and older.

Brainfeed

Each video is handpicked by a team of enthusiastic educators from around the globe who are tasked with finding short (under 10 minutes) and documentary style videos that are curriculum based, entertaining & engaging, visually stimulating, age-appropriate and child-friendly.

The app itself is free, but there to unlock all of the content you have to sign up for a subscription. The videos are great so its well worth it.

We were responsible for building the iPad app as well as the Sinatra based backend system for adding and tagging videos.

Its something I'm really proud of and its now available on the App Store.

Posted
AuthorPaulo Fierro

This morning I was using Charles to monitor some HTTP requests like I do. I noticed some odd requests were showing up every time I changed tabs in Safari, but also when swapping to and from Safari.

The requests were going to something on localhost that was running on a range of ports and accepted a request at /snap/new. So something is trying to take snapshots of every page I visit in Safari.

This can't be good.

Suspect requests

After looking around I checked the Safari Extensions to see if I had installed a rogue piece of software and there it was. Nothing fishy at all, just Ember. There to do its job which is to take screenshots.

Disabling the extension got rid of the requests and I could get back to what I was doing without poor Charles getting flooded.

Posted
AuthorPaulo Fierro

While I was working this morning I ran into some issues with an app and went to check if the Console (under /Applications/Utilities) was reporting anything.

Unfortunately the log was filled with some USB device timing out with the following error:

AppleUSBEHCI::Found a transaction past the completion deadline on bus 0xfa, timing out! (Addr: 5, EP: 1)

A very noisy log

This timeout was annoyingly happening every few seconds. The error did give me a few clues. It was happening on USB bus 0xfa on a device attached to address 5.

To find the device in question I generated a System Report ( > About this Mac > More Info > System Report) and looked for the USB bus with the same address.

Finding the USB bus number

Finding the USB bus number

Then it was just a question of going through the devices connected to this bus that had the address in question.

The address of the USB device

The address of the USB device

Found you! The device in question was the Garmin ANT+ stick that transmits data wirelessly from my Garmin Forerunner 610 watch.

Unplugging it fixed the problem and the Console stopped being flooded.

fry.jpg
Posted
AuthorPaulo Fierro

I love git and Github but I don't have any git-fu, as in I don't know how to use the command line version of git to save my life.

Don't get me wrong, I'm fine using the Terminal and for some tasks I even prefer it. But for version control, a GUI does it for me and in this case my app of choice is Tower.

And while Tower is great, and the web interface on Github is good too I recently ran into something I couldn't do with either (or I couldn't figure out).

Deleting tags.

I use tags all the time. Bookmarking commits — what's not to like? For simple things like "this is version 1.1" which we can come back to and branch off of if we need ship a bugfix for 1.1, while at the same time developing new features on the main branch. And for things like "this is where I was before that sketchy merge".

For the first example, this is probably a tag we want to keep and add some release notes. But for the latter, we might want to delete it when we're done. Once we've done testing and QA and everything is good we can nuke that sucka.

So in Tower you can right-click a tag and delete it but if I then push and check "Push All Tags" the tag doesn't get deleted. The next time I pull that tag will come back because I didn't delete it from Github.

We can do this on the command line as follows:

  1. Delete the sketchy tag locally: git tag -d sketchy
  2. Delete the tag on Github: git push origin :sketchy
  3. Push the change: git push --tags

If you added any release notes (and you should) they'll now show up under your project's releases as drafts that are no longer tied to a tag (because you deleted it). To remove it, click to edit it and then Delete Draft.

Posted
AuthorPaulo Fierro

Recently Niqui and I have become addicted to paddleboarding. We've started doing paddlefit with the guys from Waterman and renting boards in the weekend to go paddle around Seven Mile Beach. This is especially beautiful at sunset.

A week ago we made the jump and picked up a cheap deal on a second hand board on eCayTrade which we've been sharing.

This resulted in us doing what we call a "paddle run". Start at Governor's Beach and one runs the 2.5km down to Royal Palms while the other paddles. Then we switch and head back. Good fun, but the runner always wins.

Being summer and there not really being much wind I was intrigued when I saw this video on how to SUK:

Tried it out yesterday but it didn't really work out, there simply wasn't enough wind. I also fear the my kite is too small (12m) and/or the SUP is too big (10' x 29" x 4.5") but I intend to giving it another bash. 

Posted
AuthorPaulo Fierro

On my desk sits a 21" iMac which is plugged into a 27" Apple Cinema Display. The iMac is a great machine, but the audio quality is better coming out of the Cinema Display — larger screen, probably better speakers.

My desk on May 17

So when I'm playing music I always select the sound output to come from the Cinema Display. You can Option+click the Volume icon on the menu bar and select either "Display Audio" or "LED Cinema Display", both mean the same thing. If I want to use the iMac speakers I select "Internal Speakers".

But what if I want to use both? Madness right? After looking around I found that you can create a "Multi-Output" device using the Audio MIDI Setup app.

So after doing that I created a multi-output device called "Both Screens" with output going to the built-in iMac speakers as well as the Cinema Display.

The only downside is that you have to control the volume from the app doing the playback, e.g. iTunes. Whatever volume you had the selected display at is what's used so you may want to swap back to it, set the right volume and then swap back.

Dual monitor sound output. Hell yes.

Posted
AuthorPaulo Fierro

CocoaPods

I'm really glad I took the time to learn and use CocoaPods on this latest project. Such a massive time saver for iOS devs. No more adding linker flags, copying bundles and keeping external frameworks up-to-date manually.

I simply write a Podfile (similar to a Gemfile if you come from the Ruby world), and run "pod install." If a library I'm using has been updated I run "pod update". If a library I want to use isn't available, you can easily submit it to their list of specs on Github.

Great stuff.

Spark Inspector

Its like a Web Inspector for iOS apps. Modify your UI's properties and see the changes live in the Simulator or on your iOS device. you can also see your views in a 3D extruded mode to get a better grasp over how your UI is being laid out.

There's also a notification monitor to see notifications and their payloads as they are fired with the added ability to go back and resend them. Not used this much yet but it looks snazzy.

Crashlytics

I like TestFlight for distributing builds though I will be using Hockey on our next internal app because I've heard great things.

However I no longer ship the TestFlight SDK in our apps because I find the crash monitoring in Crashlytics to be far superior. You can group similar crashes and mark them closed once you've fixed the issue. You also get so many more useful details like available disk space, how many users are affected, etc so I would recommend you give it a shot. I'm a fan.

We're in the business of building things that makes our lives easier and these tools make the development easier.

Posted
AuthorPaulo Fierro

Lately Niqui has been having some issues with her iPhone 5's lock button. It works now and then, but you have to press it 6-7 times before it actually locks the screen which is quite annoying.

You can set phone to Auto-Lock after a minute but sometimes you want to lock the screen at a particular point in time.

Enter LockMe.

lockme.png

LockMe is a tiny app that simply locks the screen and quits. It uses an undocumented function called GSEventLockDevice which does just that. Its part of the private GraphicsServices framework so the app can't be submitted to the App Store, but it does the job until she can get her phone fixed.

There's a few ways to use private frameworks but I found the simplest route was to load it dynamically at runtime. The meat of the app is just ten lines of code.

That's pretty cool if you ask me.

So if you or someone you know has the same issue, grab the app from our GitHub repository, build it for them and be a hero :)

Posted
AuthorPaulo Fierro

I'm currently working on an internal iOS app and while I was working on putting together the About screen I ran into an issue where unicode characters in a UILabel were being displayed as emoji by iOS. While this is kind of awesome, its not really what I was going for.

So my code:

label.text = @"Made with ❤ by jadehopper ltd.";

results in:

madewithemoji.png

To disable the emoji character we have to tell iOS to use the variant of this character. In order to do this we change the label text to:

label.text = @"Made with ❤\U0000FE0E by jadehopper ltd.";

which results in:

madewithnoemoji.png
Posted
AuthorPaulo Fierro

When Niqui and I moved over to Grand Cayman last summer we realised that one of the things that we had been completely spoiled with while living in Brighton was the great tech-community and the amazing people that live and work there — some of which we are lucky enough to call friends.

interactiveky

Soon after moving over, Garth Humphreys invited me to a couple Facebook groups which allowed me to (virtually) meet other people in our industry living on our tiny island. Recently we'd been chatting with some friends at BB&P, a local agency, who were also looking to get the local community together and they kindly invited us to use their space.

So earlier this month we had our first get together so we could meet in meatspace. Our first meetup was a great success and everyone that turned up was keen for more of them.

And so we have interactive.ky — a meetup for designers & developers living in the Cayman Islands. Our next one is next Wednesday, April 3 and you're more than welcome to come join us.

Earlier today Ingrid Riley wrote a lovely piece on our group over on Silicon Caribe.

Posted
AuthorPaulo Fierro