Why does NSKeyedUnarchiver exist when NSKeyedArchiver inherits from NSCoder? - ios

To give some context, I'm new to iOS/Objective-C with a web dev (Ruby/JS/C#) background. I understand how the classes work, but I don't understand why the original implementors wrote these two classes (NSKeyedArchiver and NSKeyedUnarchiver) instead of consolidating both encoding and decoding logic into a single class.
Reading the Apple documentation for the abstract class NSCoder a NSCoder has methods to both encode and decode. The only thing I can think of is that the code was long so the original implementer split it into 2... It seems to me that it'd be more convenient to the developer that only a single class is used, but maybe I'm missing something nuanced about this. So are there any historical reasons for this? Was NSCoder a "convenience" in that it defines both the encoding/decoding APIs, but meant to be separated into encoder/decoders? Am I misunderstanding what a NSCoder is supposed to do?

I think that keeping archiving and unarchiving functionality in separate classes is the result of applying the Single Responsibility Principle, which says that a class has to have a single, narrow, responsibility, which should be fully encapsulated inside that class. Indeed, when you create an instance of NSCoder's subclass, you do that either to archive a group of objects, or to unarchive data into a group of objects, but not both.
This design is not ideal, because now you have several pairs of classes (i.e. NSArchiver/NSUnarchiver and NSKeyedArchiver/NSKeyedUnarchiver) linked by communicational cohesion, while a single-class design would have lead to this data dependency being fully encapsulated. This is a tradeoff on which the designers of the Cocoa library could have gone either way. It appears that they picked single responsibility principle, at the price of introducing a data format dependency.

Related

Why do delegates exist in iOS?

