Changes
5 changed files (+148/-13)
-
-
@@ -404,8 +404,11 @@ buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = plac/plac.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
-
@@ -425,6 +428,7 @@ MACOSX_DEPLOYMENT_TARGET = 15.3;MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = jp.pocka.plac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; REGISTER_APP_GROUPS = YES; SDKROOT = auto; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
-
@@ -441,8 +445,11 @@ buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = plac/plac.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
-
@@ -462,6 +469,7 @@ MACOSX_DEPLOYMENT_TARGET = 15.3;MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = jp.pocka.plac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; REGISTER_APP_GROUPS = YES; SDKROOT = auto; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
-
-
-
@@ -30,13 +30,8 @@ VStack {Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text( String(format: "Window = %u", getDefaultReceiveWindow())) Text("Window = \(getDefaultReceiveWindow())") } .padding() } } #Preview{ ContentView() }
-
-
-
@@ -0,0 +1,130 @@// Copyright 2025 Shota FUJI // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 import PlacCore import SwiftUI enum DiscoveryResult { case loading case loaded([UnsafeMutablePointer<PlacCore.plac_server>]) case failed(PlacCore.plac_scan_result_code) case nilscanner } struct ServerDiscoveryScene: Scene { @Environment(\.scenePhase) private var scenePhase @State private var discovery: DiscoveryResult = .loading var body: some Scene { WindowGroup { VStack { switch discovery { case .loading: Text("Scanning Roon Server on network...") case .loaded(let serverPtrs): List { ForEach(serverPtrs, id: \.pointee.id) { ptr in Text(String.init(cString: ptr.pointee.name)) } } case .failed(let plac_scan_result_code): switch plac_scan_result_code { case PlacCore.PLAC_SCAN_NETWORK_UNAVAILABLE: Text("Network unavailable") case PlacCore.PLAC_SCAN_UNKNOWN_ERROR: Text("Unknown error") case PlacCore.PLAC_SCAN_SOCKET_PERMISSION_ERROR: Text("Failed to open socket (permission error)") case PlacCore.PLAC_SCAN_SOCKET_SETUP_ERROR: Text("Failed to open socket") case PlacCore.PLAC_SCAN_INVALID_RECEIVE_WINDOW: Text("Invalid receiving window duration") case PlacCore.PLAC_SCAN_OK: Text("OK (unreachable)") case PlacCore.PLAC_SCAN_OUT_OF_MEMORY: Text("Out of memory") case PlacCore.PLAC_SCAN_UDP_RECV_ERROR: Text("Unabled to receive UDP message") case PlacCore.PLAC_SCAN_UDP_SEND_ERROR: Text("Unable to send UDP message") case PlacCore.PLAC_SCAN_TOO_MANY_SOCKET_ERROR: Text("Failed to open socket (too many socket)") case PlacCore.PLAC_SCAN_NULL_POINTER_ARGS: Text("Failed to setup scanner or options") default: Text("Unexpected error (platform misbehaving)") } case .nilscanner: Text("Failed to scan") } } } .onChange(of: scenePhase, initial: true) { if scenePhase == .active { let thread = Thread { switch discovery { case .loaded(let prevPointers): for pointer in prevPointers { PlacCore.plac_server_free(pointer) } default: break } discovery = .loading var opts = PlacCore.plac_server_scan_options() PlacCore.plac_server_scan_options_init(&opts) let scanner = PlacCore.plac_server_scanner_make() if let result = PlacCore.plac_server_scanner_scan( scanner, &opts) { var servers: [UnsafeMutablePointer<PlacCore.plac_server>] = [] while true { if let next = PlacCore.plac_scan_result_next( result) { servers.append(next) } else { break } } if result.pointee.code == PlacCore.PLAC_SCAN_OK { discovery = .loaded(servers) } else { discovery = .failed(result.pointee.code) } PlacCore.plac_scan_result_free(result) } else { discovery = .nilscanner } PlacCore.plac_server_scanner_free(scanner) } thread.start() } } } }
-
-
-
@@ -2,9 +2,13 @@ <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.files.user-selected.read-only</key> <true/> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.files.user-selected.read-only</key> <true/> <key>com.apple.security.network.client</key> <true/> <key>com.apple.security.network.server</key> <true/> </dict> </plist>
-
-
-
@@ -19,8 +19,6 @@@main struct placApp: App { var body: some Scene { WindowGroup { ContentView() } ServerDiscoveryScene() } }
-