Disconnect external accessory without physically disconnecting - ios

My app communicates with an external device via EA Framework. I would like to do a "soft disconnect", i.e. a software disconnect without actually physically disconnecting the device. The only way I see for a soft disconnect is to close the EASession's inputStream and outputStream. Question: Will the external device know I have closed the streams so it doesn't attempt to communicate further? Is there another way to do soft disconnect?

i think that actually is impossible to do a real soft disconnection.
i say 'think' cause you never stop learning on EA Framework (One week ago i found the showBluetoothAccessoryPickerWithNameFilter for example, maybe is useful for you for inApp-connection).
I use a EASession(s) manager to easily switch between connections. so forgot the word 'disconnection' and replace it with 'switch' :D
If you need disconnection, implements some function on btdevice-side and execute this to disconnect as soon as you receive a command from the iPhone.

Related

MIDI messages are multiplying

I keep running into a strange issue when running AKMIDI on IOS. I also think it may be an IOS problem and not necessarily from Audiokit. I can connect a MIDI controller to IPad and receive messages as expected using the MIDI listener protocol after I open the input. If I disconnect the MIDI controller by cycling the power or unplugging it from the IPad and then reconnect it, I then start receiving two identical messages at each event. If I cycle the power again I start getting three messages, etc. I should also mention that when I detect the device is removed I close the input and clear the listeners. When I detect the new connection I open the input and start over. Does anyone know what can cause this to happen?
I think I have found a workaround for this:
If I only open the midi in and midi out one time, when my device is first detected, it seems to work correctly. I now only close the in and out when the app is terminated. You can cycle the power on the midi controller and it will still communicate with the app when it reconnects. I am also now using the more generic calls openInput(), addListener(self), openOutput().

APIs are not responding fast is APP is using Multipeer Connectivity framework

I am using Multipeer Connectivity Framework in my APP and its working absolutely fine but when APP is invoking any API or downloading any file from server then its delaying the response. Sometimes its failed and sometimes I am getting Time out error.
I have also checked "Network" status on xCode debug navigator and found that speed is going up and down instantly and never going beyond 6kb/s and sometimes its showing as 0 kb/s but when I disable Multipeer Connectivity then it works fine and speed going at 70kb/s too.
I have also noticed that if bluetooth is ON then its happening not with the Wifi.
Any suggestion would be really appreciable.
This is happening because when advertising, Multipeer always advertises on the wifi (there's no way to say bluetooth only). The way it advertises is by switching the wifi access mode into adhoc multiple times per second to find other peers, then switching back to AP mode (ie. resuming its connection to your wifi router). Doing this is highly disruptive to large transfers.
You have two options to fix this:
1) as soon as you can, after getting connected, call stopAdvertising(). This will stop the wifi mode from being constantly changed, and your throughput will resume at its normal rate. Warning: you cannot micro-manage this, because it takes up to 30 seconds after calling stopAdvertising() until it takes effect
2) switch from Multipeer to an alternative framework that allows you to specify bluetooth-only, and only use bluetooth. I wrote one called BluePeer which I use in my apps. It is unicast (not multicast) and supports roles like Client/Server (as well as role-less like Multipeer)

Why don't downloads switch back to wifi after been on a cellular network?

I have encountered a rather strange behavior when trying to implement download functionality on iOS. The download implementation works fine in that it finishes successfully, can run in the background, and file is stored on device. However during a download, I can turn of wifi to let the task switch to and continue on cellular network (or just start the download using cellular). This behaves as aspected. But when I enable wifi again, the download never seem to switch back to using wifi. The device is connected, and the wifi-connection-bars displays at the statusbar. Using rechability functions to check what connection that is available will even return Wifi, but the download seems to be stuck at using cellular.
The way I am detecting this is looking at the Usage stats in the system settings. The cellular data usage will rise in sync with the pending download, and continue to rise until the download is finished (even if wifi is turned on again).
I have tested with both Alamofire and by using NSURLSession and NSURLSessionDownloadTask directly, and they both behaves similarly. I have also seen this behavior in two completely seperate projects, on multiple devices, in iOS 8.4 and 9.1, when the apps are in the foreground or the background, and even AppStore behaves like this when downloading apps!
Has somebody else experienced this?
And if so, did you find any way to gracefully switch tasks back to wifi?
Thanks in advance.
This is normal behavior. Adding a new network interface (e.g. turning Wi-Fi on) doesn't stop existing TCP connections. They will continue until the original network interface goes away.
If you want to pause the request and reconnect when Wi-Fi becomes available, you'll need to call cancelByProducingResumeData: on the task, then create a new request with that resume data to restart the request from where it left off. That new request will go over the currently active network interface, which would typically be the Wi-Fi interface if Wi-Fi is up and running.
Before you stop the existing request, though, I would suggest trying a probe request for something like Google's generate 204 or one of Apple's captive portal detection URLs, to ensure that Wi-Fi really is working.

