Okay so it's pretty obvious that push notifications aren't always reliable, as stated in the docs.
Correct me if I'm wrong, it's simply because someone might not have internet for an extended period of time and the notification could for example, expire, or get replaced, or even get lost for some cosmic reason.
I'm okay with that.
But as a junior programmer I used a lot of local notifications, not for display, but simply to call different methods when some processes where done.
Here is a simple example, when the app starts, I have a data-update process of, say, messages and stuff. When that update is done (about 3 seconds later), I send a notification that all my controllers listen to so they update their UI accordingly. If I'm on the home screen I'll show those little red badges, if I'm in a conversation I'll add the messages in the tableview, and so on.
And, as a junior developer, I had the chance to work with a senior developer who frowned upon this style. He says that it's just not reliable and I should use delegate callbacks and completion handlers. Which I find very hard to do considering the way the app is built. My system is literally a one-liner and never failed, whereas his system requires a lot of implementation of different methods in each separate class. It seems both redundant and messy.
I'm finally getting where I wanted : are notifications reliable locally, I'm talking about this :
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_SOMETHING_SOMETHING object:self];
with its addObserver: counterpart obviously.
Am I really wrong about chosing this work style ? What should I have done? Or is that okay? Or is that even awesome?
Sadly enough this is a quite opinion-based question because it's about standards and good practices, but I feel like it's not broad enough to be against the rules because I really really feel like someone is gonna bring a technical reason why this or that should/shouldn't be done, or clarify what should be used where and when.
Anyway, please ask me to clarify anything if need be, I'm genuinly interested in all the responses to come, and I'm looking forward to it.
There are different kinds of notifications in the iOS world, each really have different purposes and shouldn't be confused with each other.
push notifications:
these are the only ones not being reliable in the sense that they depend on a network connection and apple's push system...
UILocalNotification:
these are ways to notify your users upon certain events (you could compare it to a push notification only that it's not sent from a server but triggered locally by your own app)
NSNotification:
these are purely technical and basically they provide a broadcast mechanism that can be used to enable communication between certain parts of your app. i understand that on first sight it might seem handy to use NSNotification often in your code, because it's a simple and straightforward way to let 2 (or more) classes communicate with each other. however, you senior dev was right in that he advised you not to overuse this mechanism. mainly because it leads to a messy coding structure and doesn't scale well when your project becomes bigger. another huge issue is that it makes debugging very difficult. when using delegates or completion blocks on the other hand, you have a chance to structure your code in a reasonable way that ensures that you encapsulate functionality as you should, makes the code more readable and is way more appropriate to be used at scale.
Don't confuse NSNotificationCenter notifications with local (or remote) push notifications. They are completely different.
Notifications from NSNotificationCenter are reliable. No Internet is used for these. They are simple method calls made within your running app. They are just as safe as using other forms such as delegation.
Using NSNotificationCenter is great when you simply want to broadcast to the app that something has happened and you don't care who knows or how many listeners there are for the event.
The typical delegation pattern generally only works when there is at most one listener for the events.
Related
I'm not sure exactly how to correctly construct my question. It is actually more of a "what is the advised practice" instead of an "how to" type of question. So I'll try to explain my main goal first.
I've started writing a small app which allows users to fill out forms and send them to a server. But the connectivity is a real problem. Often there are times that these filled out forms must be saved on the device until wi-fi is available again.
The app has multiple view controllers, each with different jobs as you can imagine. I am thinking of writing a class which will be initialized during the app launch and will continue to run through out the apps whole life cycle. This class will periodically check for an internet connection and when available, upload saved forms to the server and than remove them from local core data database.
I've read about the background tasks, singletons, app delegate functions, global functions etc. And honestly I am confused. Every article and/or post I've read criticizes the other method with no one noting the correct way of doing this. "Globals are bad", "singletons are evil", "don't use app delegate" etc... I'm not sure what is the advised practice to achieve this.
Can we please discuss what is the preferred way to write a "self contained, periodic check and upload function" which is independent from any viewcontroller and will run in the background during apps whole life cycle.
Good day, everyone, I'm new to iOS development, programming in general actually, quick question, will my APP get approved if it does not has data persistence?
It's a quick and small text manipulation kind of APP, it reads the data, process it, then done with it (send out the results via email), I just don't see the needs of doing persistence, and also, the model is basically being put in the appDelegate, for each tabBarController to work with. Everything works just the way I expected, not sure if that's (no data persistence + use appDelegate to keep shared model) really and could get my APP rejected?
Thanks for your time answering my questions :)
The short answer: No. Your app will not get rejected.
Apps that's get rejected are usually violating something serious, like consuming to much CPU, calling Apples private APIs, responding to user input in an unpredictable manner or simply crashing etc - not just code design issues.
It sounds however like you should consider moving your model some place else, for the sake of ease the maintenance of your code.
Consider creating a modelClass that implements the Singleton pattern. The purpose and responsibility of the AppDelegate should be limited to starting up your app and controlling its lifecycle
I am trying to build an offline synchronization capability into my iOS App and would like to get some feedback/advice from the community on the strategy and best practice to be followed to do the same. The app details are as follows:
The app shows a digital catalog to users and allows them to perform actions like creating and placing orders, among others.
Currently the app only works when online, and we have APIs for all actions like viewing the catalog, creating/placing orders which return JSON data.
We would like to provide offline/synchronization capability to users, through which users can view the catalog and create/place orders while offline, and when they come online the order details will be synchronized and updated to our server.
We would also like to pull the latest data from the server, and have the app keep itself up to date in case of catalog changes or order changes that happened at the Server while the app was offline.
Can you guys help me to come with the best design and approach for handling this kind of functionality?
I have done something similar just in the beginning of this year. After I read about NSOperationQueue and NSOperation I did a straight forward approach:
Whenever an object is changed/added/... in my local database, I add a new "sync"-operation to the queue and I do not care about, if the app is online or offline (I added a reachability observer which either suspended the queue or takes it back working; of course, I do re-queueing if an error occurs (lost network during sync)). The operation itself reads/writes the database and does the networking stuff. My ViewController use a NSFetchedResultsController (with delegate=self) to get callbacks on changes. In some cases I needed some extra local data (it is about counting objects), where I have used NSManagedObjectContextObjectsDidChangeNotification.
Furthermore, I have used Multi-Context CoreData which sounded quite reasonable to use (I have only two contexts).
To get notified about changes from your server, I believe that iOS 7 has something new for you.
On the server side, you should read a little for the actual approach you want to go for: i.e. Data Synchronization by Dan Grover or Developing Android REST Client Applications (of course there are many more good articles out there).
Caution: you might be disappointed when you expect an easy solution. Your requirement is not unusual, but the solution might become more complex than you expect - depending on the "business rules" and other reasonable requirements. If you intelligently restrict your requirements you may find a solution which you can implement yourself, otherwise you may also consider to use a commercial product.
I could imagine, that if you design the business logic such that it takes an offline state into account and exposes this explicitly in the business logic, you may find a solution which you can implement yourself with moderate effort. What I mean by this is for example, when a user creates an order, it is initially in "not committed" stated. The order will only be committed when there is access to the server and if the server gives the "OK" that this order can actually be placed by this user. The server may also deny the order, sending corresponding messages to the user.
There are probably quite a few subtle issues that may arise due to the requirement of eventual consistency.
See also this question which contains pointers to solutions from commercial products, and if you visit their web sites give valuable information about the complexity of the problem and how this can be solved.
I noticed in a comment on this post Overhead of NSNotifications, user JustSid says
the overhead won't be noticeable if the App doesn't send out 30+ per run loop cycle
I'd like to write a little helper class that keeps track of how many NSNotifications have been sent on the current run loop cycle and alert me if it's above a certain pre-configurable number. I know I can register for all notifications (pass nil to name and object), but how do I track what run loop cycle they've been sent from?
It would be easy enough to have a category on NSNotificationCenter that increments some internal integer when a notification observer is added (and consequently decrements it when it is removed), but you have to ask yourself: How much is too much?
If you consider it to be some arbitrary integer (say, 30 for example's sake), then what happens when you test it on a device that has more memory and processor constraints than the one you have now? What happens if you test it on a device that can easily handle 30 observers and notifications floating around (it would be a complete waste)? While it would be possible to code general rules, it would be impossible to gauge the impact notifications have on application response time in every case.
The other possibility would be having a background process query the notification stack (or somehow just gauge it internally like above) when the amount of observers brings certain system functions to a crawl. Of course, ignoring the fact that this is way too much work, you'd be designing a sub-system which probably utilizes as much memory and steals as much away from performance as you tried to remedy with it in the first place!
TL;DR There are so many other patterns and structures you could be using instead of notifications, so why are you the one catering to NSNotification's needs?
I'm making a program for IOS for the first time. I never had a iPhone so I don't really get how it works...
I want to make my system able to call a webservice on the background and depending in the answer show a notification.
How can I do this?
I read on the Internet that I can push notifications to the phone, however that won't solve my problem because I want my server to track the user position, so it need the user to silently tell the server it's gps coordinates.
Thank you,
GustDD
I will suggest building the app first to run in the foreground. I will assume you already understand how to use the GPS, so will not go into detail on that.
First off, you will need to write the server backend and app pretty much simultaneously. There are many choices for writing the server backend language wise. I prefer python, others ruby on rails. You want to build a REST API for the server that the iDevice can talk to with simple HTTP protocol.
You must decide on the API. You must think about what kind of data you will want to send and receive and how you will wrap the data. Also what HTTP protocols will you be using for specific requests, like GET POST etc. Furthermore, you will have to decide at what URL's on the server will it be useful to GET or POST to depending on the data you want to send or receive. I would suggest you use JSON to wrap your data. It is quite intuitive and easy to encode and decode.
Next you will have to decide how to talk to the server in iOS. There are many great third party libraries that dress up NSURLConnection or you can use NSURLConnection itself (sometimes a bit tedious). I personally like to use AFNetworking. It will do the JSON decoding and encoding for you which is a big bonus.
Finally, once you have the two communicating with how you want and with the data you want, now time to dress it up. You can allow your app to run in the background and collect GPS data and send it. You can also use the notification center to display information it gets from the server in the background.
Update to Comment
This will be extremely helpful for you with background programming. From an Android perspective, iOS is a little bit different since there is not really a direct correlation for Android services in iOS. Every little detail to put your project together is in that link.