I have just delivered a prototype for a big client, everything was fine but I'm now curious to know if the solution/architecture I've chosen was the right one or there's place for improvement in case the project will keep on.
The task was to build two iOS apps: one running on 5 different iPhones, and another running on 2 iPads. Basically the iPhone applications had to communicate information to the iPads, and occasionally they also had to send information between each other (iPhone to iPhone). All the infos where small JSON objects/chunks whose size was small, really small.
The app was not intended to reach the app store, is a working prototype to test out some ideas in a user testing environment.
I discarded bluetooth because we are talking about a peer-to-peer communication, not a one-to-one.
What I did was to use web sockets thanks to SocketIO, through a small Node.js server that was running on my mac. The server was really simple, just receiving the messages from the clients and broadcasting information to the other ones.
What do you think? Is the solution I've chosen ok, or there are better ones?
For example, this morning I've just found out these thread here on SO, and I've discovered I could have used GameKit. What do you think?
Socket.IO is nice because it is fairly simple to implement but it has the downside of requiring a central server. If you wanted to avoid that, you could use the Multipeer Connectivity framework that was introduced in iOS 7.
It will let you create one-to-one communication channels between devices on either the same WiFi network or Bluetooth. Once the channel is created, you can send whole NSData objects (or create streams but it doesn't seem relevant to your use case).
A good read : http://nshipster.com/multipeer-connectivity/
The WiTap sample from Apple demonstrates peer-to-peer networking over Wi-Fi and Bluetooth. Using Bonjour, the application both advertises itself on the local network and displays a list of other instances on the network. Supports infrastructure networks, peer-to-peer Bluetooth, and peer-to-peer Wi-Fi (on compatible hardware).
I have personally tested it and it works fine and well documented.
I think socket.io is the best choice. It is built on top of engine.io (which in turn is built on the fastest websocket implementation: ws) It has oldest to newest fallbacks, so it starts with long polling and works its way up. This guarantees a quick initial connection instead of needing to poll the device for features. You can read more on this here. Best of all, it handles everything seamlessly. You write your code as if websockets are supported on connecting devices and if not it will use other methods behind the scenes.
This post details many of the websocket libraries you could use with your server. Which websocket library to use with Node.js?
I am convinced Bonjour is the best solution:
Apps can also leverage Bonjour to automatically detect other instances
of the app (or other services) on the network.
However I've never used it myself; perhaps someone who has can comment?
Related
I'm most likely not using the correct terminology in my question.
Is it somehow possible for an iphone to receive an "audio stream" from other iPhones over Bluetooth?
The idea is to make an app that makes it possible to listen to the music libraries of other iPhones in the Bluetooth range. All while not having access to the internet and not needing to pair up and transfer the actual song onto the phone.
The thing you ask of is doable, but is not something trivial. Bluetooth communication can be implemented to work like a TCP/IP socket implementation, the only problem is, there is no actual protocol to follow. Usually the apps that implement bluetooth communication use they own protocols definitions in order to serve the purpose of the app.
There are several steps that have to take in consideration:
The transfer speed over bluetooth, it's not fast but it's not slow either, the main problem with the transfer over bluetooth is that you have to implement the data transfer, for example in TCP/IP the whole package exchange (send/acknowledge/receive) is done by the system, there's no general protocol implementation to do such thing using bluetooth.
The connection handling, this is something really tricky depending on OS & OS version, especially on iOS the connect/disconnect handling is clumsy & often buggy.
Security, without pairing and bonding there's no security. Even with pairing & bonding the security is flacky. Without security you might get your app hammered down and bricked by a simple bluetooth sniffer.
Other apps that use bluetooth, for IoT or other gadgets this is not an actual problem, but when you have a client/server like approach via bluetooth using two mobile phone you might get in trouble because of other apps that wrongly use the bluetooth (don't close connections, try to scan to frequently) and you can't do anything about it.
These are the things that cross trough my mind about the bluetooth communication, I've worked on several apps that connect to IoT and I can tell you it's not something trivial to implement. You get a lot of headache for things that you can't imagine.
As an alternative you could use WI-FI without internet connection, there was a trending post some time ago about Mesh Networks that use only the WIFI signal to transmit data, not even actual wifi network, worth checking out IMO.
I’m not talking about Reachability.
What I’m talking about is figuring out how to create a network connection from an iOS device across the cellular interface.
Why? Because I have conditions where the device connects to a WiFi access point so it chooses WiFi… but that access point is not internet connected and goes nowhere. I have data which I must make every effort to deliver and it some cases it’s getting lost in the WiFi gateway to purgatory. In both cases of using Reachability and relying on MPTCP, Apple has already given priority to WiFi in the stack.
I know NSURLSessionConfiguration can set allowsCellularAccess to allow cellular access — I’m looking to require cellular for the routing.
Even at the CFNetwork level I’m looking at kCFStreamPropertyConnectionIsCellular for status, kCFStreamPropertyNoCellular to disable cellular.
I can’t find anyway to give preference to the cellular radio. I realize Apple has gone to great lengths to prefer WiFi and I’m going against that — which is why I’m having such difficulty finding an answer to this.
I'd like to keep this up in the Cocoa level, but not opposed to going into Foundation or deeper levels. I would like to avoid trying to parse an interface table (if it's even accessible) to figure out which is the cellular interface.
Has anyone successfully created a network connection across the cellular link despite WiFi appearing to be present?
Is some configuration of Multipath TCP the answer here?
To bind to a particular interface, as far as I'm aware, you'd have to drop all the way down to the raw socket level, and there's no way to provide a custom socket for NSURLSession purposes, so you'd basically be rewriting it from scratch. You should file a bug asking for support for binding an NSURLSession to a source IP.
The behavior you're experiencing is a known problem with iOS and disconnected networks. iOS 9 and later do a better job, but even then, they can be highly problematic; the devices sometimes refuse to talk to the Wi-Fi network, and sometimes refuse to talk to the cellular network. Specifically, it seems to fail spectacularly if either signal is weak. Just this morning, I actually had to force my iPhone (iOS 10) to talk to a disconnected Wi-Fi network by putting it in Airplane mode and enabling only Wi-Fi.
I'm told that you can fix this by configuring the network's DHCP server to not provide a router advertisement; that said, every time I've tried that, the iOS device would just keep asking for an offer repeatedly. Maybe that bug got fixed at some point. If so, it might be worth a shot, but don't expect it to work in older versions of iOS.
Failing that, assuming you don't need to support web browsers in iOS 3 and earlier, you might try eliminating the DHCP server on that Wi-Fi network entirely, and just rely on DNS service discovery with zero-conf IPs. That way, the device won't see a router, and it won't try to send data out that interface except to those link-local IPs.
If that isn't possible for some reason, ordinarily I would suggest using a customized copy of libcurl, except that I doubt this will work in your case, because POSIX networking doesn't wake the cellular hardware.
In iOS 12 and later you can use the Network Framework. Sample code is here.
Apologies in advance for the general-ness of the question.
I'm writing a multiple client iOS app for viewing the video feed from a single camera. Can the QX10 api support two (or 3) iPad's discovering/viewing the same QX10 at the same time?
I've been looking QX10 sample code, the camera api docs, StackOverflow, and of course the dev website and haven't seen an answer. I'd just buy the bloody thing to test with, but there are none nearby and I was hoping to avoid having to mail order/return it if it didn't work.
....And we're not locked into HW. If there's a better option, I'm open....
I don't believe it does. For ios, the camera creates a network that the ios connects to. (In ios settings/wireless) Any further attempts to connect to the camera from another device fail. Since the API only works after a network connection is established, I don't see how the API could possibly allow 2 devices could connect at once.
(No extraneous words in this post b/c that will get edited which auto down votes the question.....ahhh internet)
I did not try it, but you could use a computer with nat. For example an openrwt router to open up multiple wifi interfaces, one to connect to the camera, using the 10.0.0.0 network the camera uses and then an other network to connect your clients with NAT.
The question would be when the API would start to get confused.
So depending on what you want, maybe some mapper on that helper-computer could
do some proxying of information.
So in theory with an external box, maybe, but as Oldmicah said, it seems that only
one device can connect at the time (at least my QX100 also behaves like that). :(
I have a situation where I would like to communicate between 2-4 devices over the 3G network (it should also work over WLAN, but 3G solution is critical).
Every device (except one) asks for a GPS-location every ~5 seconds, but when this process is cancelled by the user of that device, one device needs to be informed of this event.
I was thinking that one device could act as a server, and the rest as clients that should connect to the server. Is this possible over the 3G network?
I've also read about push-notifications, is this relevant here? Can you receive notifications without disturbing the user with a popups etc?
Are there other ways?
Basically I would like to use apple "standard" solutions (if there are any) before diving into eventual socket-programming or anything similar...
What I would like to avoid is to have a webserver or some similar "3rd-party" solution, because I don't want many users to simultaniously connect and "pull" from the same external server in a final solution...
UPDATE:
Basically my application will have thousands of users that will need to be informed if an even occurs. Also this happens simultanously ~5 second, what would be the best solution to reduce load and avoid spamming?
I was thinking that one device could act as a server, and the rest as
clients that should connect to the server. Is this possible over the
3G network?
It could work, but having a dedicated server would be a better choice
I've also read about push-notifications, is this relevant here? Can
you receive notifications without disturbing the user with a popups
etc?
In your case no, since you will need a server to communicate with apple
Basically I would like to use apple "standard" solutions (if there are
any) before diving into eventual socket-programming or anything
similar...
There are no standard solution, other than you should probably rethink about using a dedicated remote server for this
iPhones can't communicate directly with each other using 3G. You can access the internet through the 3G, but you can't do peer-to-peer as you are suggesting. If you were close enough, you could use bluetooth, but I expect you are too far away.
You would have no way of detecting the one device that acts as a server from the other devices. The IP address could (and probably would) change every time the device connects to a mobile data network. You would need a central server to co-ordinate all of the clients.
You have multiple questions, but I'll try to address as many of them as I can:
I was thinking that one device could act as a server, and the rest as
clients that should connect to the server. Is this possible over the
3G network?
No, you cannot run a server on a iPhone/iPad that is accessible over 3G without an external website acting as an intermediary. (You can run one that is accessible over Wi-Fi, but this does not solve your problem as stated.)
I've also read about push-notifications, is this relevant here? Can
you receive notifications without disturbing the user with a popups
etc?
Push requires you (or a third party contracted by you) to have a web server, so if you want a server-free solution it is not relevant here.
Are there other ways?
Over 3G you will, under the current Apple restrictions, always need an external server.
Basically I would like to use apple "standard" solutions (if there are any) before diving into eventual socket-programming or anything similar...
Diving won't help you here. Even using low-level socket programming you will not be able to run a server on an iPhone accessible over 3G without an external website to aid in establishing a connection.
You can try using GameCenter. The mechanism of network games in Game Center allows connect up to four players with no third-party solutions.
I want to get to know how I can transfer data easily between 2 iPhones, over wifi. I would like to know if I could do that without having a server or database, but within an app (so without using email).
Game Kit has support for Peer-to-Peer-Connectivity and is, despite the name, not only usable for games:
The GKSession class allows your application to create and manage an
ad-hoc Bluetooth or local wireless network, as shown in Figure 1.
Copies of your application running on multiple devices can discover
each other and exchange information, providing a simple and powerful
way to create multiplayer games on iOS. Further, sessions offer all
applications an exciting mechanism to allow users to collaborate with
each other.
You can also check out Bonjour API from Apple. I am not sure if you need a static IP for it to work or it can just work over wifi. Just trying to give a pointer.
Based on your exact usecase, it can work well.
Check it out here, Game center is also there.
http://developer.apple.com/technologies/ios/networking.html