Why Apple allow to create multiple HMHomeManager instances - ios

I'll like to know why Apple allow to create more than one instance of HMHomeManager and what is the purpose of it?
I would expect the instance of HMHomeManager to be a singleton.

I can't speak for Apple but I see no cases where HMHomeManager would benefit from being a singleton and several clear disadvantages.
HMHomeManager has a delegate property. The delegate pattern works well when you want a delegator to send messages to a single delegate or when many delegators might share a delegate. It is however not useful when one delegator might produce messages of interest to many delegates which would be the case if HMHomeManager were a singleton.
Singletons are not easily deallocated. Any app using a HMHomeManager as a singleton would keep that object in memory monitoring for changes to the home database even if it was no longer needed.
The assumption that there should only ever be one HMHomeManager may not hold true forever. While one HMHomeManager can contain many homes they all share a common user. Designing this class as a singleton would preclude an app from acting on behalf of multiple users at once. Even if there's never a need for such behavior developers might be wise to avoid selecting an interface which cannot support it early in the design process.

Don't create multiple instances of HMHomeManager.May be below code will be helpful. If you want to made any changes to the existing home try to execute the code after made the changes like add room,zone...
for(HMHome *home in appDelegate.homeManager.homes)
{
if([home.name isEqualToString:appDel.selectedHome.name])
{
appDel.selectedHome = home;
}
}

I would expect internally there is a singleton client that communicates with the home daemon, the same way CLLocationManager has a singleton CLLocationInternalClient.sharedServiceClient which allows us to scatter location managers throughout our app without having to worry about forwarding notifications or multicasting delegate methods around ourselves. I haven't examined HMHomeManager as closely and it does seem quite a rushed API so maybe not as well designed. It's concerning the documentation mentions "the manager for your app" as if we are only supposed to have one. Furthermore when you receive the home changed delegate call it tells us to "invalidate your own app's objects that cache the home's data". One thing I have noticed is when you init a HMHomeManager it inits all the rooms, services and accessory objects which in my case is about 400KB (calculated by initing 10 home managers and comparing the RAM difference) for my 301 characteristics, 68 services, 19 accessories home (I used Allocations in Instruments searching for 'HM' to learn this). So we probably should stick to one manager per app but there is a serious design problem with the API that when we toggle a characteristic the delegate method isn't called so we need to reach out to our app's object and invalidate it rather than it happening automatically for us like any other API would.

Related

Should I use a singleton location manager in Swift?

Context:
My app needs the user's current location in several unrelated view controllers and, as of now, I'm creating a CLLocationManager in each of these controllers and requesting the current location over and over.
However, it doesn't look right to me. It's duplicated code and inneficient.
I've seen several references on the internet mentioning a singleton location manager. And I also heard to avoid singletons as much as possible.
Question:
Should I create a singleton class that manages the location? If not, what other solution would you suggest to avoid this duplicated code?
And I also heard to avoid singletons as much as possible
The above statement is correct in case that some dealoocated cycle of the app run needs that data so after it finishes the singleton becomes a problem from memory perspective as it stays alive all the app life cycle , in your case ( all vcs inside the app needs the location ) is the best fit for a singleton to avoid the duplication - less-efficient code and high memory issues
Needless to say 90% of apple classes uses singletons e.x
URLSession.shared
NSNotificationCenter.default
UNUserNotificationCenter.current
UserDefaults.standard
FileManager.default
There is no hard and fast rule. Apple is quite clear that it's fine to instantiate more than one location manager. However, if you do that, you might confuse yourself, because each will need a delegate, each will need its own settings, and so forth. Thus, you are right to be wary of that approach.
It is a standard strategy to pick an instance that persists throughout the life of your app — your app delegate, or your root view controller, for example — and initialize an instance property with a location manager. There is no reason whatever to add the Singleton pattern to the mix; you simply make one once and keep hold of it.
Patterns are not evil. It depends on the user. They are solutions for a specific problems. It depends on how you see your problem and what you want to achieve.
In your case, you need a location manager instance through out your app and you use it in multiple places, so you need a wrapper manager. If you only need one configuration, then it makes sense to use singleton.
Apple is recommending to have a strong reference of the manager as long as you need it. CLLocationManager - Apple Documentation
Create an instance of the CLLocationManager class and store a strong reference to it somewhere in your app.
Keeping a strong reference to the location manager object is required until all tasks involving that object are complete. Because most location manager tasks run asynchronously, storing your location manager in a local variable is insufficient.
If you create a singleton location manager it has to do things differently than other singletons. You can't use the normal delegate pattern for it to inform other objects about the location updates and errors because the normal delegate pattern is a one-to-one relationship. You have to use multiple delegates (the singleton has an array of interested objects and it sends the same message, e.g. location update, to each one). Here's another question about why that's difficult to use:
Multiple Delegates in iOS
You can get around that with notifications but personally I think that's a bad pattern (it decouples things too much and makes it hard to follow paths of responsibility).
The singleton also has to keep track of whether any of its interested objects asked it to stop or start. If they've all asked it to stop then it should power down the updates. If just one wants updates it has to power them back up. Search for all the people building frameworks just to do the same task with the network indicator to see how much trouble this is.
If there's an error with requesting location you have to save that error and when (some later time) an object wants location, you have to retransmit the error. So really you want to have all interested objects connected and listening from the start to avoid that scenario.
I'm sure I could think of more hairy cases that you'd have to deal with.
The in-between option is to create a location manager class with your special setup, error checking and so on, and instantiate one of those whenever you need it. Use the delegate pattern to get messages from it (most will just be passing the messages along directly).

