おやすみ by Tom Royal on Flickr
Tokyo by Tom Royal on Flickr
Miho no Matsubara by Tom Royal on Flickr
Miho no Matsubara by Tom Royal on Flickr
Miho no Matsubara by Tom Royal on Flickr
Miho no Matsubara by Tom Royal on Flickr
Mount Fuji by Tom Royal on Flickr
Hokutosei by Tom Royal on Flickr
Hokutosei by Tom Royal on Flickr
Sapporo by Tom Royal on Flickr

You're using a very old version of Internet Explorer which can't show the photos that should be in this box. Please consider upgrading to a newer version of IE or an alternative such as Firefox. Thanks.

Futzing with Swift and Cocoa

June 6th, 2014

I've never learned Objective C – my iOS stuff is written in Titanium (essentially Javascript, because anyone can play guita.. uh, write Javascript), and my personal tools for Mac are all scripts to run from Terminal. So the idea of a simpler language that could be used for both iOS and Mac OSX is pretty attractive to me.

Problem is, I've never used Xcode, or the Cocoa libraries before. But I thought I'd give it a shot. Based on a few hours of futzing around, here's what I've found – my planned starting point was some button handlers, text inputs, and then some XML file manipulation.

Button Handlers

You can easily drag-and-drop a button onto the window in the Interface Builder view. To handle it, you can add a handler to AppDelegate.swift. First I imported Cocoa and Foundation:

import Cocoa

Then, inside the class AppDelegate:

@IBOutlet var window: NSWindow
@IBOutlet var testButton: NSButton

Then, after the applicationWillTerminate function, add a new function to be called on button click:

@IBAction func buttonclick1(AnyObject) {
  // do stuff
  println("button clicked")
}

