A little vague in the title, but I want to know what others are doing about this. I wonder:
If you use Reachability, do you perform any additional checks or are
you fully confident that the notifications will take care of
everything?
Has anyone had any issues with their WiFi working, but
Reachability returning false despite that there's an active connection? (I haven't myself, but have read about it somewhere).
I use it, and have not had any issue with reliability of detecting WiFi connectivity. It has worked fine for me when used properly.
Related
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.
I have read up on the Reachability framework and am still confused why the definition of a host is being reachable is "when a data packet... can leave the local device".
If reachability returns "yes" then it seems that I still need to try and make a socket connection and until that actually connects I do not really know my host is up. Why doesn't Reachability use a Ping to get a better idea of whether the host is actually up? And what is the need of this framework in the first place?
My guess is these two, but if anyone knows any other reasons to use the Reachability framework please let me know.
1) Reachability gives a callback which gives instant notification when the internet comes back up. When this occurs a socket connection can be immediately attempted. However in 99% of applications it seems acceptable to just attempt a socket connection every few seconds, or worst case just try to make the connection when a user does a certain action. Granted, this is not an ideal solution but I don't see why the Reachability framework would ever be really necessary for this reason.
2) Even in the case where a socket connection has been made to the server, Reachability gives an important bit of information about whether the network is G3/WiFi. I think this is the only time Reachability is really necessary because it allows optimization of behavior according to network type.
Reachability is actually quite useful: Given your case (1), you forget that it gives you notifications on both network up and down events. Meaning you can set the callback to handle events such as losing network connectivity (which happens more than you would like on both WiFi and 3G).
Additionally, testing a connection using a socket is not that straightforward; Socket operations are , by default, blocking, and though you can use asynchronous operations (or threads), doing so involves writing code. Not to mention trying DNS when the network is down, and other such issues. By setting a reachability target using the framework, you can alleviate the need to handle all sorts of issues like these yourself, and simply wait for that callback.
Hope this helps,
TG
We're writing an application which uses our http api, and occasionally it will encounter errors, failed connections, timeouts, etc.
We'd like to, at least in beta, be able to capture these incidents, and forward them to ourselves somehow. Since obviously many of these issues could be due to the actual connection being down, this would need to queue these incidents and send them when a connection is available.
I tried googling for an answer for this but to no avail, came across a bunch of solutions which catch exceptions, but not just random "incidents" (could really just be a string we log somewhere, we'd just include all the details in it).
Short of writing my own coredata (or something) backed queue, I'm at a loss at what a solution for this could be.
Does anyone know of any libs/services which could help with this?
You might want to look into Testflight, or less general purpose, Parse. Not quite sure, but maybe HockeyKit offers a solution for this, too.
You can take a look at Bugfender, it's a product we have built to solve this problem. We have found that while developing an app there are a lot of issues that are not crashes, so we decided to make our own product to help us on this.
It's easy to integrate and you can get the devices logs. Our service works offline and online, we have spent a lot of time to make it reliable and easy to use.
Compared to other products, you don't need any crash to get the logs, you choose when you want them.
I am learning C and Objective-C so am still dependent on examples...
I found AsyncUDPSocket which has a lot of example code in the Google Code repository, but I'm not far enough along to understand it all yet.
I'm trying to build an iPhone app that uses UDP for communication to another device (Arduino). I have the device end working (testing with the UDP Tool app). I just need help with the iOS side of it...
An example with more explanation would really help (that is, a tutorial)... Is there one or what would some example code with good comments be?
https://github.com/robbiehanson/CocoaAsyncSocket
GCDAsyncUdpSocket and AsyncUdpSocket are UDP/IP socket networking libraries. Here are the key features available in both:
Native objective-c, fully self-contained in one class. No need to
muck around with low-level sockets. This class handles everything for
you.
Full delegate support.
Errors, send completions, receive completions, and disconnections all result in a call to your delegate method.
Queued non-blocking send and receive operations, with optional
timeouts.
You tell it what to send or receive, and it handles everything for you. Queueing, buffering, waiting and checking errno - all
handled for you automatically.
Support for IPv4 and IPv6.
Automatically send/recv using IPv4 and/or IPv6. No more worrying about multiple sockets.
I read some of the similar posts on this site that deal with what seems to be the same issue and the responses didn't really seem to clarify things for me.
My application works fine in the simulator. I believe I'm on Bold 9000 with OS 4.6. The app is signed.
My app makes an HTTP call via 3G to fetch an XML result. type is application/xhtml+xml.
In the device, it gives no error. it makes no visual sign of error. I tell the try catch to print the results to the screen and I get nothing.
HttpConnection was taken right out of the demos and works fine in sim.
Since it gives no error, I begin to reflect back on things I recall reading back when the project began. deviceside=true? Something like that?
My request is simply HttpConnection connection = (HttpConnection)Connector.open(url);
where url is just a standard url, no get vars.
Based on the amount of time I see the connection arrows in the corner of the screen, I assume the app is launching the initial communication to my server, then either getting a bad result, or it gets results and the persistent store is not functioning as expected.
I have no idea where to begin with this. Posting code would be ridiculous since it would be basically my whole app.
I guess my question is if anyone knows of any major differences with device versus simulator that could cause something like http connection or persistent store to fail?
A build setting? An OS restriction? Any standard procedure I may have just not known about that everyone should do before beginning device testing?
Thanks
Just providing the URL will not work. You will have to append some info after the URL to determine the transport method your HTTP connection will use. For instance http://example.com;deviceside=true will use DirectTCP (you might also have to supply APN information but that's saved on the device for my phone). http://example.com;interface=wifi will use wi-fi. On OS 5 there's a ConnectionFactory class that makes this a lot easier. Here's a link that goes into more detail.
This was a tough one for me!
As Jonathan said you have to put some parameters in the url to make it work on the device. You shouldn't do it by hand but use the ConnectionFactory instead.
As you may thing this would just make it work but it doesn't!
The real problem is that not the url has been altered because it has ;interface=wifi;deviceside=true in it (in my case). Depending on the webserver accepting your request this could broke the code.
A solution I tried and that works is try to happend a fake parameter like
&foo=true -> &foo=true;deviceside=true
This will result as a standard parameter for the webserver but your device would use it to driver your connection.
On the simulator this work without this extra code because behind it there is a BIS server for you. On the device (as in my case) there isn't because I'm using a development device unregistered and without SIM (just wifi).
Another point is that the HttpConnection class doesn't handle HTTP 302 Redirect and if you get one you have to handle it manually.
It's probably an issue with the APN not being specified. See my answer for this question for details:
video streaming over http in blackberry
I would make this a comment, but I think I don't have enough rep yet for that... So I'll just answer and hope this doesn't get hosed for just pasting in some links.
I've been working on this exact sort of networking issue on our app this past week, and it is indeed tricky as some others have pointed out. Here are two links which really helped us out using HTTP on different devices, especially older devices which do not provide ConnectionFactory.
http://supportforums.blackberry.com/t5/Java-Development/Connecting-your-BlackBerry-http-and-socket-connections-to-the/td-p/206242
The first one has some code examples, including demonstration of querying the system's ServiceBook and CoverageInfo classes to make a decision about what kind of connection will work.