Skip to content

Commit

Permalink
Version 3.2.0 (#22)
Browse files Browse the repository at this point in the history
* Version 3.1.0

- License Change.
- Added UDP Peer Documentation.
- Depend upon CoreOSC 1.1.0.
- Fixed TCP stream framing bug.

Signed-off-by: Sam Smallman <[email protected]>

* Spelling and Grammar

- Corrected spelling mistakes.
- Added missing fullstops.
- Rearranged OSCUdpPeerConfiguration init to make more sense (backwards incompatible)

Bump Major

Signed-off-by: Sam Smallman <[email protected]>

* Remove backwards imcompatibility changes

Signed-off-by: Sam Smallman <[email protected]>

* Added documentation

The interface should not be set when expecting to receive broadcasted packets into a udp socket.

robbiehanson/CocoaAsyncSocket#153
Signed-off-by: Sam Smallman <[email protected]>

Closes #5

Signed-off-by: Sam Smallman <[email protected]>

* Fix Issue-#7 (Multicast packets) (#8)

Signed-off-by: Sam Smallman <[email protected]>

* Receive Multicast Packets (Part 2) (#11)

* Fix Issue-#7 (Multicast packets)

Signed-off-by: Sam Smallman <[email protected]>

* Remove merge conflict artifacts

Signed-off-by: Sam Smallman <[email protected]>

* feat: Added Identifiable protocol (#13)

Closes #12

Signed-off-by: Sam Smallman <[email protected]>

* fix: Swapped broadcast method for the reusePort method (#15)

Closes #14

Signed-off-by: Sam Smallman <[email protected]>

* Reuse Port (#17)

Closes #14

Signed-off-by: Sam Smallman <[email protected]>

* feat: CoreOSC 1.2.1 (#20)

Co-authored-by: Sam Smallman <[email protected]>

* fix: README and Version (#21)

Signed-off-by: Sam Smallman <[email protected]>

* fix: Version test

Signed-off-by: Sam Smallman <[email protected]>

---------

Signed-off-by: Sam Smallman <[email protected]>
Co-authored-by: Sam Smallman <[email protected]>
  • Loading branch information
sammysmallman and SamSmallman authored Apr 25, 2023
1 parent f598277 commit 87bc91e
Show file tree
Hide file tree
Showing 25 changed files with 226 additions and 128 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/robbiehanson/CocoaAsyncSocket", from: "7.6.4"),
.package(name: "NetUtils" ,url: "https://github.com/svdo/swift-netutils", from: "4.1.0"),
.package(url: "https://github.com/sammysmallman/CoreOSC.git", from: "1.1.0")
.package(url: "https://github.com/sammysmallman/CoreOSC.git", from: "1.2.1")
],
targets: [
.target(
Expand Down
50 changes: 31 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
The OSCKit package provides the classes needed for your apps to communicate among computers, sound synthesizers, and other multimedia devices via [OSC](http://opensoundcontrol.org/README.html) over an IP network.

## Overview
Use the OSCKit package to create client or server objects. In its simplest form a client can send a packet, either a [Message](http://opensoundcontrol.org/spec-1_0.html#osc-messages) or [Bundle](http://opensoundcontrol.org/spec-1_0.html#osc-bundles) to a server. A server, when listening, can receive these packets and action upon them. Depending on a client or server using either UDP or TCP as a transport, there are varying levels of fuctionality and delegate methods for you to take advantage of.
Use the OSCKit package to create client or server objects. In its simplest form a client can send a packet, either a [Message](http://opensoundcontrol.org/spec-1_0.html#osc-messages) or [Bundle](http://opensoundcontrol.org/spec-1_0.html#osc-bundles) to a server. A server, when listening, can receive these packets and action upon them. Depending on a client or server using either UDP or TCP as a transport, there are varying levels of functionality and delegate methods for you to take advantage of.

OSCKit implements all required argument types as specified in [OSC 1.1](http://opensoundcontrol.org/files/2009-NIME-OSC-1.1.pdf).

An example project can be found in [OSCKitDemo](https://github.com/sammysmallman/OSCKitDemo).

## License
OSCKit is licensed under the GNU Affero General Public License, version 3. If you require a commercial license for an application that you would not like to trigger AGPLv3 obligations (e.g. open sourcing your application), please get in touch. The probability of obtaining a commerical license for free is high.
OSCKit is licensed under the GNU Affero General Public License, version 3. If you require a commercial license for an application that you would not like to trigger AGPLv3 obligations (e.g. open sourcing your application), please get in touch. The probability of obtaining a commercial license for free is high.

## Features

Expand All @@ -39,7 +39,7 @@ Add the package dependency to your Package.swift and depend on "OSCKit" in the n

``` swift
dependencies: [
.package(url: "https://github.com/SammySmallman/OSCKit", .upToNextMajor(from: "3.1.0"))
.package(url: "https://github.com/SammySmallman/OSCKit", .upToNextMajor(from: "3.2.0"))
]
```

Expand Down Expand Up @@ -253,7 +253,6 @@ do {
} catch {
print("Unable to create OSCMessage: \(error.localizedDescription)")
}

```

<h4>Step 5</h4>
Expand Down Expand Up @@ -341,25 +340,38 @@ let peer = OSCUdpPeer(host: "10.101.130.101",

Conform to the peers delegate protocol OSCUdpPeerDelegate:
```swift
func peer(_ peer: OSCUdpPeer, didReceivePacket packet: OSCPacket, fromHost host: String, port: UInt16) {
print("Peer did receive packet from \(host):\(port)")
}
func peer(_ peer: OSCUdpPeer,
didReceivePacket packet: OSCPacket,
fromHost host: String,
port: UInt16) {
print("Peer did receive packet from \(host):\(port)")
}

func peer(_ peer: OSCUdpPeer, didReadData data: Data, with error: Error) {
print("Peer did read data with error: \(error.localizedDescription)")
}
func peer(_ peer: OSCUdpPeer,
didReadData data: Data,
with error: Error) {
print("Peer did read data with error: \(error.localizedDescription)")
}

func peer(_ peer: OSCUdpPeer, didSendPacket packet: OSCPacket, fromHost host: String?, port: UInt16?) {
print("Peer sent packet to \(peer.host):\(peer.hostPort) from \(host):\(port)")
}
func peer(_ peer: OSCUdpPeer,
didSendPacket packet: OSCPacket,
fromHost host: String?,
port: UInt16?) {
print("Peer sent packet to \(peer.host):\(peer.hostPort) from \(host):\(port)")
}

func peer(_ peer: OSCUdpPeer, didNotSendPacket packet: OSCPacket, fromHost host: String?, port: UInt16?, error: Error?) {
print("Peer did not send packet to \(peer.host):\(peer.hostPort) from \(host):\(port)")
}
func peer(_ peer: OSCUdpPeer,
didNotSendPacket packet: OSCPacket,
fromHost host: String?,
port: UInt16?,
error: Error?) {
print("Peer did not send packet to \(peer.host):\(peer.hostPort) from \(host):\(port)")
}

func peer(_ peer: OSCUdpPeer, socketDidCloseWithError error: Error?) {
print("Peer Error: \(error.localizedDescription)")
}
func peer(_ peer: OSCUdpPeer,
socketDidCloseWithError error: Error?) {
print("Peer Error: \(error.localizedDescription)")
}
```

<h4>Step 4</h4>
Expand Down
4 changes: 2 additions & 2 deletions Sources/OSCKit/Extensions/Interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand All @@ -38,7 +38,7 @@ extension Interface {
}

open var displayText: String {
return "\(self.displayName) (\(self.name)) - \(self.address ?? "")"
"\(self.displayName) (\(self.name)) - \(self.address ?? "")"
}
#endif
}
2 changes: 1 addition & 1 deletion Sources/OSCKit/Extensions/Numeric.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down
12 changes: 5 additions & 7 deletions Sources/OSCKit/Extensions/UInt32.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand All @@ -27,13 +27,11 @@ extension UInt32 {

internal func byteArray() -> [UInt8] {
var bigEndian = self.bigEndian
let count = MemoryLayout<UInt32>.size
let bytePtr = withUnsafePointer(to: &bigEndian) {
$0.withMemoryRebound(to: UInt8.self, capacity: count) {
UnsafeBufferPointer(start: $0, count: count)
return Array(withUnsafePointer(to: &bigEndian) {
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<UInt32>.size) {
UnsafeBufferPointer(start: $0, count: MemoryLayout<UInt32>.size)
}
}
return Array(bytePtr)
})
}

}
8 changes: 4 additions & 4 deletions Sources/OSCKit/OSCKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

// Export all submodules so they all import
Expand All @@ -30,7 +30,7 @@ import Foundation
public enum OSCKit {

/// This package's semantic version number, mirrored also in git history as a `git tag`.
static let version: String = "3.1.0"
static let version: String = "3.2.0"

/// The license agreement this repository is licensed under.
static let license: String = {
Expand All @@ -47,8 +47,8 @@ public enum OSCKit {
static let coreOscVersion: String = "/sdk/coreosc/version"
/// An address pattern for retrieving the sdk's license.
static let coreOscLicense: String = "/sdk/coreosc/license"
/// Returns a `OSCMessage` response corresponding to the given packet.

/// Returns an `OSCMessage` response corresponding to the given packet.
static func message(for packet: OSCPacket) -> OSCMessage? {
guard let message = packet as? OSCMessage else { return nil }
switch message.addressPattern.fullPath {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OSCKit/OSCSentPacket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down
6 changes: 3 additions & 3 deletions Sources/OSCKit/OSCTcp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down Expand Up @@ -50,7 +50,7 @@ internal struct OSCTcp {
/// - packet: The `OSCPacket` to be sent.
/// - streamFraming: The method the packet will be encoded with.
/// - socket: A TCP socket.
/// - timeout: The timeout for the send opeartion. If the timeout value is negative,
/// - timeout: The timeout for the send operartion. If the timeout value is negative,
/// the send operation will not use a timeout.
/// - tag: A convenienve tag, reported back with the
/// GCDAsyncSocketDelegate method `socket(_:didWriteDataWithTag:)`.
Expand All @@ -71,7 +71,7 @@ internal struct OSCTcp {
/// - data: Data from an `OSCPacket`.
/// - streamFraming: The method the packet will be encoded with.
/// - socket: A TCP socket.
/// - timeout: The timeout for the send opeartion. If the timeout value is negative,
/// - timeout: The timeout for the send operartion. If the timeout value is negative,
/// the send operation will not use a timeout.
/// - tag: A convenienve tag, reported back with the
/// GCDAsyncSocketDelegate method `socket(_:didWriteDataWithTag:)`.
Expand Down
12 changes: 8 additions & 4 deletions Sources/OSCKit/OSCTcpClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down Expand Up @@ -56,11 +56,11 @@ public class OSCTcpClient: NSObject {
/// The clients local port.
public var localPort: UInt16? { socket.localPort }

/// The timeout for the connect opeartion.
/// The timeout for the connect operartion.
/// If the timeout value is negative, the connect operation will not use a timeout.
public var connectingTimeout: TimeInterval = 1

/// The timeout for the send opeartion.
/// The timeout for the send operartion.
/// If the timeout value is negative, the send operation will not use a timeout.
public var timeout: TimeInterval = -1

Expand Down Expand Up @@ -140,7 +140,11 @@ public class OSCTcpClient: NSObject {
public init(configuration: OSCTcpClientConfiguration,
delegate: OSCTcpClientDelegate? = nil,
queue: DispatchQueue = .main) {
interface = configuration.interface
if configuration.interface?.isEmpty == false {
interface = configuration.interface
} else {
interface = nil
}
host = configuration.host
port = configuration.port
streamFraming = configuration.streamFraming
Expand Down
27 changes: 20 additions & 7 deletions Sources/OSCKit/OSCTcpClientConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,28 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation

/// A configuration object that defines the behavior of a TCP client.
@objc(OSCTcpClientConfiguration) public class OSCTcpClientConfiguration: NSObject, NSSecureCoding, Codable {
@objc(OSCTcpClientConfiguration) public class OSCTcpClientConfiguration: NSObject, NSSecureCoding, Codable, Identifiable {

/// A textual representation of this instance.
public override var description: String {
"""
OSCKit.OSCTcpClientConfiguration(\
id: \(id.uuidString), \
interface: \(String(describing: interface)), \
host: \(host), \
port: \(port), \
streamFraming: \(streamFraming))
"""
}

/// A stable identity of this instance.
public let id: UUID

/// The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.1.15").
/// If the value of this is nil the client will use the default interface.
Expand All @@ -58,15 +62,18 @@ import Foundation

/// A configuration object that defines the behavior of a TCP client.
/// - Parameters:
/// - id: A stable identity for this instance.
/// - interface: An interface name (e.g. "en1" or "lo0"), the corresponding IP address or nil.
/// - host: The host of the server that the client should connect to.
/// - port: The port of the host the client should send packets to.
/// - streamFraming: The stream framing all OSCPackets will be encoded and decoded with by the client.
/// OSC 1.0 uses packet length headers and OSC 1.1 uses the SLIP protocol.
public init(interface: String? = nil,
/// OSC 1.0 uses packet length headers and OSC 1.1 uses the SLIP protocol.
public init(id: UUID = .init(),
interface: String? = nil,
host: String,
port: UInt16,
streamFraming: OSCTcpStreamFraming) {
self.id = id
self.interface = interface
self.port = port
self.host = host
Expand All @@ -79,6 +86,9 @@ import Foundation
///
/// NSSecureCoding is implemented to allow for this instance to be passed to a XPC Service.
public static var supportsSecureCoding: Bool = true

/// A key that defines the `id` of an `OSCTcpClientConfiguration`.
private static let idKey = "idKey"

/// A key that defines the `interface` of an `OSCTcpClient`.
private static let interfaceKey = "interfaceKey"
Expand All @@ -94,20 +104,23 @@ import Foundation

/// A configuration object that defines the behavior of a TCP server from data in a given unarchiver.
public required init?(coder: NSCoder) {
guard let host = coder.decodeObject(of: NSString.self, forKey: Self.hostKey) as String?,
let portData = coder.decodeObject(of: NSData.self, forKey: Self.portKey) as Data?,
guard let interface = coder.decodeObject(of: NSString.self, forKey: Self.interfaceKey) as? String,
let host = coder.decodeObject(of: NSString.self, forKey: Self.hostKey) as? String,
let portData = coder.decodeObject(of: NSData.self, forKey: Self.portKey) as? Data,
let streamFraming = OSCTcpStreamFraming(rawValue: coder.decodeInteger(forKey: Self.streamFramingKey))
else {
return nil
}
self.interface = coder.decodeObject(of: NSString.self, forKey: Self.interfaceKey) as String?
self.id = coder.decodeObject(of: NSUUID.self, forKey: Self.idKey) as? UUID ?? .init()
self.interface = interface
self.host = host
self.port = portData.withUnsafeBytes { $0.load(as: UInt16.self) }.bigEndian
self.streamFraming = streamFraming
}

/// Encodes this instance using a given archiver.
public func encode(with coder: NSCoder) {
coder.encode(id, forKey: Self.idKey)
coder.encode(interface, forKey: Self.interfaceKey)
coder.encode(host, forKey: Self.hostKey)
// Port could potentially be encoded as an NSInteger...
Expand Down
2 changes: 1 addition & 1 deletion Sources/OSCKit/OSCTcpClientDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down
13 changes: 6 additions & 7 deletions Sources/OSCKit/OSCTcpServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// along with this software. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation
Expand Down Expand Up @@ -58,7 +58,7 @@ public class OSCTcpServer: NSObject {
sockets.compactMap { (host: $0.value.host, port: $0.value.port) }
}

/// The timeout for the read and write opeartions.
/// The timeout for the read and write operartions.
/// If the timeout value is negative, the send operation will not use a timeout.
public var timeout: TimeInterval = -1

Expand Down Expand Up @@ -127,11 +127,10 @@ public class OSCTcpServer: NSObject {
public init(configuration: OSCTcpServerConfiguration,
delegate: OSCTcpServerDelegate? = nil,
queue: DispatchQueue = .main) {
if let configInterface = configuration.interface,
configInterface.isEmpty == false {
self.interface = configInterface
if configuration.interface?.isEmpty == false {
interface = configuration.interface
} else {
self.interface = nil
interface = nil
}
port = configuration.port
streamFraming = configuration.streamFraming
Expand Down Expand Up @@ -169,7 +168,7 @@ public class OSCTcpServer: NSObject {

// MARK: Listening

/// Start the server listening
/// Start the server listening.
/// - Throws: An error relating to the setting up of the socket.
///
/// The server will accept connections on the servers port. If an interface
Expand Down
Loading

0 comments on commit 87bc91e

Please sign in to comment.