Post-Mortem

[ Note: This is a guest blog post written by Frank Gregor (@TheCocoaNaut on twitter), an OS X- and iOS developer based in Austria, about his Mac app Review Times ] Review Times Icon

Once upon a time… No, only fairytales start that way. And this is no fairytale. It is a “true story”, like, I’m sure, many other developers have experienced one way or another. (-:

Some time around Christmas 2014, I stumbled upon a tweet, linking to appreviewtimes.com. Many of you may know about this website already. It gives you the average time Apple is currently taking to review apps for submission on the iOS and Mac App Stores.

I thought, hey, that would make a nice little Mac tool. So I asked a couple of developers on Twitter what they thought of such an app. The response I got was great. Without exception, everyone I asked wanted something like that. I had had some free time on my hands, so the idea manifested.

I wanted to build a small app that would live exclusively in the menu bar and offered a Today Widget. The information I would display in the app I would get from appreviewtimes.com. So I contacted Dave Verwer (@daveverwer on twitter), founder of Curated and publisher of the well-known iOSDevWeekly newsletter. He was the contact listed for the Shiny Development team, who are the creators of appreviewtimes.

I asked Dave if they perhaps already had such an app available or in development, and if that wasn’t the case, if they’d mind if I developed the app and used their data for it:

Hey Dave,

I found you as contact for Shiny Development, the maker of App-Review-Times. So I think it would be a great thing to have a little OS X tool that shows in an app extension the current review times via Notification Center. I’m building exactly such a tool and I have to grab and parse the website to get all the needed data.

So, to make things easier for development: Would it be possible to get all that raw data (iOS & OS X) as JSON or XML? Would be really great! (-;

Cheers, phranck

Dave answered promptly:

Hi Frank

I’m afraid that we don’t have either JSON or XML feeds of the information.

Please feel free to scrape the HTML though, as long as you include a link back to the original site.

Thanks Dave

Great! Now nothing stood in the way of me selling this App on the App Store (though I would learn better later). I got to work and within two days, I had a working prototype.

The fact that this app would run as a menu bar tool was very beneficial to me. I had been working on a piece of open source code, which does exactly that: place an icon in the menu bar and display a popover when clicked. This gave me a very good reason to further develop and improve the open source code.

Screenshot of Review Times Popover

Now was the time to tweet some screenshots, to whet the appetite of potential customers. It worked well. I received a lot of inquiries about what the app was about. This way, I got my first beta testers.

Review Times Today Widget

All in all, about three to four weeks went into developing the app and I believed the app was ready. I needed a nice icon that should really catch the eye. I made the acquaintance of Dan (@derpixeldan on twitter) and he created something truly wonderful at an unbeatable price… (-;

Around Mid-January, I submitted the app to the Mac App Store. Excitedly I waited for the notification on my iPhone that the review process had begun. About three weeks later, I received the message I longed for.

It didn’t take long and the review team contacted me again. But this message wasn’t what I had hoped for. My app got rejected! The reason Apple gave me was

…featuring speculative information about Apple products/services…

which I didn’t find reasonable at all. I was shocked. Every developer who ever received a “Rejected” notice knows this feeling of unease. I was annoyed and angry at the same time. Why in the world… ?!?! Did I go about this entire thing too naively?

Appstore Rejection

If you are familiar with Apple, you know they like to have control. And speculative information – like the average time it may take for Apple to review an app until submission to the App Store, shown by an app by some developer – well, that was completely out of their control. So Apple showed me, who’s boss.

That took the wind out of my wings in respects to this tool. I didn’t want to get into a discussion with Apple, it wouldn’t have lead anywhere anyway. I vented on twitter and let the whole thing rest for a couple of days – until, again on twitter, I received inquiries about what had happened to the app and how I would proceed with it. There were two possible options for me: 1) publish it as open source code 2) sell it outside of the Mac App Store from my website

On Twitter, I asked for input.

Since previously, people had stated their interest in paying for this app, I decided to go with option 2. After some research and testing how to best implement selling it from my website, I came to the conclusion that I should use Paddle. Their integration into an app is absurdly easy to do and they have first-class support.

All said and done, it took three more days of coding and testing and then everything was ready. I built a one-page website, wrote to many Mac-Blogs and magazines (none of whom replied!) and announced the release on twitter. Since so many developers wanted this tool, I was preparing for incredible sales-days… (-:

Poppycock. Virtually nothing happened. I sold a couple of copies, but all in all it went very, very slowly. Even after two months – with heavy-duty tweeting about it – I didn’t even make up for the cost of the icon. Reality had its grip on me again. So I had to act. Without thinking about it too long, I deleted all license- and purchase-handling code and released the app for free from my website.

Now everyone can download and install the app from http://reviewtimes.cocoanaut.com. Since then, I’ve had about 1-2 downloads a day.


Frank Gregor (@TheCocoaNaut on twitter) is an OS X- and iOS developer based in Austria. Among others, he is responsible for the Mac apps Review Times, Nekrologger and the iOS app f4analyse.

Read more

First Concept of ZENFirst concept of ZEN

After last week’s guest blog post by my cousin Sebastian about how he came up with the idea of the iOS game ZEN, the design and conception process behind it and the soundtrack, today it’s my turn to talk about putting it in code and making it all come to life.

The Premise

Like a lot of developers I know, I became intrigued with programming because of games. As a kid, I always wanted to develop games for a living, make the next Diablo. So of course I jumped at the idea of creating a game when my cousin asked me if I was interested.

I had never actually programmed a game before, so when Sebastian approached me about developing a game with him, I was already seeing myself having to learn OpenGL and everything that comes with it.

Luckily, it soon became clear that it would be a 2D game, almost 8-bit-ish, like an old Super Mario Bros game. So my fears of having to learn something new* were put to rest and the more he told me about the game, the more I realized that Core Animation would be the perfect fit for this project.

The game is about a cube with random numbers on it. Your goal is to reach ten with these numbers by turning the cube and selecting the appropriate sides within ten seconds.

ZEN Cube Animation

*just kidding, I love learning new stuff, but for a side-project having to learn OpenGL would have been a little much, especially with all my other apps that need constant attention

Core Animation actually was pretty much made for this kind of stuff. Even if the game had had some 3D effects (for example, some sort of perspective distortion when turning the cube, etc), it would have been fairly easy to implement.

First Blood

The first thing I did in the process of developing ZEN was to prototype the cube itself. I began by mapping out the cube because a) I didn’t have one handy and b) to get a visual on each side:

Mapping out the cube

Because I was using Core Animation and it was all in 2D space, I had to figure out what side would go where when the cube was turned from left to right, right to left, from the top or the bottom, so that the numbers would stay on the same side and not end up any place they shouldn’t be. I went so far to write down which side would go where once the cube was turned in any direction

Mapping out which cube side would go whereWhich side goes where when turning the cube?

To make the animation possible, I would have to use at least two CALayers that changed in shape and color, and would have to be kept up to date in terms of data (which side holds which number).

One layer would always be hidden, the layer to turn to, so to speak, the other layer would always be visible. They would alternate in doing that.
For example:

Layer 1 is visible with the front number of the cube.
You turn the cube right and layer 2 (still hidden) gets the number of the left side of the cube.
Layer 1 is animated to fold to the right
Layer 2 shows and animates to the full size of the front cube side.
Layer 1 is hidden

Turning Cube Down on PaperTurning the cube from the top on paper

With that done, I had the cube – of course, there were some kinks to be worked out (for example, sometimes the hidden layer would suddenly be visible with a completely wrong size), but basically, the cube was working.
In code, turning the cube upwards looks like this:

- (void)turnUp
{
ESSCubeSide *oldUp = self.topSide;
ESSCubeSide *oldFront = self.frontSide;
ESSCubeSide *oldDown = self.bottomSide;
ESSCubeSide *oldBack = self.backSide;
self._cubeDict[ESSCUBE_FRONT] = oldDown;
self._cubeDict[ESSCUBE_TOP] = oldFront;
self._cubeDict[ESSCUBE_BACK] = oldUp;
self._cubeDict[ESSCUBE_BOTTOM] = oldBack;
}

This is only the data model, of course. The view code just the two layers – resizing them in unison, hiding one layer and showing the other, etc.

Random Numbers

The next thing that had to be done was to fill the cube with random numbers, some of which would add up to ten.

I chose to do the following:

  1. Decide how many sides it takes to solve the current cube (a number between 2 and 6); let’s say it’s 3 – 3 sides to solve the cube.
  2. Loop while we create 3 random numbers between 1 and 9 that add up to ten.
  3. Fill the rest of the cube (3 more sides) with random numbers between 1 and 9.
  4. Shuffle the resulting array of six numbers so the solving sides aren’t always on the same sides
The same principle works for the minus mode, where there are positive and negative integers that you need to select to add up to ten.

Interface

