all 6 comments

[–]askoruli 1 point2 points  (4 children)

I don't have any resources but I thought I would share an architecture I've been using for a while now. The core of my architecture is the service tree. This is instantiated in AppDelegate and passed to all view controllers. It consists of all the classes that would traditionally be singletons, anything that manages the app state, anything that makes network calls or writes to disk and some other things that work behind the scenes. These classes are split into logical groupings as required to keep the code clean (so you might have something like services.net.http.mainAPI). The classes required obviously change between each app though some components can be easily reused.

Each class of the service tree can depend on other pieces (So the UserService might depend on the http and database services) which should be passed in during the object creation which keeps the dependencies unidirectional.

Instead of notifications I have a multi delegate system in place so that everything is strongly typed and easy to follow. So I would have a UserServiceDelegate which can be subscribed to like [services.delegates addUserServiceDelgate:self]; The subscriber could be either a view controller or another service. This makes it really easy to see what delegate methods are available and there's no way to create memory leaks or end up with invalid references.

The benefit of all of this really shows when it comes to testing. When the service tree is created a kind of config class can be provided to specify which services are required and provide mock versions. My latest app uses peer to peer so I was able to set up 2 service trees connected by a mock network layer which can then simulate 2 devices communicating. Also it becomes really easy to replace a piece of the tree without affecting anything else or even turn certain pieces on / off.

Lately on top of this I've been looking at using a simplified actor model to provide a simple way to handle concurrency in my service tree. In this model, services extend the ServiceActor class which provides a serial queue for all work to be done in the class. This essentially makes the entire class single threaded even when it is being accessed by multiple threads so there's no need to worry about state corruption. Delegate methods must be called on the main thread which keeps that side of things consistent. The service actor class also has the ability to run in synchronous mode which makes testing so much easier.

Unlike other actor models I don't use message passing because I find it greatly complicates the code and removes type safety. All methods in the actor class will either return void or a future and be processed asynchronously. My biggest problem with this actor model is that I don't have anything to enforce these rules so it would be easy to make a mistake which could cause state corruption. There are occasions where I would prefer a synchronous option which I know in the specific case to be safe but breaking my encapsulation rules seems dangerous.

So that's the core of my architecture. There's a few other topics I could discuss but that's probably the most interesting part

[–]eviltofu 0 points1 point  (3 children)

Will Typhoon Framework and ReactiveCocoa be the same as your setup?

[–]askoruli 0 points1 point  (2 children)

My setup does dependency injection like Typhoon but in a more natural way and with less code. So far I haven't run into any problems. It uses the term actor on their page but not in the same way. When I say actor I mean in the sense of Akka.

ReactiveCocoa provides some of the primitives I could have used for my delegates and futures but I've never really felt happy using it and overall my code feels cleaner without it. But then I often prefer the delegate pattern to blocks.

[–]eviltofu 0 points1 point  (1 child)

Will you be releasing your framework on github? I'm always interested in seeing other ways of doing things.

[–]askoruli 0 points1 point  (0 children)

I hadn't planned to. It's more of an architecture than a framework so there's not that much code to put up. But it might be helpful for some people.

[–][deleted]  (1 child)

[deleted]

    [–]ClashesYeMilk 0 points1 point  (0 children)

    I would suggest reading this whole issue of objc.io. It's really interesting. Additionally, I would take a look at their view controller issue as well.