Swift: Show UIAlert while waiting for semaphore - ios

I'm using CocoaAsyncSocket pod to transfer data from measurement instrument to an iOS device. The transfer works pretty well, but I get in trouble, if I have to switch between different mobile instruments.
If I need to change the instrument / connect to another instrument, I have to wait for some events:
I have to be sure to be disconnected. This is typically done by waiting for public func socketDidDisconnect(...) included in the GCDAsyncSocketDelegate
I have to connect to the other instrument. If it is still the tcp interface, I have to wait for public func socketDidConnectToHost(...)
So there are two operations which take some time. Because there is no valid connection, the user just can wait. To inform the user what's going on, I would like to present an UIAlert until the mentioned events are finished. How can I achieve this?

Semaphores seem way too low level for your case, unless you are doing it for educational purposes.
Using NotificationCenter instead:
1) Post a "didDisconnectNotification" (string name being arbitrary) from socketDidDisconnect(...) and in it's corresponding handler update your viewController UI indicating the user a connectivity problem.
2) Post a "didConnectNotification" from socketDidConnectToHost(...) and in it's handler (distinct from 1) dismiss the connectivity problem indicator^.
Note: On your viewController first appearance you would probably start with 2) so there's nothing yet to dismiss.
You can find numerous examples related to NotificationCenter on SO:
https://stackoverflow.com/a/24756761/5329717
In a scenario where the two aforementioned operations are independent (i.e. they can occur in any order relative to each other) the GCD mechanism to use would be DispatchGroup. It's somewhat closer to your attempt at using a semaphore, however you don't need it either because your 2 events (disconnect & connect) are dependent (i.e. their respective order of occurence is fixed).
An example valid usage case of DispatchGroup would be synchronising responses of many image fetch requests when you don't care about their order of arriving (you either get all of them or do not proceed).

Related

Notifying ViewController from model(networkClient) in swift

I have some complex networking in my app( I don't use any third party dependencies, because of project requirements). For instance, I send three network requests in parallel after first two requests provide results. All my networking is done in separate models, known as networkClients(following MVC-S pattern) and are called directly from repository, not from ViewControllers. However, I need the last request to notify my viewController after I get response from network. How should I do that? I don't think notification center would be right solution because it can cause memory leaks and I have not found correct approach to complex problem like this. Please provide some prominent solutions. It should conform to good design pattern like MVVM or MVC and should not be some workaround or hack. Maybe delegates would work? I know that rxSwift would solve my issue, because I could start observing for results after initializing viewController and after data would be updated from repository my viewController would also be notified...
The right design doesn't have VCs observing the network clients directly. Those network operations should be assembling parts of a model, which is what the VC really cares about. Have the VC observe that singular model.
It can do this observing using one of the well known patterns for loosely coupled communication between objects. The OP correctly mentions delegates. Notification center and KVO are others. There's plenty of discussion on SO about which to use and how to implement. (I'd go with NSNotificationCenter as an easy and rational start).
So the order of operation is like this:
allocate the model
launch the network requests and setup those request completions (completion blocks, probably) to update that model with their responses. (the model can launch the requests, which is a reasonable practice).
create the view controller(s) that setup model observation when they initialize (probably, in viewWillAppear or later)
What about the fact that >1 requests are in flight simultaneously? A commenter above points out correctly that GCD offers a way to group those async operations into a single one. But you can do this yourself straight-forwardly: the model decides when it's completely built. The completion code for each request will change some condition in the model to the "ready" state. Each request completion can check to see whether all of the ready conditions are met, and only then post a "ready" notification for observers to see.
Another niggling issue: what if those requests all run very, very fast? Maybe there's some cached response that's ready early, making the model "ready" before the VC has had a chance to setup observation? Handle this straight-forwardly in the VC: before observing the model, check to see if it's ready already and run the same update code that runs on the notification.

Async logging of a static queue in Objective-C

