-
-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
247 additions
and
76 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
21 changes: 21 additions & 0 deletions
21
Sources/MultipeerKit/Internal API/MockMultipeerConnection.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Foundation | ||
|
||
final class MockMultipeerConnection: MultipeerProtocol { | ||
|
||
var didReceiveData: ((Data, PeerName) -> Void)? | ||
|
||
var isRunning = false | ||
|
||
func resume() { | ||
isRunning = true | ||
} | ||
|
||
func stop() { | ||
isRunning = false | ||
} | ||
|
||
func broadcast(_ data: Data) throws { | ||
didReceiveData?(data, "MockPeer") | ||
} | ||
|
||
} |
65 changes: 65 additions & 0 deletions
65
Sources/MultipeerKit/Internal API/Models/MultipeerMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import Foundation | ||
|
||
struct MultipeerMessage: Codable { | ||
let type: String | ||
let payload: Any? | ||
|
||
init(type: String, payload: Any) { | ||
self.type = type | ||
self.payload = payload | ||
} | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case type | ||
case payload | ||
} | ||
|
||
private typealias MessageDecoder = (KeyedDecodingContainer<CodingKeys>) throws -> Any | ||
private typealias MessageEncoder = (Any, inout KeyedEncodingContainer<CodingKeys>) throws -> Void | ||
|
||
private static var decoders: [String: MessageDecoder] = [:] | ||
private static var encoders: [String: MessageEncoder] = [:] | ||
|
||
static func register<T: Codable>(_ type: T.Type, for typeName: String, closure: @escaping (T) -> Void) { | ||
decoders[typeName] = { container in | ||
let payload = try container.decode(T.self, forKey: .payload) | ||
|
||
DispatchQueue.main.async { closure(payload) } | ||
|
||
return payload | ||
} | ||
|
||
encoders[typeName] = { payload, container in | ||
try container.encode(payload as! T, forKey: .payload) | ||
} | ||
} | ||
|
||
init(from decoder: Decoder) throws { | ||
let container = try decoder.container(keyedBy: CodingKeys.self) | ||
type = try container.decode(String.self, forKey: .type) | ||
|
||
if let decode = Self.decoders[type] { | ||
payload = try decode(container) | ||
} else { | ||
payload = nil | ||
} | ||
} | ||
|
||
func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
|
||
try container.encode(type, forKey: .type) | ||
|
||
if let payload = self.payload { | ||
guard let encode = Self.encoders[type] else { | ||
let context = EncodingError.Context(codingPath: [], debugDescription: "Invalid payload type: \(type).") | ||
throw EncodingError.invalidValue(self, context) | ||
} | ||
|
||
try encode(payload, &container) | ||
} else { | ||
try container.encodeNil(forKey: .payload) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foundation | ||
|
||
typealias PeerName = String | ||
|
||
protocol MultipeerProtocol: AnyObject { | ||
|
||
var didReceiveData: ((Data, PeerName) -> Void)? { get set } | ||
|
||
func resume() | ||
func stop() | ||
|
||
func broadcast(_ data: Data) throws | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
68 changes: 68 additions & 0 deletions
68
Sources/MultipeerKit/Public API/MultipeerTransceiver.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import Foundation | ||
import MultipeerConnectivity.MCPeerID | ||
import os.log | ||
|
||
public final class MultipeerTransceiver { | ||
|
||
private let log = MultipeerKit.log(for: MultipeerTransceiver.self) | ||
|
||
let connection: MultipeerProtocol | ||
|
||
public init(configuration: MultipeerConfiguration = .default) { | ||
self.connection = MultipeerConnection( | ||
modes: MultipeerConnection.Mode.allCases, | ||
configuration: configuration | ||
) | ||
|
||
configure(connection) | ||
} | ||
|
||
init(connection: MultipeerProtocol) { | ||
self.connection = connection | ||
|
||
configure(connection) | ||
} | ||
|
||
private func configure(_ connection: MultipeerProtocol) { | ||
connection.didReceiveData = { [weak self] data, peer in | ||
self?.handleDataReceived(data, from: peer) | ||
} | ||
} | ||
|
||
public func receive<T: Codable>(_ type: T.Type, using closure: @escaping (T) -> Void) { | ||
MultipeerMessage.register(type, for: String(describing: type), closure: closure) | ||
} | ||
|
||
public func resume() { | ||
connection.resume() | ||
} | ||
|
||
public func stop() { | ||
connection.stop() | ||
} | ||
|
||
public func broadcast<T: Encodable>(_ payload: T) { | ||
do { | ||
let message = MultipeerMessage(type: String(describing: T.self), payload: payload) | ||
|
||
let data = try JSONEncoder().encode(message) | ||
|
||
try connection.broadcast(data) | ||
} catch { | ||
os_log("Failed to send payload %@: %{public}@", log: self.log, type: .error, String(describing: payload), String(describing: error)) | ||
} | ||
} | ||
|
||
private func handleDataReceived(_ data: Data, from peer: PeerName) { | ||
os_log("%{public}@", log: log, type: .debug, #function) | ||
|
||
do { | ||
let message = try JSONDecoder().decode(MultipeerMessage.self, from: data) | ||
|
||
os_log("Received message %@", log: self.log, type: .debug, String(describing: message)) | ||
} catch { | ||
os_log("Failed to decode message: %{public}@", log: self.log, type: .error, String(describing: error)) | ||
} | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.