Design patterns: exposing notifications using a protocol

I have got several types of a logic controller class that handle the communication with a remote resource. To do so each class uses an instance of a network controller class that deals with the connection details: connects to a resource, sends data, receives data. The logic controller classes are notified of data changes from the network controller class using notifications. So in my current solution each logic controller class registers for the notifications and implements specific functions to deal with them differently.
However, if I want to do proper code engineering, I wonder whether it would be more robust to use protocols and delegation.
I wonder if I could define which methods the logical controller classes need to implement in order to receive the notification. However I am not sure if this makes sense and is correct because I do not want inheritance here.
Any suggestion?
Typically you have 1 or 2 (explained later) methods per notification. So it is a quite simple mapping. The reason for that is that you have one notification per "event" and there is little reason to chance that for delegation.
But your design is good. What is the difference between delegation and notifications? (Robustness is not.)
A delegate is a single instance that customizes the behavior of the delegating instance. Therefore beside the usual "inform" methods (will…, did…) it can have the ability to change the behavior of the delegating, i. e. returning NO as an "invalid marker" (should…) or change the data set, a operation is executed on. (Sometimes this is the 2nd method for an event.) It is obvious that in such cases you cannot have multiple instances at a time. Delegation is in competition with subclassing and often the better choice (white boxing vs. black boxing).
You can have as many notification receivers as you want to. Obviously they cannot change the behavior of the notification sender. Therefore it is the better choice, if you have several instances that only needs an information that an event happened.
If understood your use case correctly, notifications are perfectly fitting your requirements.

Which observer pattern should I use for remote app?

I am building a remote app which is receiving different states of its accessory. It is receiving things like: power state on/off, volume state 5, equalizer setting jazz, etc. and has nothing more to do than map theses states into the UI with selected or unselected states and send changes done back to the accessory.
About the app architecture:
The app is connected with it's accessory as illustrated in Apples EADemo project using the external accessory framework.
The UI is build within non-repeating customized UITableViewCell full of UIButtons. When starting the app a data model class will receive all current states from the examples EADSessionController and has to communicate theses states to the UI (the cells directly rather than the UITableViewController) with one of the mentioned patterns. This will be a stand alone, one-page app looking like a real remote.
Thinking of NSNotification, delegates and KVO (key-value-observing) I am trying to figure out which of these patterns I should use for this special approach?
Any answer on why choosing one of them and a brief description on how to implement would be appreciated. If your answer will be KVO please give some more insights since I never used this pattern so far.
It really depends.
The most loosely coupled one is to use NSNotification and NSNotificationCenter, as the instance which post the notification does not necessarily have knowledge about the observer, and there can be more than one observer.
The delegate pattern is a little more rigid, and there could usually be only one delegate object that receives a message. If the UITableViewController in your project is the only instance that handles a message(, or it would properly propagate the message to other components), it is still OK.
The KVO pattern requires more precisely designed observation relationship. You will have and have to look after exactly how the KVO is implemented. And KVO also allows one-to-many observation. The down side of KVO is if the observing relationship is dynamic and transient, you must take much more care about how these objects were torn down, or you could get a lot of crashes like sending updates to a dealloc'ed instance, etc.
If you are working on a library which would be delivered to a 3rd party to use, perhaps NSNotification would be the first choice.

Which class should be responsible for activity indications when both model and controller need to display it?