The first interface concept, as you can see in the first screenshot of this blog post, was pretty simple. The title and three buttons. There was no mention of animations!

As it always happens, things change during the development process, you iterate on everything, and the interface gets overhauled as well. This new one was, in my opinion, much nicer as it demonstrates the “cube-y” nature of the game very nicely.

ZEN Line animation

But it took me some time to get there. I was hoping that Sebastian could define the animations in svg or gif or something like that and I could just load them in and display them.
However, I could not do that – apparently iOS doesn’t support svgs or gifs out of the box (and I didn’t want to rely on 3rd party libraries to do the job). After googling around for a couple of days (because, you know, you want to be thorough), I tried doing it in a web view, because these animations would work in the browser. However, I wouldn’t have that amount of control over them as I did with the final approach I took – code it in Core Animation as well.

So I have one view class that, depending on the width and height of the bounds of the view either expands horizontally or vertically. That was the easy part.

The hard part was creating all the views in Xcode’s Interface Builder with the proper dimensions and positioning them so they would define the buttons and letters. I’m just glad the Help – view is not animated 😉 :

Help ViewThe Help View – thankfully for me, not animated

Creating ZEN was a very exciting experience and I learned a lot during the process. As I usually work alone, working within a team on this project (even if it’s just two people) was a breath of fresh air and is a lot of fun, bouncing ideas off of each other, inspiring each other – there’s a whole lot of energy there.
While I do have a few dear friends with whom I can exchange ideas over the internet for my own projects, it’s quite different when you’re one on one, face to face.

It’s been  a lot of fun.

—-
My name is Matt, I’m the developer of Eternal Storms Software. If you’d like to comment, you can catch me on twitter here: [twitter-follow screen_name=’eternalstorms’ show_count=’yes’] or by eMail.

Read more

[Note: This is a guest blog post written by my cousin, Sebastian Gansrigler, about the iOS game ZEN (App Store) he and I developed during 2014]

It was around March 2014, I started to set up a basic idea for a game I wanted to create in my spare time. How about combining a Rubik’s Cube and 3D game mechanics with complex mathematical theory and provide all of this with minimalistic pixel art on a touch interface? ZEN was born.

Basic concept on paper, pixel measurements, final screenBasic concept on paper, pixel measurements, final screen

I can’t really say where the idea came from, the game was always based on the concept of a rotating cube, about revealing something that’s hidden, about stress, learning, advancing and getting better and better by repeating it over and over again. ZEN was a good name: …a school of Mahayana Buddhism that developed in China during the 6th century. The word might be translated as something like “absorption” or “meditative state”.

Since I didn’t want to use any fonts, plugins or other preset assets, I created everything from scratch. Beginning with first scribbles on paper, I subsequently moved on to Photoshop and Illustrator to build a basic grid system, alignment rules, colors, etc. I tried to treat pixels like real pixels, there’s not one element in the game that’s round or off grid. Everything had to be perfectly consistent and at the end, of course, fun to play. From then on I went into After Effects for animations and interactions.

All game elementsAll game elements

One musician I had in mind for ZEN’s sound design was Brian Grainger aka Milieu. He created the original score for “Eufloria”, which I played a few years ago on PS3 and totally loved. I wanted something relaxing, yet stressful and packed with tension. Somewhere between Mount Kimbie, Kavinsky and Baiyon. I wrote him, Brian got on board and created an amazing soundtrack (soon available on his Bandcamp) and all sound effects.

Matthias Gansrigler, my cousin, has created some great apps for OS X and iOS, so I contacted him about the game. He did all the code and actual implementation of graphics and animations. The bug fixing was most fun, as soon as something had been fixed, something else came up. Special thanks to Das Möbel in Vienna for a great location to brainstorm and discuss (and of course for the ham & cheese toasts).

Funny button bugFunny button bug

After quite a bit over half a year of production, the game was completed and went online on December 21 2014 on the App Store for iPhone and iPad.


Sebastian Gansrigler is a 20-year old photographer and designer in Vienna, Austria. He works for WDM responsible for web and graphic design. You can reach him on twitter under @gansrigler.

Read more

Transloader Mac Icon

You might have heard about my new app, Transloader, for OS X and iOS.
I’d like to give you a little background info on the app because it’s been an interesting process creating it and getting it out to users.

What Is Transloader?

