Wednesday, 20 March 2013

Multiple MOCs - Why?

I've been using Core Data with my current iOS app since early days. I've been learning more and more about the idiosyncrasies of Core Data and this magical thing called the 'Managed Object Context'.

What is the Managed Object Context?

I've heard it described as a scratchpad for you persistent data store. You can use it to represent the current state of your data store, or it can function to hold temporary data... that won't be or hasn't yet been persisted to your data store.

I think knowing these functions and thinking about them when you first start working with Core Data and managed object contexts is important. Otherwise, you ask yourself... 'Why, do I have to go through this thing to talk to my data store'.

After you understand this, you might ask yourself.. 'Well, why do I need to hold temporary data..? Or hold data before persisting it?'

I know of few cases where this is useful.
  1. Entity creation that spans multiple screens. As a ex-web developer I can think of what a pain it is to do this in the web world. If the user cancels half-way through, you need to ensure that nothing has persisted to the database. In web, you would have to have some fancy javascript or session storage going on to make this work. It's a huge pain! If you use something like an MOC to store this temporary object while the user builds it out, you don't have to persist it until it's completed.
  2. Data synchronization. Consider a situation where the user creates some entity that needs to be persisted to a back-end server. One strategy for doing this involves hold that entity in an MOC and only merging it to the main MOC and underlying data store when it has successfully been persisted to the back-end server.
I bet there are lots of other useful ways of using multiple MOCs. I'm just starting to explore this realm of Core Data and will update this post if I find other use cases!

Tuesday, 12 March 2013

Property Attributes and Definition in iOS

Properties are an alternative to defining instance variables and their corresponding accessors methods. Let's go over the difference

Defining a Property vs. an Instance Variable


Without Properties

With Properties

What happens behind the scenes here are declarations for you accessor methods. This means with the above header and implementation code, you can operate on an instance of this object as follows.

Property Attributes


Each property has a set of attributes that describe the behavior of the accessor methods for that property. Here's an example.

There are three property attributes. Two of these must be specified and the 3rd has a default.
  1. The first attribute specifies either atomic or nonatomic. This has to do with multi-threading. Let's just say here that if you're doing a standard iOS app you should be using nonatomic.
  2. The second attribute specifies either readwrite or readonly. This tells Objective-C whether it should generate a getter and a setter(readwrite)... or just a getter(readonly).
  3. The final attribute has to do with memory management, which I've talked about in more detail here. The options here are weak, strong, or assign. Assign is the default which can be used for primitive values that don't point to an object. (like int)

iOS memory management with ARC

I've been learning iOS development over the last few months. I've been lucky enough to be working with iOS's ARC or automatic reference counting. This is what was introduced in iOS 5 and makes life a lot easier for iOS developers.

To understand how ARC works, a few concepts involving application memory need to be considered.

The Heap

This is the part of memory where all Objective-C objects are stored. When you send the alloc as a message to a given class, a chunk of memory is allocated from the heap for this new instance. This chunk includes space for the object's instance variables. However, if these instance variables are references to other objects, those objects are stored in their own heap allocation.

Pointers are used to remember where objects are stored in the heap.

The Stack

If the heap can be visualized as a heap of objects we reference via pointers, the stack can be visualized as a stack of frames (or chunks of memory). Frames from the stack are allocated as methods are executed and they store variables declared inside the method (i.e. local variables).

If you think about it. Most programs start by running some sort of main function. This would be the first frame on the stack. If it calls another method which then calls another method... each of these would get new frames allocated from the stack. As each method finishes, it's frame is popped off the stack and destroyed.

Pointers

These point to objects stored in the heap.

These can exist in 2 forms:

  1. As references from the local variables defined by methods using frames on the stack.
  2. As references from instance variables on another object stored within the heap
Memory Management

Heap memory is obviously not endless. It is important to destroy objects that are no longer needed to make room for new objects. It is also very important to not destroy objects that are STILL needed.

Object ownership is what helps in determining whether an object should be destroyed or not.
  • An object with no owners can be destroyed
  • An object with one or more owners can not be destroyed
iOS's ARC

Automatic reference counting was introduced in iOS 5 and takes care of deciding which objects have owners and which don't. And destroys those that don't! Before this, you would have to manage memory yourself using retain and release messages.

ARC now takes care of most of this for you, but it's still important to know what's going on behind the scenes in case you need to step in at some point.

