OverTheEther provides a simple way to programmatically send data from one iOS device to another one (or more) nearby. Be it short text messages, objects of custom classes or large image files. OTE uses CocoaAsyncSocket to send data via TCP. One device is configured as the server and others can connect to it as clients. A client can only be connected to one server but a server can be connected to as many clients as there are free ports. You just tell it which device to connect to and send whatever you want.
Simply add pod 'OverTheEther'
to your Podfile and run pod install
Drag all files in the /OverTheEther/Classes folder into your project. Then install CocoaAsyncSocket (e.g. via CocoaPods) and CocoaLumberjack. If you don't use CocoaLumberjack, simply go to the end of the Helpers.swift file and uncomment the block of function definitions to replace the log statements.
To run the example project, clone the repo, and run pod install
from the Example directory first.
let server = Server()
server.delegate = self
server.startServer(name: "ImageSharing", infoDict: nil)
let client = Client()
client.delegate = self
client.discoverServers()
//Implement this delegate method
func discoveredListOfServers(servers:[String]) {
//connecting to the first server in the list
client.connectToServer(name: servers[0])
}
let someObject = SomeNSCodingClass()
client.sendObject(someObject)
let someObject = SomeNSCodingClass()
server.broadCastObject(someObject)
//Implement this delegate method
func didReceiveData(data: AnyObject?, fromClient client:GCDAsyncSocket) {
//Received object is of type 'String'
if let string = data as? String {
print(string)
}
//Received object is of some other type
else {
print("Received: \(data)")
}
}
//Implement this delegate method
func didReceiveObjectFromServer(object:AnyObject?) {
//You can handle this just like in the example above ('if let ...')
}
-
You can only send objects which implement the NSCoding protocol. Many of Apple's own classes (e.g. NSString, NSData, UIColor, SKSpriteNode and loads more) already implement NSCoding. You can also send Swift's Int, String, [String:String](dictionary), etc. types, because they are bridged to Objective-C. If you don't know how to implement NSCoding in your own classes, I suggest this tutorial.
-
When you are sending your own classes between two different applications (meaning the classes are in differently named modules), you need to prefix these classes with
@objc(ABCSomeClass)
. ABCSomeClass can be any name that is unique in the context of Objective-C. Failing to to so will cause NSKeyedUnarchiver to throw an exception. Example:@objc(FTDSharedName) class SharedClass: NSObject, NSCoding { // Class Implementation }
-
Don't forget to set the delegate property and implement the delegate methods for both the server and the client.
Please note that this is still a work in progress. The code is not fully tested.
Known Issues:
- All files are saved in memory and not on disk, sending very large files (>100mb) may cause the watchdog to quit your app.
- Currently some low level details (e.g. the GCDAsyncSocket parameter in didReceiveData()) are still exposed. I'm working on making this a little bit more high level.