Transloader (né Lifeline – as in a line that keeps your connection to your Mac alive) lets you send URLs from your iOS device to your Mac for download.
Say you’re browsing on your iPad and come across a Mac demo app you’d like to try. On your iPad, you can’t download it and even if you can, there’s not much use in it since it’s a Mac app. This is where Transloader is useful.
Enter the URL to the demo into Transloader on your iPad and it gets synced to Transloader on your Mac where the URL will be downloaded to your Downloads folder, ready for you to use when you return to your Mac.
That’s it. Pretty simple, isn’t it?
Creating it, however, wasn’t 😉

Got To Get You Into My Life

The idea for Transloader, like for all my other apps, came out of a need I had myself, a little more than two years ago (and I’d been sitting on pins and needles ever since, thinking someone else might come up with a similar idea and beat me to it).

I browse the web a lot on my iPad. And it’s not unusual that I come across a zip or dmg file, or even a movie I’d like to download for later.
What I used to do was send myself an eMail containing the URL to the file – and I can’t tell you how much that bothered me.
It’s so much unnecessary work to do it, it’s so tedious:

  • Copy the URL
  • Open Mail
  • New Mail
  • Enter my eMail address (I have several, so I need to find the right one in the list)
  • Paste the URL into the mail’s body
  • Send
  • Confirm I don’t want a subject for the eMail
  • Sent

And when I’m back on my Mac:

  • Launch Mail (if I don’t forget I sent myself a link)
  • Find the mail
  • Copy the URL
  • Launch my browser
  • Paste the URL into the browser and wait for the download

I believe in writing apps for a single problem, even if it’s a very small one. I like to keep things clean. And to their purpose. I don’t like using eMails to remind myself of something. That’s what the Reminders.app is for or perhaps the Notes app (though I can’t tell you how many times I forgot I put something into Notes.app for later, and only months later found it by accident).

I wanted a much simpler way to do this. So I had the idea for Transloader. The workflow would be very simple:

  • Copy the URL
  • Launch Transloader
  • Add the URL

and on the Mac:

  • If Transloader’s not running either launch it
  • or if it is running – do nothing.

Let the app take care of everything else. The sync, the download – that also has the advantage that the user does not have to initiate the download. It starts downloading as soon as the URL is synced – and, ideally, the download is ready once you’re back at your Mac. That was the idea for Transloader.

We have all the time in the world

To reiterate, I had the idea for the app about 2 years ago – before Apple introduced iCloud.
So I had to find a way to make the iOS app talk to the Mac counterpart.
I basically copied the way Apple’s Remote.app on iOS handles the connection to iTunes on the Mac, asking for a PIN.
The setup needed to be done by the user. Start the server app on the Mac, launch the app on iOS, add the server by entering the IP and the port to connect on and then enter the random PIN displayed on the Mac.
Once the setup was done, the app worked pretty much the same as it does now. Add URLs on iOS and it would get transferred to the Mac directly.

There were quite a few things different, though.
Due to the direct connection to the Mac, more control was possible. For startes, you could have multiple Macs you could differentiate between and send URLs to. You could interrupt downloads, you could see how far along the download on your Mac was and how fast it was going and you could delete the downloaded file from your Mac once it was finished, remotely from your iOS device.
On the other hand, to add URLs, an internet connection was mandatory at the time of entry and the setup to get the app working was tedious. The Mac had to be running, so did the Mac app. Also, adding URLs over the internet was only experimental, only the Bonjour service (meaning you had to be in the same WiFi network for it to work) was really supported. (Although I must say I never had a problem with adding URLs over the internet, but it depends on your WiFi router, port forwarding, etc).

Part of why it took so long to release the app was that I wasn’t completely sure if the “experimental” internet connection would go over well with users. The purpose of the app was to be able to add URLs while on the road, somewhere in a café for example, not at home where you’re at your Mac anyway.

Lifline on MacLifeline, the first iteration of Transloader, on the Mac.

Lifeline on iPhoneLifeline, the first iteration of Transloader, on the iPhone. Server Selection.

Photo 3Lifeline, the first iteration of Transloader, on the iPhone. Showing progress and speed of the download.

Stuck inside a Cloud

Some time went by where I didn’t do any work on the app. Only using it myself and showing it off to people to get feedback.
Maybe half a year passed. Perhaps a little more.
Then what happened was that Apple announced iCloud. At first I didn’t make the connection, but I soon came to realize that it would be the perfect fit for my app.
I always hated the fact that a server/client configuration was necessary for the app to work. I didn’t want to put the user through any of that.
Also, with iCloud, at the time of entering a new URL, a connection to the internet is not necessary and the Mac app doesn’t have to be running. It gets synced as soon as there is an internet connection again. Big plus.

