renewing ACAccount credentials on iOS

An iOS 5/6 device can have system-level Twitter/Facebook accounts that become disassociated from the underlying service accounts. This means that the ACAccountStore framework will return you ACAccount objects that can be used to sign requests and get access tokens, but NONE OF THE REQUESTS WILL WORK and you’ll get MYSTERIOUS OAUTH ERRORS and LOTS OF SUPPORT MAIL and be GRUMPY because it WORKS FOR YOU JUST FINE.

I’m not certain how to fake this state. Changing your Facebook password and choosing to log out other devices is pretty reliable, albeit really annoying if you actually use Facebook for anything. Likewise, changing your Twitter password might work. I think restoring the phone from backup will also cause this problem, especially if it’s a iTunes-based non-encrypted backup, because the passwords aren’t saved, but the phone won’t prompt you at any point to enter them again.

When this happens to Twitter account objects, I see server responses to otherwise perfectly reasonably signed requests with the error Bad Authentication data and the error code 215. I used to get This method requires authentication when calling the old 1.0 API, because the 1.0 API interprets a bad signature as no signature (REALLY ANNOYING), but the 1.1 API is a lot stricter.

When this happens with Facebook, I see Error validating access token: The session has been invalidated because the user has changed the password and sometimes Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.

The solution to this is the method on ACAccountStore:

- (void)renewCredentialsForAccount:(ACAccount*)account

From the docs:

For Twitter and Sina Weibo accounts, this method will prompt the user to go to Settings to re-enter their password.

For Facebook accounts, if the access token has become invalid due to a regular expiration, this method will obtain a new one.

If the user has deauthorized your app, this renewal request will return ACAccountCredentialRenewResultRejected.

Calling this method on the ACAccount object you’re trying to deal with will make-or-break it. I find that the token either works afterwards, or doesn’t, but now it doesn’t work because the iOS device knows that it doesn’t have a valid token. You may still have to punt the user into the Settings app to fix it. For instance, in the case of Twitter I find that calling renewCredentialsForAccount will pop up a system dialog about the problem.

Facebook is more subtle – the ACAccount object can still be used to get an access token, but that token will fail on the server with The session has been invalidated because the user has changed the password still. However, punting them manually into at this point will ask them for a Facebook password and things will work afterwards.

Alas, it’s asynchronous. You can work around that. Call it on the ACAccount instance before you try to do something serious with it, or do work in the callback.

I hope this helps -someone-, because it sure would have helped me 6 months ago.

Programmable twitter clients

Dave Winer wants a programmable twitter client.

Unix had a shell language. DOS had a batch language. Lotus 1-2-3 had its macro language. Emacs is a programming tool as much as it is a text editor. We have gotten out of the habit of making programmable end-user products, but they are still just as important today as they were a couple of decades ago.

What if there were a relatively simple and low-power programming language built into a Twitter client that allowed power users to build their own little apps on top of Twitter.

I have a few thoughts about this. Firstly, I think the reason lots of apps don’t bother packaging a programming language any more is that programming languages are better now. The DOS batch language is horrible compared to Python. Or even Perl.

Secondly, Twitter has an API. It’s a really really easy to use API. There are clients for it in lots of languages. A unfollow-for-24-hours app would not be difficult to just write.

But more importantly, I have a programmable twitter client. Shelf already asks Twitterrific about the currently displayed tweet so it could display other data about the user. I could do this because just about every application on my preferred platform is already programmable.

Twitter timeline

Yay twitter. You launch a small fun social chatter app. It falls over during WWDC, hillarity ensues. You gain an adorable downtime mascot! Next WWDC, you’re better, things stay up. Much handwaving happens about business models, never goes anywhere. Spammers arrive – you must be a real web service! Yay!

US elections happen! Major political parties use Twitter to do.. things. You start appearing in major newspapers. Every company suddenly has to have a Twitter account. Hardcore userbase grumble about how people aren’t using twitter ‘properly’, it’s just microblogging/broadcast. Noone notices them because their grumbles are buried under the firehose. You turn off some features, tweak others, there’s a little grumbling, noone actually stops using it. Future looking rosy! Though that might just be the burning servers.

Then the State Department asks you to move downtime to not clash with elections. Today, you’re a tool for Iranian propaganda.

Personal thoughts on this.

a. Twitter are a lot bigger and more important than I thought they were, apparently.

b. If I worked there, I’d be terrified.

Twitter is useless

as archival systems go, Twitter is beyond useless – the shift to the infinite-page ‘More’ button and the complete lack of any sort of dated archive mechanism means finding things you’ve said in the past is almost impossible

Hmmm, suggestion. Twitter is as popular as it is exactly because archiving is useless. It’s so shitty that it almost approaches an actual conversation in terms of forgetteability and deniability, and this is valuble.

Of course, it only feels like that. Things are hard to find if you’re looking for them, but not actually gone, so we have things the dangerous and nasty way round, rather than the useful-to-monkeys-with-overdeveloped-social-lobes way round. But it feels safer.

Am I supposed to read all these twitters?

This morning I had to page back twice on to read all the tweets that had come in overnight. I don’t normally do this, normally I just read whatever twiteriffic gives me, and ignore everything else, but I was looking for a specific one. But am I expected to have read them? Are people going to assume that I’ve seen everything they’ve twitered? I do enough catching up in the mornings already without having to remember what the most recent twitter I’ve seen was and paging back till I see it.