You can then link the button to this function from the Interface Builder (it's a control-key-and-drag job).

Text Fields and Alerts

After dragging two text fields onto the window in Interface Builder, I added IBOutlet variables for them:

@IBOutlet var text1 : NSTextField
@IBOutlet var text2 : NSTextField

It's possible to get these – and link them up – automatically by control-dragging the text fields from the Interface Builder into the right area of your code. That done, you can then a value from one field, and put it in the other one:

var fromtextbox = text1.stringValue
text2.stringValue = fromtextbox;

It's easy to display it in a simple alert box:

let myPopup:NSAlert = NSAlert()
myPopup.messageText = "Modal NSAlert Popup";
myPopup.informativeText = "Echo that variable: \(fromtextbox)"
myPopup.runModal()

Because who doesn't love extraneous alerts. Or, if you need an OK / Cancel:

let myPopup:NSAlert = NSAlert()
myPopup.addButtonWithTitle("OK")
myPopup.addButtonWithTitle("Cancel")
myPopup.messageText = "Are you sure?";
myPopup.informativeText = "Do you really want to do that?"
if myPopup.runModal() == NSAlertFirstButtonReturn {
// yes, they're sure.
}

Else, handle the cancel action, etc.

A File Selector

I want to choose an XML file, in order to later manipulate it. I found that I could get a file dialog box like this:

let myFiledialog:NSOpenPanel = NSOpenPanel()
myFiledialog.allowsMultipleSelection = false
myFiledialog.canChooseDirectories = false
myFiledialog.runModal()  
var chosenfile = myFiledialog.URL // holds path to selected file, if there is one

And to check that a file has been chosen:

if chosenfile {
// do something with it
}

Maniuplating XML

Next up is opening, reading and manipulating that XML file. Getting a local file to manipulate it is pretty easy:

let xmlurl = "/var/tmp/file.xml" // or from your file chooser
let nxmlurl:NSURL = NSURL(fileURLWithPath: xmlurl)
var xmlasstring:NSString = NSString(contentsOfURL: nxmlurl);

Once you have the XML as a string, you could feed it into a proper XML parser – but I just wanted to grab a few values, so used some string manipulation using NSRange objects. You can also bust a string that's delineated (in my case a com.something.something GUID) into an array of values really easily:

var substrofguid:NSArray = currentguid.componentsSeparatedByString(".")

.. and then when you're ready to write the string data back to an XML file:

var myfileman:NSFileManager = NSFileManager();
var xmldatatowrite:NSData = myeditedstring.dataUsingEncoding(NSUTF8StringEncoding)
var writethefile = myfileman.createFileAtPath("/var/tmp/file.xml", contents: xmldatatowrite, attributes: nil)

You can then check that writethefile variable to see if the operation completed properly.

Stuff the App Store needs to do..

March 23rd, 2013

The iOS App Store really is a brilliant thing. I first learned to program way before internet access was widely available, so the options for sharing my first creations (in STOS Basic, on the Atari ST), amounted to 3.5in floppy disks – today, if you can code something you can easily distribute it to a global audience of millions. It. Is. Brilliant.

But let's not pretend that the whole affair is flawless. Over the past year or two of working with apps I've been mentally compiling a wishlist of 'Stuff the App Store really, really should do better' – I don't expect Apple to care, but since I'm waiting for a 6GB file to download over domestic broadband, here it is. If nothing else, it could be interesting to look back in another two years and see which, if any, have changed.

Free with In-App-Purchases

The whole reason this list popped back into my head today is the news that, finally, Apple seems to be making small inroads to fixing this long time issue. Many developers – my company, and my personal business, included – make use of a model where a free app can be used to offer paid-for content. My work is making magazine apps where the reader, and some articles, are free but others are paid for. My personal apps offer a limited amount of function for free, with a payment unlocking more.

Neither are entirely free, and I'd never claim otherwise, but the App Store marks them with a big 'Free' button, and that annoys some customers who feel they are being misled. It's bad for them, bad for us (ONE STAR), and not exactly beneficial for Apple. It seems that the company is now marking these apps with a note on the web store view – I really hope it can find a way ('Free App'?) to do so in the main store.

Sort out International Subscriptions

The Subscription concept used in Apple's Newsstand is, well, odd. For one there's the fact that subscriptions are mandatory for Newsstand, and the 'Mandatory Free Subscription' concept that allows free-issue publishers to work around that. But more importantly, the in-app subscriptions do not support geography.

By way of example: say I sell a magazine called Unicorns Monthly. People in, say, Narnia buy auto-renewing subscriptions. I then have to remove the app from sale in Narnia (legal letter from an angry lion) – a process Apple makes very simple. What I can't do is stop the in-app subscriptions of my customers there, so they will continue to be billed. They'll keep getting issues for a while, but if a mandatory update is needed it'll be unavialable to them, and they are left with recurring payments for a product they can't use.

It's bonkers. If an app binary is no longer for sale in a given territory, why not make the IAP subscriptions off-sale in that area, too – that would allow app publishers to wind down support properly.

Buy, buy, sell, sell

Here's a big one: you can't move any app from one account to another if the publisher is bought or sold. This isn't just a magazine thing, but it becomes an even bigger pain in the backside when the apps have subscriptions attached. My team produced four magazine apps with significant readerships – when we set up as an independent company, there was no way to take those apps with us.

The best you can do is set up a new app and close the old one, but then there are hundreds or thousands of customers – many of whom you may not even be able to contact, because Apple subscribers have to opt-in to share even an email address – who have paid for a product that disappears. There are strategies for mitigating this problem (essentially, batch importing known users into a separate authentication service for the new app, and notifying old app users of the process), but it's a horror.

Moving apps between accounts must be a pain for Apple. But I'd pay for the service. Big companies would pay a lot.

No API for data

A minor thing, but there's still no official API for getting app sales data – instead you can use the web interface, third party tools (I like AppViz), or set up CRON jobs to run shell scripts that use a Java autoingestion class provided by Apple (I like that too, because I'm a geek). A proper API, though, would allow for more and better analysis tools.

ONE STAR

And here's the big one. The current app review mechanism allows angry people to quickly lash out at a developer – sometimes with good reason, sometimes not – and, because happy customers are seldom as vocal as mad ones, pushes developers towards 'Why not rate this app' nag screens in order to get positive feedback on the board. In many cases, angry reviewers could be made happy with just one sentence explaining that, yes, they *can* do what they want, by tapping button X, or whatever – but the developer has no way to contact them.

It's a tough one to fix, of course, but here's my two cents: developers should be able to 'answer' any review, positive or negative, in up to 150 characters. This response would be sent, by email, to the reviewer. After this response, the reviewer would be offered the opportunity to change their review rating. Meanwhile, when an App Store user chooses to download another app, they could be offered the chance – while waiting – to quickly star-rate their last purchases.