I realized I wouldn’t be able to give the user the control they would have had with my own implementation (mainly getting feedback on the progress of the download and its speed) and that I would make myself rely on a service that might not be available at times, but knowing that using the app would get much simpler, especially first setup (of which there is basically none now), was enough to make me go for it. And I haven’t regretted the choice since.

Changing from my own system to iCloud was a complete re-write of the app. Obviously.
However, it took way less time than the first implementation since I didn’t have to deal with any server/client implementation or communication between the two. All of that is handled by iCloud.

It took maybe two weeks to get the app working and basically finished (no polish, of course). In comparison, the first version took me a few months.

She feels good, she knows she’s looking fine

Once I got the app working and finished from a coding standpoint, it was time to get the UI done.
Everything you see is the creation of the brilliant Alexander Käßner who, I think, couldn’t have done a better job with the app.
And customers seem to agree, they do like the graphical elements very much.
After maybe two days I had a mockup and a few days later, the graphical elements were done and put into the app. It was a quick and painless process.

Do what the rest all do, or face the fact that the Apple Store Review Team may have no other choice than to reject you (in short – DAMN, Transloader was rejected)

I usually submit new apps to the App Store well knowing the first submission will likely result in a rejection.
Transloader was no exception. Not because of the usual reasons (Sandbox, for example, or a stupid unnecessary bug I overlooked in final testing), but because I was using iCloud in a different, unexpected way. And I kind of felt it was going to cause problems.

And I wasn’t wrong. It didn’t take too long until I got a call from a very sweet, patient and understanding representative of the Review Team, telling me Transloader got rejected for using iCloud as a transport mechanism and an iCloud account being necessary for the app to work.

I tried making the point that at no point is any file stored on iCloud and that the sync was used as a sync, not as a transport mechanism – it syncs the URLs to all devices. What the Mac does with that link is a different story, but of no concern to iCloud, because the actual download has nothing to do with iCloud or the sync.
I also tried arguing that if the reason for rejection was that an iCloud account was necessary, there shouldn’t be any twitter, Facebook, flickr or instagram apps allowed on the App Store either because they all needed accounts for their respective services as well (a cheap shot, I know, but I was frustrated).

Anyway, my points didn’t go over well. The rejection was done.

Reconsider, Baby

At this point, I was kind of desperate. I was so close to finally releasing the app but couldn’t have been farther away at the same time.
I resubmitted the app to Apple with a video explaining how the two apps worked together and a lengthy review note providing even more details.
Yet again, no dice. I got another call from the representative, asking me not to submit the app again without significant changes to how it worked.

So I considered going back to my original implementation. Users would just have to endure the horrible server/client setup.
I just wanted the app out at this point. I got lots of positive feedback from friends, family and colleagues about the app so I was confident it would do ok.

I started to work on re-implementing the first implementation when about two weeks later, I got another call. They were sorry it took so long to review, it was a complicated, different way of using iCloud and they had to make sure it all was in order. It would be live on the App Store in a few hours. I just sat there in amazement, mumbling out a “Wow, thank you” and hung up.

I seem to have a guardian angel and I couldn’t be more grateful.

Don’t ask me what I want it for if you don’t want to pay some more

You might have noticed that the iOS app is free and the Mac app is $4.99.
I had to find a way to make sure Windows-PC users wouldn’t pay for an app on iOS they couldn’t use.
Transloader for iOS depends on the Mac app, and the Mac app depends on the iOS app. One without the other is completely, entirely, utterly useless through and through.

Another angle, obviously, is that Mac users might not have an iOS device but pay for the Mac app. I had to decide for one way or another, though, and I figured the chance of a Windows user having an iPhone is higher than a Mac user not having one.
Plus, I added a disclaimer in the apps’ descriptions that both a Mac and iOS device are necessary. So far it hasn’t failed me.
There have been enquiries to develop Transloader for Windows, though 🙂

Now you’re expecting me to live without you…

Transloader is the first app I don’t provide a demo for. It’s not because I don’t want to, it’s because I can’t.
iCloud needs a provisioning profile in the app bundle that is only available to apps downloaded through the Mac/iOS App Store which makes a demo impossible.

It’s been quite a journey and I’m so very happy I was finally able to release the app. I’ve got a few things planned for it and I’m looking forward to putting out updates and implementing some of your amazing suggestions. Keep them coming 🙂

Thank you for your time 🙂
Take care,
Matt

[twitter-follow screen_name=’eternalstorms’ show_count=’yes’]

Read more