Failure to reconnect after De-authentication from Cisco AP Wifi

Apologizing in advance, I am no 802.11 expert and this is a long winded question...
I am working on an iOS voip client, we use the Cocoaasyncsocket library for our TCP/UDP connections. The app/iDevice is allowed to roam in/out of wifi coverage (for the purposes of this discussion we will assume the app is using wifi only... no cellular connection). We have the appropriate plist settings for backgroundmode (voip, audio) as well as requiring persistent wifi.
We are having a problem that seems particular to Cisco AP's. With the client app in the foreground and roaming out and in of wifi range, we noticed that eventually the iOS device will eventually not automatically rejoin the network. After a great deal of debug the failure to rejoin was noted to have nothing to do with the app. The failure to re-join can ultimately be reproduced by forcing the AP (via config) to deauthenticate the iDevice three times. After the 1st and 2nd deauthentications, the iDevice readily automatically re-joins. But after the 3rd time, iOS does not automatically rejoin the network.
The network will be rejoined if, for example, the iOS email app is put in the foreground.
We were curious if any other VOIP type apps suffered this problem, and ran an experiment with running FaceTime and Skype on the iOS device.
Skype behaved much like our voip app, after the 3rd deauth the connection was lost. Trying to initiate another call resulted in a message to the effect of "must have an internet connection to make a call".
FaceTime did disconnect on the 3rd deauth and failed to automatically rejoin... however, we were able to re-initiate another FaceTime call which caused iOS to rejoin the network and make the call.
We would like to emulate the FaceTime behavior, but so far do not understand what we should be doing differently. To the best of our knowledge, we are properly closing the open sockets when we get disconnected. Is anyone familiar with this issue and have some insight to offer?

Using Sockets & GameKit at the same time. Drastic socket speed reduction

I've encountered a pretty large issue and have been trying to find a solution for 2 months now with no luck. I've submitted it as a bug, ( https://bugzilla.xamarin.com/show_bug.cgi?id=4910 ) but was hoping maybe someone here could shed some light on the cause of the problem, or suggest a work-around.
In a nutshell, to encounter the error:
Create a basic .Net socket connection between two devices
Create and initialize a GameKit.GKSession object on a least one device.
What occurs is the transfer of the data on the .NET socket becomes erratic and too slow to be usable. I've performed many tests across different devices (see link below) and it affects all of them (iPad 3 affected the least). I've tested it between an iPhone and a Windows PC and it still occurs. MonoTouch's GameKit code is somehow affecting the Socket code.
As you can see from the spreadsheet, speed drop from a few milliseconds to send 1 MB to several minutes to forever.
As soon as the GameKit.GKSession is set to null, any backedlogged data on the socket flows freely again and the sockets act normally once more.
Sample Windows and iOS/MonoTouch Apps demonstrating problem: https://dl.dropbox.com/u/8617393/SocketBug/SocketBug.zip
Test results across different devices (PDF Spreadsheet):
https://dl.dropbox.com/u/8617393/SocketBug/SocketBugTestResults.pdf
This issue seems so hard even Apple decided to circumvent it: http://developer.apple.com/library/ios/#qa/qa1753/_index.html#//apple_ref/doc/uid/DTS40011315
The revealing sentence is this: "This change was made to reduce interference with Wi-Fi."
To assist with anyone that comes across this problem, the issue only manifests itself when the GKSession.Available is set to true. This is required for the device to be discoverable, but not to maintain a connection. With this in mind, a temporary work-around can be used where the GKSession.Available is only set to true when required, and set to false as soon as the connection has been made.
In my scenario, I have a socket connection to the server on both devices. I use this connection to send a message from device A to device B, asking it to become discoverable via bluetooth for the next 10 seconds. As soon as the message is sent, device A begins looking for device B and connects as soon as it finds it. Once the connection is established (or 10 seconds elapses without a connection), device B turns off discoverability and the socket behaves as normal.
In my circumstances, this is an acceptable (pending no real fix) workaround to the problem.

Resources