044 iPhreaks Show - Offline Authentication with Peter Kananen

00:00
Download MP3

The panelists talk about offline authentication with Peter Kananen.

Transcript

CHUCK: It’s not a problem for me, my iPhone’s always connected. Except for when it’s not. BEN: When I pull out of my bat cave and launched through the waterfall, I lose connectivity there. CHUCK: Hey everybody and welcome to episode 44 of the iPhreaks Show. This week on our panel we have Ben Scheirman. BEN: Hello, from Houston. CHUCK: Jaim Zuber. JAIM: Hello, from Minneapolis. CHUCK: I'm Charles Max Wood from DevChat.tv and this week we have a special guest, and that is Peter Kananen. PETER: Hi, from Cincinnati, Ohio. CHUCK: Since you haven't been on the show before, Peter, do you wanna introduce yourself? PETER: Yeah, my name is Peter Kananen and I have been a developer for about eight years. I'm actually what you call a project guide; I guess that's the less offensive version of project manager these days at our company. I work at a small consulting [inaudible] called Gaslight and we have made our name mostly on Ruby on Rails work, although we’ve done iOS apps and we’ve done quite a bit of [inaudible] JavaScript development in the last few years. We tend to work with medium-sized companies, helping them build applications that build their business. I've been doing iOS for about four years, maybe five now, I guess starting 2009-ish, so good time doing that. I've been a little less involved in the last year with actual development time, but I've been trying to keep up with iOS and the last paid application I did is really relevant to the topic today which is offline authentication. CHUCK: Awesome. So what do you mean by offline authentication? I have three different guesses and I want to see which one’s right. PETER: The requirement that we dealt with was it’s actually a project full of clichés, because we were actually building a literal bug tracker for literal usage in the field. And in this environment where we were collecting a lot of data – this is for an agricultural application. In the environment where we were collecting a lot of data, cell service is not an assumption that you can make out in the field, literally in the middle of nowhere where at least self-decode or something like that. And the need to record a lot of data offline and possibly a lot of multiple users use the application, essentially needed a way to keep track of user credentials when they're disconnected from the network and then sync back up later with the server side application that we were interfacing with, which is the Rails app that we wrote as well. So for us, offline authentication meant that the user entered their username and password, and they were able to use their application with their previously-stored data that they pulled down from the server and they would be able to pass the device between users, meanwhile they were never connected to the network doing all these things. CHUCK: That sounds pretty handy. BEN: So if they're entirely offline and they’ve never downloaded data, is there – can they still use it or do they have to at least logged in once? PETER: Yeah, they're going to have to have logged in at least once to pull down their data, because the application didn’t really ship with any user-specific data. I suppose there could be some functionality you could expose about an account, but for the client, that wasn’t really a need because they have an established base of customers. This isn’t an app that you download from the App Store and just start playing with. You wouldn’t have downloaded it unless you had a long-term relationship with the provider. BEN: Okay, so there's no chance of you sort of entering a username and password and then we just hope it’s okay for now, and then later on we’ll check it again on connectivity? You just kind of assume that their account is still valid? PETER: Yeah, well that’s one of the big questions, right, is how long should they be able to be offline before you require them to revalidate? What if their permissions change, or they're no longer a valid user? Those are the kinds of questions that make solving this problem difficult, so. CHUCK: So what do you do? Do you store the username and password when they log in in some kind of encrypted file? PETER: That’s usually –. What we did is initially, assuming we have a network connection, we would first attempt to retrieve their stored credentials and we use the keychain for this in iOS, which is usually the best way to go when you do something like this. And this is another decision point: do we attempt to re-authenticate and possibly pull updates for their account using user-specific data? Or do we just assume what they have cached on the device is good enough for now and there's no need to revalidate. Obviously if you don’t have a network connection, you can’t try to revalidate their credentials and pull down any data, but the decision to do that is kind of a tough one, and in some ways you want the user be able to override the default; immediately pull down data they desire, because maybe they know that they're going to get an update even though the system might not be aware of that. There are various strategies you can use in your server. [Inaudible] the server to deal with invalidated data, like a lastmodifiedsince value that you can provide. You can set various headers to show you’re your cache is invalid or something like that. So the happy path would usually be, okay, the user logs in, they pull down data, and let’s assume they're going to be offline for a week. No problem, they can just use data. Everything is stored locally in core data as they, you know, create additional reports, which is what the user is doing here. And then when we find that we have an internet connection, we just go back and send up any data they’ve created, and then pull for any updates that they may need. The edge cases there is what makes this topic tricky, in my opinion. Because aside from – the happy path is not that hard. JAIM: So walk us through the application. So you’ve logged in, you download your data, you're all good. PETER: Okay. JAIM: Now you're in a cornfield somewhere in the middle of South Dakota – how does the app work? PETER: Let’s say you have data about a field, which is geographic data and coordinates, essentially, and you might have some other data about what crop type is there and maybe historical data about past observations. This is like a scouting app, essentially, for agricultural usage. And you go and create a report, you walk the perimeter of the field, the device is recording your coordinates; since we’re using an iPad in this case that has GPS hardware, you don’t need to be connected to the network in order to record any of this information. As the user takes pictures or makes notes about things, we’re just creating a model that’s saving core data of all their observations relative to that field, and then when they go back to the server, they probably get back on that network connection, they can choose to submit the report that they’ve created. That’s essentially the use case for the app. It’s not extremely complicated in a lot of ways, but it gets tricky when you deal with data that’s being pulled from a server that has several different layers of nesting. So you might have a regional-level data, and you have a grower-specific level of data, and then you have fields underneath that growers – so you have this network essentially of, this data that needs to be all pulled down together, because the relationship between these entities is really important. The data size in these cases wasn’t huge, but once you throw a couple thousand objects in core data and start mapping them, it can be a little more interesting there. Choosing how to update that data is kinda hard; you can attempt to do deltas, but if an object at the lowest level is dependent on another object there, like kind of it has many relationship or something, that object in the middle goes away, that you have to blow away essentially all of your local data. I know there's different merge strategies you can employ here, but we choose usually to go with a – if you wanna do an update where it’s going to blow everything you have away and start from scratch, so. JAIM: Okay. Sounds like more of what you discussed is not necessarily authentication, making sure the right user is using it, but what to do after the user comes online. You get all this data walking around the corn field, now you're online – is it more of a sync problem? Am I getting that right? PETER: Yeah, it is kind of an offline data sync strategy and there are some really cool enhancements added to iOS in the last year, too, that are supposed to help with this. Unfortunately, at the time when I spent most time developing the app, it was still really early for things like IncrementalStore to be used. Like you mentioned, offline data to me was one of the harder issues, but authentication itself really was just – we’re going to store the token and then we’re just going to reuse that token the next time we get on the network and are able to submit information. Maybe the other panels would have some more unusual use cases for offline authentication and any issues they encountered. But I didn’t have that many just with the authentication part. I did complicate my life a lot when I made a mistake in my server side authentication logic and I gave an invalid token to a number of users and that actually turned out to be really tricky to get rid of the bad token on their device. And actually, this concept of – there's almost this concept of versioning that I encountered when I was trying to implement this offline authentication logic and that might be a more interesting topic to talk about as well. So any other experiences on how you’ve solved this problem for offline usage of an application for users’ account? JAIM: I have a similar anecdote, and to go with it, sort of a hard lesson learned. One of the projects I worked on a few years ago, we’d store a lot of data, GPS data, and at the end of a trip, you would submit the data to the server. We would do some number crunching on the server to basically analyze the trip. It wasn’t so bad for my drive from home to work, and then I would work on that data and it would all work. The idea was just like a simple Rails controller action, you would submit an array of waypoints and the name for the trip. And the server would save it into the database and compute the score, and then return the score back to you, and other things that we’ve determined based on the analysis of the trip. So that worked fine; but turns out that truck drivers started to use this app and they would drive from Florida to California, all tracking the data, and they would all go in one big file – on disk. And so then when we went to go send it, that post would end up taking longer than – I think at the time, Heroku had a 30-second timeout for processing a web request, and we didn’t do any of this stuff in the background at that time, which was lesson learned number one. Because of that, some of them would actually get stuck in the processing phase after they had been saved in the database, but before we returned their result to the client. So the client, being smart and wanting to handle low network conditions, would just say, “Oh, we got an error. I'm going to submit that one again next time.” And so we got just loads and loads of duplicate trips. And to make matters worse, the timestamps were based on when you submitted, and so it was not trivial for me to detect the fact that there were duplicate trips, especially since it would [inaudible] on to the same file. So there is a number of problems there, but one of the biggest ones, I think, is to generate IDs on the client side so then I could detect whether or not you're trying to submit the same trip twice. CHUCK: When you said that it would take more than 30 seconds, I thought you were going to say it would take longer than it took them to drive that distance. JAIM: [Chuckles] Yeah, I mean it’s kinds of a similar scenario where they're collecting a lot of data; we don’t want to hammer their network in the entire trip, and so we’re just collecting it into the end, and then we zip up that file and upload it. But then, Rails has to do something with it and what we should have done is accept the files and say, “Okay, we’re processing it” and give them back a token that they can go back and look at the trip, at the status of that trip. And then we could just process it in our own time and update the record when we’re done, and they could just pull for the status. CHUCK: I'm kinda curious if you have multiple access levels? Do you tend to manage all of that in your iOS app or do you do some kind of management on the back end? You know, the data service or whatever. Because it seems like you would need it in the case of doing offline authentication especially, or even just making the application responsive enough, given the data is already there on the application. Does that change any of the parameters of your offline authentication? PETER: I suppose it could. I didn’t have many varied levels of user permissions; everything was essentially controlled via the data that they have access to. So that was definitely one challenge. Let’s say that the user has access to a certain set of data, they pull the data down their device, they are offline; meanwhile, they lose access to that data’s server side, and they no longer have the account permission and there's a much more robust permission system on the server side app – in this case, Rails app. And then later the user creates data based on this invalid data they don’t have access to anymore. Let’s say it’s an account that they no longer are working on, and then they submit a report for that account. Well the server’s going to have to check to make sure that they no longer, make sure they have access to that, and oftentimes that kind of permissioning wouldn’t be built into your Rails controller that you would use if you're just serving up a Rails view, because the assumption is I was going to have access to data because I'm running this browser request response cycles here and it’s not like I'm going to lose access to the stuff on that 30-second timeline like I would if I'm offline for two weeks. Most of my user permissioning was really at a data level that wasn’t directly controlled. JAIM: I think it’s really important to make sure that it absolutely has to be on the server, right? Like if somebody were to not use your client and use their own homegrown one to hack your service, you still have to have that level of data security on the server. But like you said, you can’t just check at any point in time, ‘do you have access to x?’ and so I think it also, in this case, needs to be in the client so that you can –. If there were such a requirement to say, “Okay, you can’t edit this field.” And let’s say, somehow, due to a bug in the software or a malicious user who can jailbreak their device and go edit stuff in the application itself, once they go to submit that data, it should be able to validate it. “Yes, the data that you submitted is still valid. Nothing was tampered with.” Either that or we just reject the things that we’re not allowing the user to write. CHUCK: How do you keep those permissions in sync? That’s a much easier question to ask, I think. JAIM: [Chuckles] I don’t know. In a lot of cases, you can just punt in web apps and say the server will catch it. For instance, like username uniqueness validator. Almost every website will have a form, you type in a username – it’s so easy to write an ajax request that just checks the validity or uniqueness of that username, but then you also have to check again when you submit, right? So that one’s like a quick win, so it doesn’t matter so much to keep that in sync. If the rule’s more complex, I think it’s perfectly acceptable to just punt and let the server handle it and return an error, right? But in an offline scenario where you're going to be disconnected for a period of time, where you're not going to know if the data you're entering is invalid – think of the pain that that might cause the user if they were supposed to be entering in values in Fahrenheit instead of Celsius or whatever. What do they do at the time when they're trying to submit all these reports? Do they have to go back and correct them, write them an error, like that? To me it seems like it’s worthwhile for the user experience to keep them in sync manually. PETER: Yeah, this is the harder topics to address. It’s almost not as much of a technical challenge, although that can be the case; it’s almost more like an implementation – how much do I value this thing over this thing, and what is user experience here, and do I want to lessen user experience and create an easier to implement permission system for validation of this data. One thing that we did in a few cases is we attempted to use a hypermedia approach to the service that we we’re talking in the Rails end, where the response would indicate to the client the next actions that it could take and [inaudible] build a very primitive state machine into the HTTP responses. And that way, the client should never be confused as to what actions it can take next. It takes a lot of work to build this correctly, but the idea is you don’t want to end up in the situation where a user feels trapped on their device; they can’t solve the problem that they're in, which might be data that goes missing that is no longer available for them to see. This happened to us when we actually – they would go to the server, pull down the data, they would lose access to some of the information or some objects or entities that are no longer valid to them, but data they’ve created based on that old version of the data model is now lost. They don’t have access to see it, and it’s actually trapped on their7 device. This is a really unfortunate situation to be in, and that did happen to us, so. Those are kinds of considerations you have to make. JAIM: So we’re talking about hypermedia; kind of walk us through exactly what's happening. You're talking about having your service actually become that, they could call it the engine of the application state – what does that mean for when you make a request? How is a response or a request different? PETER: Well first of all, I am not an expert in this stuff; I'm just dabbling in a little bit. The idea is that the response you receive as a client should indicate to you what things you can do with the response. For example, it’s going to include URLs that are relevant to the data you receive. I get a list back of all these things, and each of the entries includes a URL for showing them, like a show URL, the simple [inaudible]. And then perhaps how much you post back or how to create, and the idea is that you – it’s a more robust way to build a client-server relationship, or any application that kinda has several different clients talking to it. This can be applied to web app as well. If you’ve ever dealt with multiple teams building different clients that interact with the central application, or central services like a web service, these kinds of systems, when you build this according from the beginning, makes a lot easier to –. It’s almost like built-in versioning and knowledge, and intrinsic knowledge about what valid things you can do with the application. BEN: That’s very cool. So basically you're getting back a set of links to different URLs, so if you're trying to upload data and you no longer have access to that because you’ve moved on to a different project, one of your responses would be a different URL that might show you information, saying you have this error conditions? PETER: Yeah, and like I said, I'm not an expert in this topic. I would recommend that you read about hypermedia and this idea of, I believe it’s called HATEOAS. And this is like using HEDP as the engine of application state, and essentially treating HEDP as an API. It’s interesting; I will tell you more about it and I've used it in simple cases to store and retrieve information about certain entities that user might have access to editing, but I haven't built an entire application around these principles. BEN: Okay. I've done some work kind of creating iOS with, creating a web service and done it with iOS, and I found it very powerful – at least for the application we were doing. We were doing kind of a search engine, so instead of returning just a blind filter, we would return, ‘Oh, here’s this genre of music. Here’s this genre of music. Here’s something you can search next.’ So if you search for [inaudible] ring, we would also return URL for your next search. It’s kind of going into the weeds of hypermedia, but it’s definitely doable for iOS, and actually a very good way to write your APIs. PETER: So how do you handle cases where, similar to the one I described earlier – a request maybe failed halfway throughout and the server maybe received the data, but the client thinks it hasn’t sent it yet or maybe encountered an error? BEN: Generally, you mean it kind of becomes part of your domain, so you have some work flow. You sit down – what actually happens in this error case and –. PETER: So I mean, if you think about an endpoint where you’re going to add a new report, like submit a brand new report, versus updating an existing report? Those will be two different endpoints – one’s an insert and one’s an update. And so if you continue to call the insert, it’s because you think it’s brand new. You run into issues there, right? BEN: Right, yeah. I guess I don’t fully understand. A lot of times it comes down to just fully flushing out what happens in different error cases. PETER: And so if there is one, maybe you just decide that those two endpoints are the same, like submitting a report or submitting a report, and it will later insert an update, the existing report is there. One of the techniques of generating IDs in the client side can help alleviate that, because then you would know that, hey this one already exists. JAIM: I think the more restful way is you'd probably – you got your resource, your report, and you create it by creating a post, and you'd probably get back your ID, your URL for the new resource, whatever it is. And then you can a do a PUT up to that so the server would give you your ID and then you'd respond a second request that actually uploads the data using a PUT that would go to that ID. [Inaudible] BEN: It does; I think you could do that in one step where you have – the server just does the check for you and says, ‘Okay, we’ve already inserted this one, so I'm just going to give you the location of the existing one’ and from the client code it doesn’t matter if it was a brand new insert or it was already inserted but you just didn’t know about it so I'm just going to give you a thumbs up. JAIM: It could be if you're inserting data, how do you know it’s repeat? BEN: That’s why I say you should generate an ID on the client side. Did you do anything like that, Peter? PETER: I'm trying to remember how we handled that. Because we were creating core data objects; we were using RestKit which helped most of these mapping problems, and there's a way to when you receive responses back from your Restful service to tell RestKit how to map attributes you get back to values in core data so it doesn’t recreate them essentially. So how does it know if it’s a duplicate versus a new one, or an existing one or new one, and the new entity or existing entity in core data? Well, RestKit helps you to do that with an identifier property or something that you set. I don’t think we generated client-side IDs that we would use in Rails, although we did have a core data ID, and there might be some logical key that you can – like a computed key, almost – to know how to say, ‘okay, I have this particular object for this parent record on this day, so that should be mapped to this.’ I think that’s how we did it, but I could be wrong. BEN: I'm a fan of using natural keys where they're truly, truly unique and always present, but turns out those are kinda hard to come by. Somebody might say, “Oh, we’ll just use Social Security number.” Turns out that not everybody has one of those, you know? JAIM: And they're typed wrong. BEN: Yeah. [Chuckles] I am a fan of using logical or natural keys when you can get away with it, for sure, rather than relying on a [inaudible] or something. I think using some sort of key like that you at least it saves your app from inserting the same data twice. JAIM: Yeah, if there's some client-specific key. It kind of weirds me out too, to have a client create the key that a server uses as its unique key, but if a client has its own [inaudible] field, you can make sure that you're not having duplicate data, I think. That’s reasonable. BEN: Yeah, I mean, it doesn’t have to be a priority on the server. It’s just a field that is unique in the database and the client generates it, so in that way you can easily check. What about – I don’t know if this was a case for you, Peter, but if you allowed this to exist on multiple devices at once, are they editing the same report so they're creating new reports? Is that report maybe tied specifically to that device? If you could edit them on different devices, then you run into the problem of conflicts arising when you finally get back to the office to sync up. PETER: Thankfully, once you submitted a report from your device and it was received by Rails, no more edits can be done in the device for that. That greatly simplified that particular workflow, so you really can have a report in progress by more than one user, and that report, it’s only local to that device. Once it’s off the device, then it’s no longer editable. That could save us a lot of work, because that’s a hard problem to solve. I would really be interested to know if someone has experience with IncrementalStore. [Inaudible] that’s holding up in a production environment, because when I was evaluating it for usage in this project, it was, “Oh, it doesn’t do several of the major [inaudible] operations yet,” which, obviously, was a deal-breaker for me. BEN: Yeah, I've only played with it similarly, just evaluating it. While it’s technically really cool, there was a whole lot of magic that I didn’t understand and a lot of times that’s the stuff you need to understand in order to fully extend it to accommodate your use cases, so I have never used it in production. PETER: Okay. I'm interested to check back in on that one, because it seemed like NSIncrementalStore really was designed to solve a lot of these hard problems, and other frameworks like RestKit, with the core data support, they got you close to there, but it still is hard to piece together information that is possibly incomplete and possibly in conflict and to keep that in sync across core data on multiple, possibly thousands of iOS devices, some of which are not online all the time and your central database – that’s a hard problem to solve. BEN: I did see Jonathan Penn’s NSIncrementalStore presentation at Cocoa Conf, which was fascinating and kinda terrifying at the same time. His use of it was mostly, I think, to demonstrate what you could do with it. In his case, he was storing lots of plists for the records, and so just kinda like deconstructing NSIncrementalStore and learning a whole bunch of stuff about core data along the way that you probably never wanted to know. So it’s definitely like a technically cool topic. It certainly requires that requisite amount of investigation and prototyping to make sure that it does work for your use case. PETER: If it’s okay, I'm going to back up a second and talk a little bit about the keychain and its role in this. I kind of oversimplified, because it’s not usually hard to deal with. So keychain services is provided by Apple for usage in OSX and iOS apps. I've never used it in OSX, but I understand that almost all of us have used it, and there's a master key that allows you to essentially access a bunch of stored passwords or other tokens and things like that. In iOS, each app has access to its keychain without the need to unlock anything. This is really just because iOS supports apps sandboxing, and it actually requires it. So you don’t even need to enter a password for an app to access the keychain. I think keychain services is a C-API; I've never actually interfaced with it itself, I've always used a wrapper, and I've used one that used to be called SFHFKeychainUtils and now it’s STKeychain, which is part of STUtils by L.D. Anderson on GitHub, and that provides an easy way to store items in a keychain and you can associate them with a username and a service name, I believe, so you could potentially store a couple of different values for a user. What I ended up doing was I created a category that essentially made up – I used the system of creating service names based on particular needs. So if I had any of the tokens for more than one service, I would just create a different service name for those things, and then name the category method appropriately. I also used the service names of this framework [inaudible] library supported to essentially invalidate offline data. I supposed you could lock some of this out at the service-side level, but let’s say the user has a token that they’ve received a web service that provides them access. In my case, I ended up with a situation where users have a valued token; the only problem was it was not their token and it was really hard to figure out how to make them stop submitting reports as the wrong user, because I've never built into the –. BEN: The site’s really bad. PETER: Yeah, it is really bad and I can’t put logic in my controller to say, “Oh, if you're this user, you really should set your username to this, because it could be the invalid person doing this.” It really all came down to a bug in my find or createuserby method and making assumptions there that were incorrect. So what I had to was when I shipped the next version of the app, I created another version in my service name, so that I wouldn’t try to pull the wrong token anymore out of the keychain. And actually, and I should’ve dug in the keychain more because I didn’t find a lot of good support for deleting values. You can remove them – I think you can remove for a username or for a service name, but I know there are some limitations with the [inaudible] that I was using to do that. So I ended up creating a version of the service name essentially so I could store these credentials and invalidate them accordingly. So if anyone has any thoughts on how keychain works and what best practices you should use, I'd love to hear them. BEN: I've used a lot of the similar auth tokens-type API access where you store a username and a password in the keychain and a temporary auth token, and the idea is that auth toke is a potentially vulnerable piece of data where if somebody gets a hold of it they can impersonate you forever. And so I like to make my auth tokens expire, kind of like every once in a while your credit card company sends you a new credit card, so that if one ever gets out you sort of limit the ability for that to cause problems. In addition, you can, at any point in time, cycle somebody’s auth token and hopefully their experience doesn’t suck when they try to submit some data. The way I've handled that in the past is when they type in their username and password, I save that in the keychain also, but in transit, obviously you're only sending the auth token for authenticated requests. If I ever get back an auth token expired or invalid, call from an API request; it’ll be like 401 unauthorized or something. And I’ll inspect that, and if it’s the one that I'm looking for then I will hang on to that request and instead make a log in call for a new auth token using the saved login credentials and get back a new auth token. And once I have a new auth token, I’ll save it and retry the original request. So the idea is that the user doesn’t really know this is going on, and if that login request fails, then of course at that point something bad has happened, and that user probably doesn’t have access anymore. So I'm not going to continually try to re-login – I'm just going to try that once, but if it does work and I get a new auth token then I can retry that original request and do that without the user having to push the button again, which I think is a really good user experience and it provides a decent level of security and the ability to revoke auth tokens without adversely affecting the user experience. PETER: That’s actually really similar to the workflow that we used as well, where we would have the username and password stored in a token, and if a token expired, or some other problem occurred in maybe validation of a server, then we could attempt to login for them and acquire a new token and resubmit data, and hopefully all they see is just a little bit of spinner activity while all of this is happening. CHUCK: I have a question and that is, if you are offline for a long time, sometimes the app gets out of date – do you wind up having to maintain some backward compatibility both in your API and possibly your database schema on the back end in order to accommodate that? BEN: That’s the bane of my existence. [Chuckles] I don’t even think that really has to do with, necessarily offline apps. I think people, in general, if they're not on iOS7 or if they haven't updated their automatic updates feature, we still have plenty of requests that happen through our old versions of the API and as we wanna make changes and improve things and write previous wrongs and things, it becomes somewhat annoying, because you have to still accept all of the bad data that you used to get. Not bad, but in a different format, and then handle it in a new way if it’s in the new format. PETER: Yeah, the [inaudible] of data migrations was frequently discussed around here, and coming from Rails core data, it’s not quite as simple as it was in Rails to do migrations although it’s possible. Apple does provide support for it; it’s just usually not as seamless in my experience. BEN: I mean, if you add a new column, or a new attribute to an entity, or add a new entity, those things are usually fine. If you changed the type of column, then I think you're kind of – toast is not the right word, but [inaudible]. JAIM: You'd have a bad time. BEN: Yeah, you can have a bad time. You have to create the new model in a standard way and then connect to the old model and copy the data over the new model and then delete the old model and rename that one back to the original file name or whatever. I'm not sure exactly these migrations go, but. CHUCK: I think the official term is data gymnastics. So anything else that we should bring up before we get to the picks? JAIM: I think we just skimmed over five episodes worth of stuff. BEN: Offline authentication, sync, hypermedia, core data migration. PETER: Those are some of the harder problems that I was trying to figure out the answers to these things, and oftentimes it involves discussion with the client like, how much do you value someone being able to just pull their updates or do the delta and get the three things out of chain, versus sitting there for five minutes and loading in thousands of –? We were loading a lot of Wicket data, which is this well-known text representation of geometric shapes for plotting on maps, and we were like, how much d you value sitting there for five minutes waiting for it to load, versus being able to get the three things that have actually changed? Because it’d be a lot easier to just pretend it all changed and just download it all. So it required a lot of user experience thought, and that’s the value of implementing this feature versus the amount of work it takes, the complexity that adds. Because this topic, when it was first discussed as a feature, “Oh, it’s not that hard. We’ll just keep everything in core data like it is and then we’ll just have to check for this one thing that made them change when they get back online.” Then it turns out there's all this edge cases you need to assume, or need to consider when you're building [inaudible]. It’s a nuance topic and it touches a lot of other functional areas of the application. CHUCK: Alright, well let’s get to the picks. Ben, do you wanna start us off with the picks? BEN: Sure, I've got four picks today, two of them are games. I have been losing lots of time to this game called Threes. It’s an insanely addicting puzzle game. You’ve probably already heard of it, and maybe have already played it. where you combine tiles of given numbers together so you can only combine a one and a two to make a three, and from that point on a three has to merge with another three, a six has to merge with another six. The idea is the whole board moves at a time, so you can go up, down, left and right, and the tiles all move together, and so you wanna collapse things in groups if you can. The scoring is sort of exponential as well, so the higher numbers you get, the way higher the score goes. Anyway, it’s really addicting and I kinda suck at this game, but it’s fun. So check out Threes. Another game that I've been playing recently is Hearthstone. It’s a game by Blizzard that uses the world of warcraft lore and it’s kind of a fun, interactive card game. Right now it’s free during their open beta, and this is going to be eventually an iPad app and it’s just a lot of fun; I've been having a lot of fun with that. Another one related to the topic today is Steward Gleadow’s talk at Cocoa Talk in Boston, I believe, No App is an Island. And in it he talks a lot about the Rest style, hypermedia design of APIs for the purposes of consumption in a mobile device in order to make the mobile device a little bit more robust to changes and not so tightly coupled to implementation details of the server. My last pick is a beer pick. I had one from Utah, actually. It’s Detour Double IPA by Crooked Line, I believe is the name. Anyway, it was super potent and very tasty. So I will put the link to all those in the show notes. CHUCK: Awesome. Jaim, what are your picks? JAIM: Alright, I'm going to go with two picks. Because we kinda skipped over the hypermedia stuff, I just wanna point out a couple of resources that kinda helped me when I was trying to figure this stuff out. One is a book called Restful Web Services, and it’s pretty old – I think 2007, or something like that, but it’s really one of the earlier descriptions of how to write hypermedia, what rest is, how to use resource-based, how to do hypermedia – by Sam Ruby and Leonard Richardson. It’s a really solid book; I've gone through it, it took me, I think, twice through before I actually started absorbing the content but [inaudible] move beyond kinda simple web service design; it’s a really great resource. Secondly, a more recent thing. If you’ve drank the koolaid, the Rest koolaid and you're like, “How do I create a hypermedia API?” There is a specification called HAL. I don’t actually remember how it’s called, it stands for HAL – Hypertext Application Language. It’s very simple, most of the languages that you're probably thinking of using have a library for it, but it’s actually fairly simple. You would be able to write your own kinda library, but just a basic way to organize your responses into links, resources and things like that, so I would recommend HAL. Those are my picks. CHUCK: Awesome. I've got a couple of picks also relating to hypermedia APIs. Steve Klabnik – he’s a fairly well-known Rubyist – but he has a book out on designing hypermedia APIs, and that's at designinghypermediaapis.com, and that’ll be in the show notes. Also, we did an episode with him two years ago back when hypermedia and rest were kind of defining themselves as different from each other and so that one’s called REST Done Right. It’s on rubyrogues.com, I’ll put a link to that in the show notes as well. We’re also going to be interviewing Steve in a few weeks in the JavaScript Jabber show, so you can get updated information on what hypermedia is and what it means there. And finally, I've almost finished this basic economics book, it’s by Thomas Sowell. It’s an awesome book; I've been listening to it on Audible, and the narrator’s pretty good. But if you want to get a real handle on how things work at large in the economy and what some of the incentives are for people to do certain things, and why politicians on both sides of the aisle are wrong and in a lot of cases really just doing what will get them reelected as opposed to what will really help us out, then I highly, highly recommend this book, and so I’ll put a link to that in the show notes as well. Peter, what are your picks? PETER: Well first of all, I also have been listening to basically economics in the last six months or so, and it really did kinda pull back a little bit on the idea of unintended consequences of what sounds good in theory can have the opposite effect in practice, so really interesting stuff. My sole pick is SmartThings. SmartThings is an home automation platform, I guess. I think it started from a kickstarter campaign a couple of years ago, and it has since launched as a platform that is, I found, to be very developer-friendly, and you can buy a hub for 99 bucks. And right out of the box you buy the hub and any of your iOS, and I assume, Android devices – you can register those as proximity sensors for the hub. So you can buy one for your office and you can see, you log in to SmartThings, you install the app, and you can see it right there like who’s in the office, who’s not, and then you just start adding sensors. It’s compatible with most of the z-wave and zigbee sensors and anything that goes on Wi-Fi will work on it too – not anything, but most things are. So you start adding motion sensors, and switches, and dimmers and garage door openers. You can add cameras and motion sensors, or the accelerometers and you can start to automate your house, or your office. Ans it’s a really clean interface, it’s really friendly for us people who wanna write code and build things. One of the nice things about it too is a little bit on the opposite end of the spectrum from buying it or do we know, and wiring up the centers yourself. Once you’ve done that once or twice, and you realize how much work it is to actually build something that’s really complex, you'll really appreciate what some of the SmartThings does for you. They do have an IED – it’s like a web-based IDE, and you can publish your – they call them smart apps, that you can kinda plug and play these devices and wire them up to do all kinds of cool stuff. It also works with If This Then That, so I think it’s really fun to jump into that stuff. I've started to do it with my house, and I would highly recommend SmartThings. JAIM: Now, it’s a very cool tech. Those were Minneapolis guys that did a lot of the tech stuff for that. PETER: Yup. JAIM: It’s very cool. CHUCK: Minneapolis makes everything cool, doesn’t it? JAIM: It does. It’s so cold here, you gotta stay inside and build stuff. CHUCK: [Chuckles] PETER: You know I was actually born in Minneapolis, so I guess I’d agree. JAIM: There we go. CHUCK: There you go. Alright, well, we’ll go ahead and wrap this up. Thanks for coming, Peter. PETER: Yeah, it was great to be here. BEN: Yeah, thanks. CHUCK: We’ll catch you all next week.

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.