I have a model which can download data from a server and thus an activity indicator needs to be displayed (both in the status bar and on screen).
But I also have a UIWebView which is displaying content, the content has links, some are local and some are remote, if a remote link needs to be downloaded then an activity indicator needs to be displayed again.
What are design options for accomplishing this?
The app delegate could have methods to start and stop the activity indicators as directed by the models and controllers. But somehow this doesn't seem quite clean to me - its starting to use the app delegate just as a bucket for dumping miscellaneous functionality.
I'm thinking the model should deal with its own activity indication and the controllers should deal with their own, i.e. separate them. However if I did that wouldn't we then have the situation where a model is doing some UI related stuff (even if minimal)?
Is there a clean recommended solution?
IMO, Activity indicator is a View component independent of a specific view therefore it should be managed by your application delegate.
The way I tackled it is I created an ActivityManager class and I create and instance in my application delegate. It takes an instance of UIWindow and from that, I can determine how to center and display the indicator appropriately. All other areas of my application interact with this class through the observer pattern. They post notifications when the network state has changed and my activity manager evaluates the overall state of the application to see if it needs to either show or hide the indicator. Here is a sample of what you might see in my app:
ActivityManager *activityManager = [[ActivityManager alloc] initWithWindow:self.window];
self.activityManager = activityManager;
[activityManager release];
[self.activityManager addNotification:kNetworkStatusDidChangeNotification];
[self.activityManager addAsyncActivity:[HttpManager defaultManager]];
[self.activityManager startObserving];
I've added the ability to add new notifications so that way, when the manager observes these notification is can evaluate what needs to happen. AsyncActivity is just a protocol for singletons I can check to see if they are processing data. Then I just tell my manager to start observing. When I close my app I simply call:
[self.activityManager stopObserving];
to remove all observers and free up any memory. That should get you started in the right direction, I'm sure there are other ways to do it but that seems like the least invasive way to handle it to me. It's also very portable.
It sounds like there could be multiple network events occurring simultaneously that all need to report activity accurately. Perhaps a separate class that is only responsible for tracking network operations and communicating with your instance of UIApplication is in order.
Imagine an object that uses a simple counter to keep track of the number of network operations. Adding an event increments the counter and removing one decrements the counter. While the counter is > 0, the spinner is visible. This may be a reasonable approach to encapsulating communication between the application and the model layer.

What is the AppDelegate for and how do I know when to use it?

I'm just beginning to work on iPhone apps. How do I know when I should be putting stuff in AppDelegate versus a custom class? Is there a rule or any type of analogy with another programming language like Python or PHP that uses an AppDelegate like pattern?
I normally avoid the design approach implied by Andrew's use of the term "heart of your application". What I mean by this is that I think you should avoid lumping too many things in a central location -- good program design normally involves separating functionality by "area of concern".
A delegate object is an object that gets notified when the object to which it is connected reaches certain events or states. In this case, the Application Delegate is an object which receives notifications when the UIApplication object reaches certain states. In many respects, it is a specialized one-to-one Observer pattern.
This means that the "area of concern" for the AppDelegate is handling special UIApplication states. The most important of these are:
applicationDidFinishLaunching: - good for handling on-startup configuration and construction
applicationWillTerminate: - good for cleaning up at the end
You should avoid putting other functionality in the AppDelegate since they don't really belong there. Such other functionality includes:
Document data -- you should have a document manager singleton (for multiple document applications) or a document singleton (for single document applications)
Button/table/view controllers, view delegate methods or other view handling (except for construction of the top-level view in applicationDidFinishLaunching:) -- this work should be in respective view controller classes.
Many people lump these things into their AppDelegate because they are lazy or they think the AppDelegate controls the whole program. You should avoid centralizing in your AppDelegate since it muddies the areas of concern in the app and doesn't scale.
Your application delegate is the heart of your application. It's effectively your "Program Controller".
The Application Delegate is the class that receives application-level messages, including the applicationDidFinishLaunching message most commonly used to initiate the creation of other views.
While not exactly similar you could think of it as the "main()" routine of your Cocoa program.
#Shivam, thanks.
From what I understand of appDelegate, is close to what an Application is in Android. The viewDidLoad, viewDidDisappear is comparable to what Android's Lifecycle. Every application has a life cycle, from launching to interruptions from calls coming in, to notifications showing up. If you need your code to do something special when these system events occur then you need to write code the methods.
In Android we use onPause, onDestroy, onCreate kinda callback methods to handle such system events.
Hope this will help a little more ...
Programmers new to this language always have the same question - does the program start from a main method? Yes, you are right in this case; IOS apps also start from a main method. Your main class calls the below function:
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
UIApplicationMain kicks off the Cocoa Touch run loop and app infrastructure which creates a UIApplication object. Our application needs content so objective-c uses a delegate to handle this. That's why we call it AppDelegate (act as delegate of UIApplication). We implement some of the optional methods of that delegate and it behaves accordingly.

Resources