I understand that delegates are essentially objects that another object can pass messages to, and that they are used on behalf of other classes. So for example, a UITableViewDelegate has methods which can be used to detect particular events in a UITableView. This is very useful, and indeed I have used delegates a lot in past iOS projects, so this is more of a curiosity:
Why do the methods in a delegate class not just exist in the class that the delegate is being delegated by?
Surely it would be more convenient to have those methods in the actual class, such as a UITableView?
Perhaps it is that architecturally it is more convenient, but from fist looks it seems counter intuitive.
As a general rule, composition is more powerful than inheritance. Inheritance creates many subtle problems, the most common of which is the diamond problem, but there are many other problems.
Delegation is just a specific formulation of the Strategy pattern, which allows us to extend an object via composition rather than inheritance.
As a concrete example of the issue, and how the diamond problem creeps in when you use inheritance, consider this:
You have a very common way you want to provide cells. For example, you'd like a Core Data fetch request, or a network request that generates cells. So you would build a superclass that encapsulated all this logic. We'll call the class that handles thatFetchRequestDataProviding.
Separately, you have a visual behavior you use a lot. For example, you want a particular kind of animations for your view, so you wrap that up into a class FadeInTableView.
Now we have a problem because we want both. So we need multiple inheritance. And multiple inheritance is Pandora's box of ambiguities.
But I eliminate all of that if I make FetchRequestDataProviding a separate object that behaves as a delegate. I actually could make things even more powerful by breaking out FadeInAnimating as a delegate/strategy (though UIView doesn't have that power today).
In ObjC, "composition is more powerful than inheritance" shows itself commonly in a fairly shallow inheritance tree and lots of delegates. Swift pushes this further with protocols and structs that have no inheritance. None of this means that inheritance is bad; it can have a lot of value (though languages like Go avoid it entirely; though interestingly still has to face the diamond problem due to embedding). But when in doubt, composition is the more powerful tool.

Where to put Constants.swift?

I'm a newbie to Swift and iOS programming in general, and I'm currently getting my hands dirty building a Swift app. I have encountered this problem of where to put the Constants.swift file (which basically stores the constants used by the app), and the confusion is mainly caused by the MVC logic. I have two options that I deem somewhat reasonable.
Put Constants.swift outside of the MVC framework, so that it does not belong to any particular party. Rationale: this way it could be conveniently referenced by all the components.
Put Constants.swift in the controller. Rationale: Controller is application-specific, and so is Constants.swift. Model and View are generic and hence should not be used to store constants.
But I don't know which of the two above I should use, or if there are any better options. What do you all think?
I think you should separate the constants in the classes that have to do with them and access them like:
Configurations.Constants.width or Car.Constant.speed
You can use structs with static properties to store them.
Don't know if that is your case, and depends on the constants, but it is not common to have one file with ALL the constants of the program, or one file with constants that need to be accessed from all the other components, this could indicate a design problem. If you store them close to or in the classes related to them, you won't have a problem with Cocoa's MVC.

Data Accessor object singleton or some other pattern? (Objective C)

It seems to satisfy the three requirements here: On Design Patterns: When to use the Singleton?
I need it to exist only once.
I need to access it from all over the source base.
It handles concurrent access, i.e. Locks for writes, but can handle concurrent reads.
Hi all,
I've been reading a lot of no doubt intelligent educated and wise gems of advice that Singletons are 'Evil' and singletons are anti patterns or just plain bad news.
With the argument that logging makes sense but not much else.
Just interested to know if the case of essentially a persistent data store context makes sense for a singleton, i.e. Reading/Writing from disk to memory and referencing an object graph.
And if not, how do people normally tackle this issue, I don't currently have any problem with it, I know it's created only once, it's fast and the accessor logic is in one place. Meaning it takes me one line of code to do anything data model related.
Which leaves the only argument that it's bad for testing, in that it's a hard coded production implementation to data, but couldn't I just write a method swizzle through a category or in the test code to create the test version of the singleton?
And the final argument from DI testers, is that it is a hard coded implementation, rather than simply an interface to something, which I do get but I don't really have a major drive to use a DI framework given that I can use protocols for implementation, and use separate init methods for setting up an objects state in testing. There's only ever going to be two types of state for the singleton, or realistically one type...production.
Making it (in my opinion) much easier to read and faster to develop.
Change my view SO?
Yup, for some singletons are Evil. For the new developers who has little MRC knowledge and more ARC it sounds scary because they need to mess with memory,volatile,synchronize etc.
However it is not against to use them, they indeed has their own purpose to use with some are below.
when sharing large data models like arrays and dictionaries etc between multiple screens (VC's) we can't prefer storing them in UserDefaults (because userdefaults is permanent storage and storing such large entries make app start lazily) instead singletons are best since they stay only current app context and restarting app creates new one.
when we need a stable db connection to be accessible allover the app without messing up with connecting and closing in every business classes we can go for it.
when we wanted an ability to app for theming itself dynamically we would need to create a singleton class which holds all the color,image instances etc. and use that instance in application VC/Views etc so no code duplication and re-processing theme occurs in all places.
You dont have to change your view but tweak it a bit to get some positive intention towards singletons.
Hoping this clears it out, thanks

Abstracting Parse objects?

I want to use Parse (parse.com) in my app. Parse uses PFObject models. I'd like to use my own models throughout my code (so that it doesn't depend on parse). If possible I'd like to design my app so that I can replace parse with another cloud service as seamlessly as possible if I wanted to.
Is this a good idea? What's the best way to abstract the model storage so that there is no (or minimal) traces of Parse code in my app?
Perhaps use the adapter design pattern to map parse objects to my own objects? Should this be an independent class or part of the model logic?
If anyone has tried something like this I'd like to hear your thoughts. Should I just use parse models directly in my code? Or perhaps a singleton factory to generate my models based on parse objects?
Any tips/thoughts/comments ?
I've found relatively clean way to manage this.
Basically I've created a protocol called NPDictionaryRepresenting which classes can conform to in order to specify how they should be converted into a dictionary or initialized from a dictionary.
#protocol NPDictionaryRepresenting <NSObject>
- (NSDictionary *)dictionaryRepresentation;
+ (id)objectWithDictionaryRepresentation:(NSDictionary *)dictionary;
#end
Each of my models that I need stored in Parse will conform to this and implement their own custom behaviour. This protocol is abstracted through the use of dictionaries so it doesn't depend on Parse in any way.
Then I've implemented a NPNetworkAdapter base class to handle all network storage. I've also implemented an NPParseNetworkAdapter class which inherits from NPNetworkAdapter. This is the only class which knows anything about Parse. Its interface deals with objects that conform to NPDictionaryRepresenting. The parse network adapter is able to create PFObjects by extracting dictionary representations of my objects. Conversely it's able to fetch PFObjects and give me back my own models by instantiating them using dictionaries.
The drawback with this implementation is it doesn't work very well with object relationships (but I'm working on it).
If anyone has any comments on this approach I'd love to hear them.
I realise this is an old question, but I'm busy working on a project that poses this exact same problem so I thought I'd comment. Firstly, I think you did well to identify this and to try and avoid coupling your code too tightly with Parse.
The route I have decided to take is to make use of Protocols (Interfaces) for my model classes with the underlying implementation being the Parse objects - using the Parse subclassing feature; I've combined this with the use of factory classes to decouple object creation and implementation specifics from most of my application code. This may seem like overkill and does require a bit of extra code upfront, however, I believe it will pay dividends with testing and if the time ever comes to change how I access back-end services.
The other alternative for me was to make use of wrapper classes which just wrapped the PFObjects. However, in my case, the wrapper classes would've just been dumb delegation classes without the added benefit Protocols provide for testing, so I stuck with the Protocols approach.

Creating a global object across classes

I need to create a global object that will work and can be used across all the classes in the program. I've done some research and seen the solution seems to be implementing it in the AppDelegate, but there doesn't seem to be much explanation as to how to accomplish this and more importantly this doesn't really seem correct as per my understand of the AppDelegate purpose.
you should check the singleton pattern:
In software engineering, the singleton pattern is a design pattern
that restricts the instantiation of a class to one object. This is
useful when exactly one object is needed to coordinate actions across
the system. The concept is sometimes generalized to systems that
operate more efficiently when only one object exists, or that restrict
the instantiation to a certain number of objects. The term comes from
the mathematical concept of a singleton.
here is a source for a example implementation: What should my Objective-C singleton look like?

Resources