I'd like some advice on how to implement the following in Objective C. The actual application in related to an AB testing framework I'm working on, but that context shouldn't matter too much.
I have an IOS application, and when a certain event happens I'd like to send a log message to a HTTP Service endpoint.
I don't want to send the message every time the event happens. Instead I'd prefer to aggregate them, and when it gets to some (configurable) number, I'd like to send them off async.
I'm thinking to wrap up a static NSMutableArray in a class with an add method. That method can check to see if we have reached the configurable max number, if we have, aggregate and send async.
Does objective-c offer any better constructs to store this data? Perhaps one that helps handle concurrency issues? Maybe some kind of message queue?
I've also seen some solutions with dispatching that I'm still trying to get my head around (I'm new).
If the log messages are important, keeping them in memory (array) might not suffice. If the app quits or crashes the NSArray will not persist on subsequent execution.
Instead, you should save them to a database with an 'sync' flag. You can trigger the sync module on every insert to check if the entries with sync flag set to false has reached a threshold and trigger the upload and set sync flag to true for all uploaded records of simply delete the synced records. This also helps you separate your logging module and syncing module and both of them work independently.
You will get a lot of help for syncing SQLite db or CoreData online. Check these links or simply google iOS database sync. If your requirements are not very complex, and you don't mind using third party or open source code, it is always better to go for a readily available solution instead of reinventing the wheel.

When to refresh data in iOS

I'm not sure this question is strictly limited to iOS, as it's more of a general application-design question on data integrity. But at the moment, I'm getting into iOS and have hit a "best practice" wall.
If we use the Twitter app as an example. We have one tab for our timeline and one tab for our profile. So (to keep things very simple) each one is a View Controller, backed by an object (model). I tweet on the timeline VC, then I head on over to my profile tab. Both viewDidLoad methods have already ran, so the data that was loaded to draw the UI is currently stale. The "count" of my tweets is now out of date. In the iOS world, what is the best methods/approaches to keeping the VC model data synced with the backend?
Is it on a time interval? Or network requests in the viewWillAppear method? Is it event driven, ie. when I tweet in one VC, and it's been saved in the backend web service, I notify any VCs that care that there's a new tweet
I'm not 100% sure this question will have an "answer" in the SO sense, but I'm just trying to understand what's the done thing in the iOS world (as someone who comes from the web development world).
Here's a loose sketch of some things our team has done on a networking application that might give you insight for your own architecture.
At the level of the VC (in viewWillAppear) we typically have multiple NSNotificationCenter observers that will call whatever update methods you need to run after a network update call.
Firing off these notifications is some network listener that lives on a background thread. It's job is to wait for responses from the backend server (typically JSON blobs) that contain updates to the data model. I believe ours has a time interval that will periodically phone home and check to see if we have new things to update.
Note you will necessarily have to devise an asynchronous solution for network calls as the passing/receiving of data packs can be unreliable, and take time, and thus should be computed in the background. You'll also need a way to handle data loss and other errors between server and device. And of course in order to see UI updates, you'll need to switch back to the main thread when updating the VC.
Assuming a some change of state (i.e. new message), then it makes the call to get the new data, which then fires off an NSNotification (with a new payload of info), that goes to the observer on the VC.
As you mentioned with viewWillAppear, UIViewControllers are a core building block of iOS apps. They have a lifecycle to follow to help with things like this scenario.
You have many options, but the best practices would to make calls on the viewWillAppear method and then reload your table views, collection views, etc.
Another thing you can add is push notifications on data change. You can now send a push notification with the "content-available" option that is silent and sent to your app when data changes on the backend. Then your app can refresh data only when needed.
I would stay away from timers. They will keep making network request and keep the radio from going into a battery saving idle mode.

Arduino non blocking Wifi connection

I'm putting a system that monitors a few sensors and based on them it turns a few lights on/off.
For further data analysis we also want to send that data to a central server, so we've added a Wifi shield. Keep in mind that the system should be fully functional if there's no network. So what I've done is monitor the network status in the loop() and connect again if it goes down.
Now, the problem is that Wifi.begin() blocks execution until is either connected or throws an error. This is not acceptable since during that time the system would be unresponsive.
I've looked into using threads in Arduino, for example here, but then this shows up in the Limitations:
One of the major potential problems with this library is the fact that
a single Thread that gets hung will lock the entire system up, since
the next Thread can’t be called until the current one finishes its
loop() function.
So, anyone has any pointers, ideas or experience?
Thanks,
Juan
You could create a timer interrupt that when expires kills the thread with the stalled blocking function.
Actually you may want to use an Interrupt such as Timer1 library to perform the critical updates. That way you don't need to worry about blocking code, anywhere.

NSURLConnection getting limited to a Single Connection at a time?

OK - let's rephrase this whole question shall we?
Is there any way to tell if iOS is holding onto an NSURLConnection after it has finished & returned it's data?
I've got 2 NSURLConnections I'm instantiating & calling into a server with. The first one initiates the connection with the server and then goes into a COMET style long-polling wait while another user interacts with the request. The second one goes into the server and triggers a cancel mechanism which safely ends the first request and causes both to return successfully with a "Cancelled by you" message.
In the happy path case the Cancel button will never be clicked. But it's possible to click it and exit the current action.
This whole scenario works GREAT once. And then never works again (until the app is reset).
It's as though the first time thru one of the connections is never released and we are from then on limited to only a single connection because one of them is locked.
BTW I've tried NSURLConnection, AFNetwork, MKNetworkKit, ASIHTTPRequest - no luck what-so-ever with any other frameworks. NSURLConnection should do what I want. It's just ... not letting go of one of my connections.
I suspect the cancellation request in Step 2 is leaving the HTTP connection open.
I don't know exactly how the NS* classes work with respect to the HTTP/1.1 recommendation of at most two simultaneous connections, but let's assume they're enforcing at most two connections. Let's suppose the triggering code in Instance A (steps 1 and 3 of your example) cleans up after itself, but the cancellation code in Instance B (steps 2 and 4) leaves the connection open. That might explain what you are observing.
If I were you, I'd compare the code that runs in step 1 against the code that runs in step 2. I bet there's a difference between them in terms of the way they clean up after themselves.
If I'm not wrong,
iOS/Mac holds on to a NSURLConnection as long as the "Keep-Alive" header dictates it to.
But as a iOS developer you shouldn't be worried. any reason why you would like to know that?
So unfortunately with the lack of a real solution to this issue being found in all my testing I've had to implement simple polling to resolve the issue.
I've also had to implement iOS only APIs on the server.
What this comes down to is an API to send up a command and put it into a queue on the server, then using an NSTimer on the client to check the status of the of the queued item on a regular interval.
Until I can find out how to make multiple connections on iOS with long-polling this is the only working solution. Once I have a decent amount of points I'll gladly bounty them away for a solution to this :(

Resources