Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move CiaoBrowser to AsyncStream with CiaoBrowserEvent enum #10

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions Ciao.podspec
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Pod::Spec.new do |s|
s.name = 'Ciao'
s.version = '2.1.1'
s.version = '3.0.0'
s.license = { :type => "MIT", :file => "LICENSE" }
s.summary = 'Lib to publish and find services using mDNS'
s.authors = { "Alexandre Mantovani Tavares" => "alexandre@live.in" }
s.source = { :git => "https://github.com/AlTavares/Ciao.git", :tag => s.version.to_s }
s.homepage = "https://github.com/AlTavares/Ciao"
s.platforms = { :ios => "8.0", :osx => "10.10", :tvos => "9.0" }
s.platforms = { :ios => "13.0", :osx => "10.15", :tvos => "13.0" }
s.requires_arc = true
s.swift_version = '4.2'
s.swift_version = '5.10'

s.default_subspec = "Core"
s.subspec "Core" do |ss|
Expand Down
26 changes: 26 additions & 0 deletions Ciao.xctestplan
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"configurations" : [
{
"id" : "99097CFE-D4C3-4D52-9D51-1A8C21133B30",
"name" : "Test Scheme Action",
"options" : {

}
}
],
"defaultOptions" : {
"testRepetitionMode" : "retryOnFailure",
"testTimeoutsEnabled" : true
},
"testTargets" : [
{
"parallelizable" : true,
"target" : {
"containerPath" : "container:",
"identifier" : "CiaoTests",
"name" : "CiaoTests"
}
}
],
"version" : 1
}
6 changes: 5 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// swift-tools-version:5.0
// swift-tools-version:5.10
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Ciao",
platforms: [
.iOS(.v13),
.macOS(.v10_15)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
Expand Down
46 changes: 24 additions & 22 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'Ciao', '~> 2.1.1'
pod 'Ciao', '~> 2.1.2'
```

Then, run the following command:
Expand All @@ -73,15 +73,15 @@ $ brew install carthage
To integrate Ciao into your Xcode project using Carthage, specify it in your `Cartfile`:

```ogdl
github "AlTavares/Ciao" ~> 2.1.1
github "AlTavares/Ciao" ~> 2.1.2
```
### Swift Package Manager

To use Ciao as a [Swift Package Manager](https://swift.org/package-manager/) package just add the following in your Package.swift file.

``` swift
dependencies: [
.package(url: "https://github.com/AlTavares/Ciao.git", from: "2.1.1")
.package(url: "https://github.com/AlTavares/Ciao.git", from: "2.1.2")
]
```

Expand All @@ -103,26 +103,28 @@ ciaoServer.txtRecord = ["someKey": "someValue"]
```swift
let ciaoBrowser = CiaoBrowser()

// get notified when a service is found
browser.serviceFoundHandler = { service in
print("Service found")
print(service)
Task {
for await event in browser.browse(type: type) {
case startedSearch:
print("Started search")
case stoppedSearch:
print("Stopped search")

case found(let service):
print("Found a service: ", service)

case removed(let service):
print("Removed a service: ", service)

case resolved(let result):
switch result {
case .success(let service):
print("Resolved service: ", service)
case .failure(let error):
print("Failed to resolve service: ", error)
}
}
}

// register to automatically resolve a service
browser.serviceResolvedHandler = { service in
print("Service resolved")
print(service)
print(service.hostName)
print(service.txtRecordDictionary)
}

browser.serviceRemovedHandler = { service in
print("Service removed")
print(service)
}

ciaoBrowser.browse(type: type)
```

### Resolver
Expand Down
81 changes: 42 additions & 39 deletions Sources/Ciao/CiaoBrowser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,93 +11,96 @@ import Foundation
public class CiaoBrowser {
var netServiceBrowser: NetServiceBrowser
var delegate: CiaoBrowserDelegate

public var services = Set<NetService>()

// Handlers
public var serviceFoundHandler: ((NetService) -> Void)?
public var serviceRemovedHandler: ((NetService) -> Void)?
public var serviceResolvedHandler: ((Result<NetService, ErrorDictionary>) -> Void)?
public var startedSearchingHandler: (() -> Void)?
public var stoppedSearchingHandler: (() -> Void)?

private var discoveryContinuation: AsyncStream<CiaoBrowserEvent>.Continuation?

public var isSearching = false {
didSet {
Logger.info(isSearching)
if isSearching, let startedSearchingHandler {
startedSearchingHandler()
} else if !isSearching, let stoppedSearchingHandler {
stoppedSearchingHandler()
if isSearching,
let discoveryContinuation {
discoveryContinuation.yield(.startedSearch)
} else if !isSearching,
let discoveryContinuation {
discoveryContinuation.yield(.stoppedSearch)
}
}
}

public init() {
netServiceBrowser = NetServiceBrowser()
delegate = CiaoBrowserDelegate()
netServiceBrowser.delegate = delegate
delegate.browser = self
}

public func browse(type: ServiceType, domain: String = "") {
browse(type: type.description, domain: domain)
public func browse(type: ServiceType, domain: String = "") -> AsyncStream<CiaoBrowserEvent> {
self.browse(type: type.description, domain: domain)
}

public func browse(type: String, domain: String = "") {
stop()
netServiceBrowser.searchForServices(ofType: type, inDomain: domain)

public func browse(type: String, domain: String = "") -> AsyncStream<CiaoBrowserEvent>{
self.stop()
return AsyncStream { continuation in
self.discoveryContinuation = continuation
self.netServiceBrowser.searchForServices(ofType: type, inDomain: domain)
}
}

fileprivate func serviceFound(_ service: NetService) {
services.update(with: service)
serviceFoundHandler?(service)

self.services.update(with: service)
self.discoveryContinuation?.yield(.found(service))
// resolve services if handler is registered
guard let serviceResolvedHandler = serviceResolvedHandler else { return }
guard let discoveryContinuation
else { return }

var resolver: CiaoResolver? = CiaoResolver(service: service)
resolver?.resolve(withTimeout: 0) { result in
serviceResolvedHandler(result)
discoveryContinuation.yield(.resolved(result))
// retain resolver until resolution
resolver = nil
}
}

fileprivate func serviceRemoved(_ service: NetService) {
services.remove(service)
serviceRemovedHandler?(service)
self.services.remove(service)
self.discoveryContinuation?.yield(.removed(service))
}

public func stop() {
netServiceBrowser.stop()
self.netServiceBrowser.stop()
self.discoveryContinuation?.finish()
self.discoveryContinuation = nil
}

deinit {
stop()
self.stop()
}
}

class CiaoBrowserDelegate: NSObject, NetServiceBrowserDelegate {
weak var browser: CiaoBrowser?

func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
Logger.info("Service found", service)
self.browser?.serviceFound(service)
}

func netServiceBrowserWillSearch(_ browser: NetServiceBrowser) {
Logger.info("Browser will search")
self.browser?.isSearching = true
}

func netServiceBrowserDidStopSearch(_ browser: NetServiceBrowser) {
Logger.info("Browser stopped search")
self.browser?.isSearching = false
}

func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String: NSNumber]) {
Logger.debug("Browser didn't search", errorDict)
self.browser?.isSearching = false
}

func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool) {
Logger.info("Service removed", service)
self.browser?.serviceRemoved(service)
Expand Down
16 changes: 16 additions & 0 deletions Sources/Ciao/CiaoBrowserEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// File.swift
//
//
// Created by Josh Billions on 7/14/24.
//

import Foundation

public enum CiaoBrowserEvent {
case startedSearch
case stoppedSearch
case found(NetService)
case removed(NetService)
case resolved(Result<NetService, ErrorDictionary>)
}
Loading