How does ARC know an object doesn't have any more owners? It keeps track of all pointers to that object as they are created. Later, a number of things can happen to these pointers which mean they don't 'own' the object at the other end of the pointer.
  1. The pointer is changed to point to another object
  2. The pointer is set to nil
  3. The variable holding the pointer is destroyed
The last one is interesting because, as objects own other objects, which can own other objects.. the destruction of a single object can set off a chain reaction of loss of ownership and subsequent object destruction.

Your Hook in ARC

In Objective-C you're able to define variables as having strong or weak references. This ties directly into how ARC will manage the objects pointed to by these variables.

Strong Reference - This encompasses the discussion so far. If a variable is defined as pointing to an object, that object will never be destroyed.

Weak Reference - A variable that does not take ownership of the object it points to. If an object only has pointers from weak references pointing to it, it will be destroyed

Why have weak references? They're mostly used for retain cycles. This is when two or more objects have strong references to each other. This is bad because neither of these (or any objects they own) will ever be destroyed, even if all other pointers to both have been removed.

An interesting thing about weak references is that they know when the object they point to is destroyed. They are set to nil in this case. This will prevent any exceptions from occurring if the object containing that weak reference ever tries to use it.

Conclusion

So, if all those strong vs. weak variable definitions were confusing you (as they did me at first) there you go. It's the framework for memory management in Objective-C.

Monday, 4 March 2013

AF Networking Simplifies iOS Http Requests

I wrote this post a month or so ago on implementing http requests using the built in iOS libraries. I've been building a iOS app with a Rails on Mongo instance functioning at the backend API. I just switched everything over to AF Networking, which has helped simplify my network calls greatly!

If you compare these two approaches you can see the simplicity AF Networking gets you!

And then you just implement the two methods given to the networking operation callback block. In this case, processResult and processFailure. It's so simple! And so much less code than the standard iOS option.

The AF Networking github page.

Monday, 25 February 2013

iOS Data Synchronization - How???

I'm working on an iPhone app at the moment and I'm approaching the time when I'll need to do data synchronization with my backend Rails API. Up to this point, I've only pulled data down to the mobile device so the backend has acted as the sort of 'master' of the data. Now, data entered on the device will need to be incorporated into the 'master' data and available to all users.

I've sort of been deferring the decision of how to implement this until the last 'responsible' point because it's a daunting task... and done wrong, would perhaps need to be completely done over again in the future.

I remember the pain on my last project (an Android tablet app) after we brought in our first solution to data syncing between device and backend. We suffered through 3 months of headache and then gutted the whole thing for another strategy. The odd thing is the initial thing we'd gone for was one of the Android 'recommended approaches'. These things called Cursor Adapters. Steer clear! I'll maybe do a different post on these and why they are painful.

So, I'm cautious about using libraries intended to be a one-size-fits-all. Luckily I guess, I haven't actually found any for iOS, so I think I'll be rolling my strategy.

These are the questions I'm asking myself.

1. How close are the data models between the device and backend?
2. How much data will be need to be synchronized?
3. How frequently will it need to be synchronized?
4. If the user deletes the app and reinstalls it, will data need to be downloaded to the device in the same state as before the delete?
5. I'm going to need to know which data came from which user.. how will I tag the data as such?
6. How to queue up changes if they are made while the user if offline?

Because I don't have a huge amount of data that will need to be synched, my initial approach will be to set up a process that checks for changes across the tables where they might occur (initially only 2 for my case) and then pushes these to my RESTful backend using JSON over an HTTP post request. My backend, will then store these data in separate tables where the user and timestamps are recorded. After this, I should be able to set up another timed request. More posts as I move forward on this!

Tuesday, 19 February 2013

My start-up experience (to date)

I've been working on GoFest, a start-up I created, for the last 4 months and it's been a really interesting ride. I'm close to an iOS app store release and I have my first potential customer. I realized I'd been blogging about the technical side of what I was doing.. but not on the experience itself. I wanted to remedy that! I think I'll keep trying to blog, but for starters, I want to give a little overview of how things have gone so far.

It all started when I left my job (of 6+ years) in software consulting last October. I did this for a couple of reasons.
  1. I was unhappy with the current state of things in my work life. I felt like things were in a rut and I wasn't growing. On top of that, there was a lot of conflict and aggression occurring in the project I was on that I was eager move beyond.
  2. I had a growing urge to start something on my own. I'd been exposed to the start-up world expanding around me and was getting more and more excited by it. I had a mobile app idea that I knew I could build, if I had the time.
  3. I felt starting a company would be a great opportunity for the growth and learning that I was craving.