Sound fair?

Ah, screenshots..

June 18th, 2011

How to take a screenshot in Apple iOS:

  1. Push both buttons simultaneously

How to take a screenshot in Google's Android:

  1. Root the phone
  2. Install Screenshot It (£2.50)
  3. Use that app

How to take a screenshot in Microsoft's Windows Phone 7:

  1. Attach handset to tripod with Blu-tak
  2. Attach DSLR to another tripod
  3. Place the two 40cm apart
  4. Focus camera
  5. Darken room
  6. Adjust camera exposure
  7. Take a photo of the stupid bastard thing
  8. Put photo through Lightroom and Photoshop to fix colours and crop

So in order: simple, a bit clunky but fine if you're a geek, and an unmitigated pain in the arse. Hmm.

How to shop in an Apple Store

May 11th, 2011

Apple Store

For reasons that are complicated, I've recently changed my work computer to a shiny new Macbook Pro. It's very nice (8GB of memory makes everything easier), but comes with a mini DisplayPort connector that's ideal for connecting to displays that do not exist in real life. Adding VGA (still the standard for generic meeting-room projectors) requires a £21 adapter, so today I popped out of the office to buy one.

Fortunately the Regent Street Apple Store is a few minutes away from my office, so what could be simpler than going to grab one from there?

Well, as it turns out: just about anything.

The Apple Store is, of course, lovely. It's huge, light, airy and full of shiny things. The staff are pleasant and helpful and neatly, alarmingly colour co-ordinated in smurf-blue shirts so you can spot them easily. If you want to play with an iPad, or an iPhone, or – who knows – even a Mac of some type, because they do still exist, you can. You can surf the web. You can check your email. You can leave your AOL webmail account logged in for others to muck about with, if you really want. This is all marvellous. Can you buy anything? Well, yeah. But only if you try really, really hard.

The normal process of buying in a shop is this: go in, find object, take to till, pay, leave. In some shops you may have to go in, ask for something, pay, then leave. My visit to the store today – 11.30am on a weekday, with the store not particularly busy – went like this:

  1. Go in. Admire shiny things in a vague way. Look around for where the stuff to buy is.
  2. Fail to find it. Ascend glorious glass staircase. Look around some more.
  3. See area with stuff on shelves. Go to stuff.
  4. Find it is all bloody iPhone cases. Give up. Look for member of staff.
  5. See member of staff not helping customer. Walk towards them.
  6. Member of staff is accosted by other, better, customer. Repeat steps 5 and 6 a couple of times.
  7. Eventually accost staff member. Ask for item. He is very helpful, produces item, then disappears in a puff of smiley Cupertinosity into the morass of tourists.
  8. Walk to till.
  9. There is no fucking till.
  10. Walk downstairs. Perform victory loop of shop. No, there really is no till. Argh.
  11. Consider just giving up
  12. Vaguely ponder walking towards exit with item in order to attract attention of someone, anyone
  13. Find another member of staff. She can help!
  14. Walk to card terminal hidden in corner. She fiddles with iPhone thing. Buy item. Success!
  15. No, not yet. Staff member must fetch receipt from somewhere
  16. Wait
  17. Ponder
  18. Watch people gawk at iPhones
  19. Consider building house of cards using display iPads
  20. Idly paw at iPad
  21. Idly paw at desk iPad is sitting on
  22. Member of staff returns with receipt.
  23. Escape!

So, not much fun, but at the end of the day I did eventually manage to hand over twenty one pounds of not my own money for a dongle. Capitalism, ho!

And, as I stood waiting around for a receipt that could have easily been printed in seconds if there were some kind of fixed location for transactions to be carried out, I realised two things. For one, I'm never going back. Never. Can't stand it. But more to the point: the Apple Store experience was evidently   designed to work in so many ways, and all are handled brilliantly – it's just a shame that "sell products to customers" wasn't one of them.

Apple Store photo by Rodrigo Galindez, used under CC license

A modest proposal..

April 21st, 2011

A quick idea inspired by facepalming at the comments on a Guardian Tech story for the umpteenth time: for any news story regarding the activities of one Apple Inc, it might be helpful to use the following form rather than any generic comments template.


HTML Form Creator