I’ve been so busy I forgot to post that I shipped an app. Check it out! thredz.myndarc.com
Parse’s Local Data Store
In my (forthcoming) app Thredz, I used Parse.com as my backend database. In my initial build, I used network calls to Parse to populate the 3 tableView controllers of (1) people (2) clothing brands and (3) clothing sizes.
This presented 2 problems (1) too many network calls and (2) bad UX where the user doesn’t have an available network connection.
Parse’s SDK provides for a Local Data Store, i.e. the ability to “pin” things to a local database on the user’s device: http://blog.parse.com/learn/parse-local-datastore-for-ios/.
To implement this, I wanted to kick off a network call to Parse.com to get the user’s data in my App’s App Delegate class, then cash the data locally into the Local Data Store. Then within my tableViews, I would work with the local data store objects (and not need to call the network over and over). Finally, I would sync, i.e. save the updated local data store objects back to Parse.com when the app enters a background state.
All was going well, until I attempted to work with the .Delete method inside my first tableView. It appears that Parse’s SDK is a little buggy here as unpinning objects doesn’t seem to work, see here: http://stackoverflow.com/questions/29465802/parse-unpin-does-not-remove-object-from-local-datastore/29834767?noredirect=1#comment52557315_29834767. No matter what I tried I couldn’t get the object unpinned when the user deleted the row.
I can’t really think of a way around this yet, so I’ve delayed implementing the Local Data Store until I can figure out a suitable solution…but other than this hiccup, it’s a great solution for developers looking to bring the highest quality UX posssible….
How Far We’ve Come…. (queue Matchbox 20)
February 26, 2015 I devoted myself to learning Swift and IOS development. As I’m getting ready to ship my newest app Thredz, it occurred to me how far I’ve come in only 7 months. When your head is down everyday churning out code, you don’t realize the forest from the trees, but I’ve certainly learned a lot.
Thredz will be my 5th app in the store…and looking at my source code from my earlier apps the difference in the quality of the code is immediately apparent. 😳 And yet, I know it needs to get better and there’s still so much I want to learn. I thought it would be good to stop and take a minute to document the things I feel like I’ve grasped pretty well up to this point, as well as to think about what I’d like to learn next:
What I have a good handle on:
- UIKit basics e.g. UIViewController and UIView subclasses
- MVC Programming Architecture
- Itunes Connect and the Developer Portal
- App Review & Apple Guidelines/HIG
- Persisting state using Singletons
- Storing data via NSUserDefaults
- Storing data via the Parse.com framework
- Log in/sign up through Parse.com and Twitter APIs
- UITableViews
- Watchkit 1.0 and communication between iPhone and Apple Watch
- Implementing In App Purchases & StoreKit
- Source Control and Git
- Some asynchronous programming/Grand Central Dispatch
And the things I want to dig into soon:
- Unit Testing
- SpriteKit and GameKit
- Core Location
- Core Graphics and Animation
- Protocol Oriented Programming
- MVVM Architecture
- Spending more time learning functional programming
Hopefully in another 6 months I can look back at having conquered these topics as well. Onward!! 🏃
Open Beta for My App Thredz! 🎉
I have an open beta for the app I’ve been working on called Thredz. Thredz lets you keep track of clothing and shoes sizes of different brands. Thredz has an Apple Watch app as well. Sign up below if interested or just email me at gary@myndarc.com
Simple Tip: Enable auto-capitalization of words for your users
I was working on an app recently, and in testing…it annoyed me that I had to manually capitalize the first word of the text I was entering. I researched and BOOM!
theNameofYourTextField.autocapitalizationType = UITextAutocapitalizationType.Words
👊
Passing Data to Apple Watch before WatchOS 💀🔫
I’ve been working on an app that’s both an IOS app as well as an Apple Watch app. Because I intend to ship prior to this fall, I really haven’t delved into WatchOS much yet and have been programming using the old watchkit sdk.
While in WatchOS, I think we’ll be able to make network requests etc. from the Watch itself, for now the Watch is still just a screen to project data from the iPhone onto.
My app is using Parse as a backend. After working with Parse pretty extensively over the past few months I’m really impressed with their product (more in a later post). I’ve gone through several iterations of strategy to program the Watch component:
(1) I first started trying to use Parse’s local data store. Per Parse, this is supposed to be a new addition to the SDK: http://blog.parse.com/announcements/introducing-local-data-sharing-for-apple-watch-and-app-extensions/. However, they really don’t provide any documentation that I could find at least as to how to pass the data. I couldn’t really find anyone who has used this either: http://stackoverflow.com/questions/31551505/parse-local-data-sharing-for-apple-watch so I abandoned this idea for now.
(2) I know that trying to make network calls from the Watch via the old SDK is a non-starter due to performance issues, so my second thought was that I could use the methods of OpenParentApplication and HandleWatchkitExtensionRequest since the iPhone is making the network calls, not the Watch. (Natasha The Robot goes over this well here: http://natashatherobot.com/watchkit-open-ios-app-from-watch/).
Coding this was pretty horrible…because I’m using Parse and it’s PFObject subclass, AND my data model is 3 layers deep (i.e. [String : [String : [String : String]]]) that populates 3 WKInterfaceTables in the Watch app, I had to key value code it so that (1) I passed back to the parent app the current user (again, can’t pass back the current user, need to pass back the name string then re-look it up from Parse on the iPhone), then send back the corresponding data to populate WKInterfaceTable 1 on the Watch. Then send the selected value to interface controller 2 via context. Then pass back the string value to the iPhone again via OpenParentApplication again (note: though you can only have 1 handleWatchkitExtensionRequest method in your AppDelegate, you can make multiple requests within that method via different keys in the dictionary you’re sending from the watch), again re-look up the appropriate data in Parse.com, then send back to interface controller 2 to populate WKInterfaceTable 2, and repeat the whole thing again for interface controller/WKInterfaceTable 3…. 😫
Needless to say, that took a ton of code, but I got it done…only to find out upon testing that the calls were incredibly buggy and the responses were not consistent.
(3) So, I finally settled on cashing the data locally in AppDelegate on the iPhone and passing this data to the watch via App Groups and NSUserDefaults. Alas it works, and is snappy UX-wise. I’m still working on when and where exactly to call my cashing method….and I’m still working through how to update my Watch App’s UI when the data has been changed on the iPhone, but it looks like this will be the method I’ll ship with…then refactor in the fall when WatchOS comes out and hopefully makes this all a lot more simple. 🙏
What the Hell are Setters and Getters Anyway?
Having learned to code in Swift with no Objective-C background, I would hear references to setters and getters and had no clue what they were talking about. Even Paul Hegarty at Stanford in his C193P lectures, who usually provides a background for everything, didn’t really explain what they were.
It turns out I knew what they were all along…
Recently reading this Stack Overflow answer, @wander provided a great background for what they are in Objective-C:

So dot syntax, which I use everyday in Swift either to SET some value or to GET some value is all they really are 😇
Don’t be the guy (or girl) that doesn’t use version control….💀
I recently was working on a large project. I had implemented the Parse framework by manually adding the files to my project. I wanted to use another framework that was only available via cocoapods, so I installed via a pod.
Unfortunately something in this build process triggered an Xcode error that I couldn’t solve no matter how hard I tried.
I had always been aware of GIT and version control generally, but never really taken the time to stop and learn it. Because I hadn’t, I had no way of restoring the state of my project to it’s previously error-free state.
The only thing I was left to do was create a new project and manually drag the files and the storyboard into the new project (as well as create a new backend on Parse.com). No fun…😑
So I finally took the time to learn GIT. This tutorial was really helpful.
I’ll never be THAT GUY again 👍
Do you comment bro?
As my code gets increasingly complex, I find myself going back to something I wrote as recently as yesterday and I can’t figure out what the hell it means. 🙄 Imagine if someone else were looking at my code…. for that reason I try to comment my code whenever I’m doing anything that might take more than a few seconds to understand what it’s doing. The below is a snippet from a current project I’m working on:
func loadUsers() {
//1 load User Array of JSON from NSUD
let defaults = NSUserDefaults.standardUserDefaults()
//2 grab users from defaults
if let usersFromDefaults = defaults.objectForKey("usersKey") as? JSON {
//3 iterate through dictionary key values in defaults
for name in usersFromDefaults.keys {
//4 convert each saved user by key = name into JSON and store in local var
if let userJSON = usersFromDefaults[name] as? JSON,
//5 create a user for each value in the loop
let user = User(json: userJSON) {
//6 store the user in the local dictionary at key = name
userDictionary[name] = user
}
}
}
}
How is Programming Like Being a Lawyer?
In my legal career, I’ve learned very little in law school that has translated to the actual practice of law. Sure you reference back sometimes to fundamental principals, but the great majority of things you do everyday as an attorney you learn by doing. I don’t know if its the same for programmers who have CS degrees…but I certainly wouldn’t look down upon a lawyer with a CS background who hadn’t gone to law school (if it were possible 🙄 ).
One skill that both fields have in common is the ability to be resourceful. In both the law and programming, no one can know everything there is to know. In law school, you’re not taught the law so much as you are taught how to “think like a lawyer.” You’ll hear this phrase often in law schools around the country. Many times it refers to the “Socratic” method so popular in law school lectures (for a great example stream the movie “The Paper Chase” which does a great job of capturing it) which usually involves an endless array (pun intended) of questions by the law professor, to a “1L” (first year) law student…who, no matter how many “correct” answers they give, are peppered with yet another question.
One of my law professors once said “being a lawyer isn’t knowing the answer so much as it is knowing what the question is.” Over the years practicing law this has proven true over and over again. In other words, a client will describe a complicated series of events to you, which you’ll have to parse (sorry, I can’t stop…) to figure out what the legal question is before you can go on to trying to find a solution.
The point is that, like programmers, attorneys don’t know everything. It’s impossible to know every statute, regulation, case etc. even when he or she specializes in a small area of law. Instead lawyers learn to be resourceful. It’s ok that you don’t have the answer in your mind immediately as long as you know where you go find it quickly…
My experience with programming is so much the same. The world of programming to a new programmer can seem endless….even when limited to one platform like IOS. All of the frameworks and libraries (Apple’s alone, let alone third party) and learning Swift can be overwhelming…so like a lawyer, you go out and find how to do something when you need it.
Too bad there’s no Stack Overflow for lawyers… 😆