So, off I went! I knew I would make a lot of mistakes, but I was hoping to make them quickly and learn quickly. I left my job and dove into learning how to start a company.

Here's a quick overview of the activities I busied myself with.

Reading
  • I knew I had a lot to learn, so I picked up 2 books that were recommendations from friends and collegues: The Lean Start-up by Eric Reis and The Personal MBA by Josh Kaufman. I've since read them both and they are invaluable! I'd highly recommend them to everyone working in the business world.
Market Research (This is where I started.)
  • I looked around for apps even remotely related to my idea. I compiled of list of those I felt would be competitors or those that should just be watched for future direction. I allowed this to influence my idea because it's likely better to create a product with as little competition as possible.
  • I explored the Twitter and Facebook world around the topic my app would relate to. People on these networks would probably be the easiest to reach later when I wanted to do user research.
  • I tried to define who my customer would be and what they were interested in/willing to pay for.
Business Model/Plan
  • This obviously has to make me money. How was it going to do this? When was it likely that this would first happen?
Define MVP (minimum viable product)
  • What was the minimum feature set I needed to get this to the market?
Building
  • I started building the product. It was a lot of fun! I hadn't done any iOS development before, so I had a lot to learn.. but it's fun learning a new language and framework. And you get all those little wins each time you make something work.
Outside Help
  • One of my weaknesses was that I didn't have a solid co-founder. I had an ex-colleague offering business type advise and I had a friend here or there helping with with UX (user experience) or design. 
  • Tandem Incubator - In early December I was almost 2 months into this whole thing and I decided to look into incubators. I'd heard of these, but had earlier felt that I needed to get a little further with my project before applying. I decided that now was the time and dove into the application process.
    • I worked very hard for about 2 weeks getting things ready for the application. Deploying the app's website, generating screenshots and even a presentation. In the end, I didn't get accepted. But, going through the application ended up being a really beneficial thing. I refined my business plan, answered some hard questions about timelines and really worked out what the 'Pitch' for this app would focus on.
Where I am I now?
  • My iOS is app is nearing completion (I hope to deploy it in the app store in the next 6 weeks)
  • I have my first customer (my app is sort of based on customer subscriptions in a way)
  • I'm running out of money. :-)
  • While revenue could start coming in soon, I'm realizing that it won't start pouring in any time in the near future.

So, I'm undecided on what to do! I'm still lacking the co-founder. I've been attending networking events with different entrepreneurial circles here in NYC. I'm seeking the cofounder at these, but I'm also seeking community and potential role models. This process has been really awesome actually! It's great to meet so many people doing amazing things. 

One thing that afflicts the developer entrepreneur is the knowing of the current state of the job market. There are lots of jobs out there for an experienced engineer. Exciting, well paying jobs! The lure of this is in the back of my head every time I think about my checking account balance.

I think blogging about this is good for me to figure out what's next. Maybe I'll get accepted to an incubator! Who knows? Maybe I do take a job with a start-up and learn in a more mature, but related environment.  For now, I'm going to keep plugging at it for a while more.

Thursday, 14 February 2013

iOS provisioning HELL (solved)

Sometime I feel like the relationship I have with Apple is quite similar to that one would have with a bipolar boyfriend or girlfriend. The good times are really good... and the bad times are REALLY bad. But you just stay because you can't imagine life without them. :-) They brought us smart phones, mac books and iPods. You can't give those up! And they obviously brought us mobile apps easily distributed though an app store. This is great!

But it's well known that it's a pain the ass releasing your app through their long and tedious process. Provisioning used to be a nightmare! It also used to be hard to get your app to beta testers because you needed their phone's UDID and then you would have to produce a different build for each UDID. PAIN!

Test Flight was the earliest tool out there for managing your builds and distributing them to stakeholders, testers, etc.. I was even talking to Jeff Soto from the iOS Brooklyn Meetup and his team at Tendigi are building a tool to integrate Test Flight with their QA process. Very cool!

I've actually just started using AirOnApp because they go one step further and remove the need for collecting each of the UDIDs from every device that you'll distribute to during testing. They resign the app automagically for the each device. :-)

I'm planning on releasing my app in the next month and will use their automated release process as well. Hoping that goes as well as beta testing distribution!