Category Archives: Computing

Articles about computers and the IT industry.

Moving an app from Paid to Free

I’ve seen quite a few people saying that it isn’t possible to move an iOS app from paid to being free with an in-app purchase to unlock the full functionality. Fortunately they’re wrong.

“Traditionally” I would have had to remove version one from sale and offer a completely new app, which would have meant that existing users would have to pay again to get the same functionality. Or I’d have to support two apps. Or I’d keep the same app in the store and all existing users would get downgraded to the free version. None of these solutions seemed fair to existing users.

What I wanted was for people who had bought version one to get the full, unlocked version and for new users to be promoted for the paid upgrade.

Since iOS 7 came out in 2013 that it entirely possible. I’ll explain how it’s done here. This isn’t just some theoretical “I’ve seen the documentation” claim – I’ve done it with one of my own apps, Rootn Tootn.

The really short answer: take a look at the session 308 video from WWDC 2013. That’s the only information from Apple that explains how to do it. They have documented the API calls that are required but the actual process is left as an exercise for the interested student. And there are quite a few steps if you want to do it properly.

Firstly you need to get the app receipt. Before iOS 7 this only made sense for IAP but now they are available for all purchases and come in the same format as receipts from the Mac App Store.

Receipts have a number of useful features. In the past they have been used to validate purchase, and they can still be used for this. What’s interesting with the new receipts is that they include both the original purchase and the version number of that original purchase. This means that we can decide whether a user gets the paid functionally by looking for either an in app purchase or a purchase date before a particular time or, more likely, before a particular version.

When you download an app you should get a receipt automatically but you can also use the SKReceiptRefreshRequest class to force one to be generated. (This is also useful during development where, obviously, there is no receipt.)

Once the refresh has completed, you use [NSBundle appStoreReceiptURL:] to access the receipt.

Once you have the receipt the bad news starts.

It’s not in a user friendly format. And Apple do not provide any APIs to read it. Check out Apple’s documentation:

The outermost portion (labeled Receipt in the figure) is a PKCS #7 container, as defined by RFC 2315, with its payload encoded using ASN.1 (Abstract Syntax Notation One), as defined by ITU-T X.690. The payload is composed of a set of receipt attributes. Each receipt attribute contains a type, a version, and a value.

If security is important to you, you should probably write your own code to do this. ASN.1 is a standard format and it’s not that hard.

There are apps that generate the validation code, such as

Tighten Pro and Receigen. I can’t vouch for either of them but the reviews seems positive.

There are also Open Source projects that do the same thing. I’ve used RMStore; there’s also VerifyStoreReceiptiOS. The main disadvantage of these is that, as standard, open code it makes it easier for crackers to reverse engineer how you remember that a purchase has been made.

And there you have it. It is possible. It’s just a lot harder than you might imagine. Remember this when someone tells you that it can’t be done.

“Preview” is damaged and can’t be opened.

“Preview” is damaged and can’t be opened. You should move it to the Trash.

"Preview" is damaged.

This was the rather surprising error message that I’ve been getting when I try to open a PDF from the Finder since I upgraded to OS X Yosemite. It’s bad enough when you get an error message, but one suggesting that you delete a frequently used app is inconvenient to say the least!

Since I found it, I’ve been using a workaround: start Preview.app and open the file manually.

But there’s a better answer. Apparently it just has a duff “quarantine” attribute set. To get rid of it and get things back to normal simply do the following in a Terminal window:

/Users/stephend $ cd /Applications 
/Applications $ xattr -l Preview.app
com.apple.quarantine: 0006;53563f06;Acorn;
/Applications $

If you see the same thing, proceed to the next step:

/Applications $ sudo xattr -d com.apple.quarantine Preview.app
Password:****

And that’s all. Now opening a PDF from the Finder should work. It’s bizarre.

I raised Radar 19384558 with Apple. Please dupe if you see the same thing. Thanks to Gus Mueller (developer of Acorn) for the support.

Update: It seems that a couple of other apps also have the same, incorrect attributes:

/Applications $ xattr -l *.app Utilities/*.app | grep Acorn       
Mail.app: com.apple.quarantine: 0006;53563f06;Acorn;
iPhoto.app: com.apple.quarantine: 0006;53563f06;Acorn;

I have also removed those tags, though I’ve not seen any problems with them so far.

QA Mindf**k

When I read Rand’s recent post on QA I was pretty much entirely in agreement. A good QA team is a real asset to any project, especially large ones. However, a bad QA team can be a huge liability and cause problems for everyone.

Bad testers don’t understand the product they’re working on. They follow test scripts they don’t understand, write short, inaccurate bug reports and make no attempt to appreciate the context of any error.

This should all be obvious from Rand’s post. What’s maybe not so clear is what problems it causes.

What follows is not the tale of any one project but all of these things have happened at one time or another.

  • The QA team starts too early in development and doesn’t comprehend that it’s working on unfinished software. Many bug reports are raised for things that are known to be missing or incomplete.
  • The real bug reports contain so little data that they can’t be reproduced, or at least can’t be replicated without a lot of effort.
  • There are many bugs in the test scripts too, but since the QA team have no real understanding of what the software is supposed to do they refuse to take a second look at them.
  • Since QA don’t understand the desired functionality, important modules are not tested, leaving an unpleasant surprise at a later, critical stage of the project.
  • As the bugs pile up, the development team have to spend more and more time working on them instead of completing the project as originally planned.
  • Eventually, overwhelmed, the project is replanned.
  • This time the development team is under increased scrutiny. Metrics – bugs raised, time to fix, closure rate – are tracked.
  • Collecting all the metrics slows down development further.
  • Bugs pile up, the metrics start taking over the project.
  • The numbers mean everything. Few actually understand what is wrong, only how many defects there are.
  • Ironically, the pressure of developing the remaining features, working on the stream of defects and the new management overhead result in a decrease in quality as the same people are expected to do more work.
  • Management adds more people to the project to solve this problem. Unfortunately Fred Brookes wasn’t wrong.
  • The new project plan fails, further replanning…
  • Rinse. Repeat.

It’s a death spiral. Longer hours. Weekend work. Replanning. Delays. People, frustrated, leave. It’s toxic.

More often than not, projects like these get cancelled but sometimes, for political reasons, they have to be delivered. In order to do so the cycle has to be broken. This always requires someone brave to come in, slash the scope and come up with a truly realistic plan.

But it’s best just to have a constructive relationship between the development and QA teams. After all, the goal for everyone should be to deliver the best possible software.

Java and Yosemite

"To view this web content, you need to install the Java Runtime Environment."
“To view this web content, you need to install the Java Runtime Environment.”

Ever since upgrading from OS X 10.9 to Yosemite (10.10) I’ve been getting the above error message periodically. As far as I know I have no software that needs Java to run.

When I asked on Twitter, the most common suggestion was that it was the Adobe updater. But I don’t have PhotoShop or anything else likely installed.

I checked the system logs, but, again, nothing.

The final obvious — for a fairly broad definition of “obvious” — was in System Preferences. If you look in the “Users” pane, you can find a list of “Login items,” programs that are started when the computer boots. (I figured this wasn’t likely since the alert pops up at all time but it was worth checking.)

think I found the solution but I found some interesting (if you’re geeky) new commands that I thought I’d talk about before I document the actual solution.

So the underlying system that the Mac uses to start programs periodically is called ‘launchd’ (or “launch daemon”). It’s kind of an amalgam of init and cron and a bunch of other standard Unix processes, a concept that is controversial in some circles. The interface, I found, isn’t terribly intuitive.

In addition to the long-running process, there’s a configuration program called ‘launchctl.’ The man page runs to several pages. ‘launchctl help’ is only slightly shorter.

I find the ‘list’ subcommand in the “legacy” section and give it a try:

$ launchctl list | grep -i java
- 0 com.apple.java.updateSharing
98767 0 com.apple.java.InstallOnDemandAgent
$

The columns are Process, Status and Label. So we can see that Apple’s Install On Demand Agent is running but not what triggered it.

There’s also a sub-command called ‘procinfo’. It’s not even “legacy” so it must be good… I certainly can’t complain about the volume of information, though I couldn’t claim to understand a good chunk of it.

Ah, but then I see ‘blame’ which the help tells me ‘Prints the reason a service is running.’ Ooh, yes please!

$ launchctl blame 98767
Usage: launchctl blame <service-target>
$

Er, so what’s a service-target?

Anyway, long story short, I find that the text in the man page isn’t entirely clear and that I need to do this:

$ launchctl blame pid/98767/com.apple.java.InstallOnDemandAgent
Not privileged to signal service.
$

So, I don’t know. (If anyone could give me a sample command I’d be grateful!)

But, after all this messing around I did find something. The configuration for ‘launchd’ is scattered around the filesystem in directories like ‘~/Library/LaunchAgents’. I grep’d in that directory for “java” and found a single reference to it in an application that I installed ages ago and never used. The file is called “com.facebook.videochat.stephend.plist”. I deleted it and the other binaries related to it and then restarted.

Clean so far…

ShareEverywhere

ShareEverwhere main screen
ShareEverwhere main screen

I was so busy when it came out that I never quite got around to blogging about it here: I have a new app out! It’s called ShareEverywhere. It is built exclusively for iOS 8 and uses the new, built-in “share” functionality, allowing you to share to a good number of services from any app that uses the standard share button.

When I first wrote it, I wasn’t sure how many, if any, developers would build share widgets into their apps. Now that we know the answer is “a lot of them,” I still use ShareEverywhere because it beats having a dozen widgets hiding in your action menu. And there are still services, like Pinboard.in, that don’t have their own native apps.

It’s available now in the App Store for your iPhone or iPad. It costs £1.49, $1.99, €1.79 or your local equivalent.

How do I do “X” in Swift?

Maybe I have some duff feeds in my RSS reader. Maybe I have a few poor choices of people that I follow on Twitter. But I see links along these lines all the time:

How do you do something in Swift?

The answer is, almost always, exactly the same way you’d do it in Objective-C!

You want to do pull-to-refresh? Same.

You want to play with location services? Same.

You want to display one of the new UIAlertControllers? That’s the same, too.

Why? Because they’re all part of the underlying framework, the framework that’s there whichever language you’re using. That includes both Apple-languages — Swift and Objective-C — and everything else, C#, Python, Ruby.

That’s not to say that there is nothing useful to write about Swift. As a new language there are lots of things to write about, new ways of structuring your code, better ways of implementing algorithms. Tricks to avoid common errors or pitfalls. But interfacing with the OS? The syntax changes slightly but the code is pretty much the same.