From 688a371e7882d53f97a46458862f629df469f720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 22 Dec 2025 13:57:34 +0800 Subject: [PATCH] Add browse button to open working directory in Files app (iOS) --- .../Views/Setting/CoreView.swift | 38 +++++++++++++++++++ Localizable.xcstrings | 10 +++++ 2 files changed, 48 insertions(+) diff --git a/ApplicationLibrary/Views/Setting/CoreView.swift b/ApplicationLibrary/Views/Setting/CoreView.swift index 989c28c..9c2bfb0 100644 --- a/ApplicationLibrary/Views/Setting/CoreView.swift +++ b/ApplicationLibrary/Views/Setting/CoreView.swift @@ -1,6 +1,10 @@ import Libbox import Library import SwiftUI +#if os(iOS) + import FileProvider + import UIKit +#endif @MainActor public struct CoreView: View { @@ -41,6 +45,16 @@ public struct CoreView: View { } label: { Label("Open", systemImage: "macwindow.and.cursorarrow") } + #elseif os(iOS) + if #available(iOS 16.0, *) { + FormButton { + Task { + await openInFilesApp() + } + } label: { + Label("Browse", systemImage: "folder.fill") + } + } #endif FormButton(role: .destructive) { Task { @@ -115,6 +129,30 @@ public struct CoreView: View { isLoading = true } } + + #if os(iOS) + @available(iOS 16.0, *) + private nonisolated func openInFilesApp() async { + do { + let domains = try await NSFileProviderManager.domains() + guard let domain = domains.first(where: { $0.identifier.rawValue == "io.nekohasekai.sfavt.workingdir" }) else { + throw NSError(domain: "CoreView", code: 0, userInfo: [NSLocalizedDescriptionKey: "File provider domain not found"]) + } + guard let manager = NSFileProviderManager(for: domain) else { + throw NSError(domain: "CoreView", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to get file provider manager"]) + } + let url = try await manager.getUserVisibleURL(for: .rootContainer) + guard let sharedURL = URL(string: "shareddocuments://\(url.path)") else { + throw NSError(domain: "CoreView", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create shared documents URL"]) + } + await UIApplication.shared.open(sharedURL) + } catch { + await MainActor.run { + alert = AlertState(error: error) + } + } + } + #endif } private extension URL { diff --git a/Localizable.xcstrings b/Localizable.xcstrings index cba13f4..f38114e 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -204,6 +204,16 @@ } } }, + "Browse" : { + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "浏览" + } + } + } + }, "By default, segment routing is used in `auto_route` instead of global routing.\nIf `` exists in the configuration, this item will not take effect on the corresponding network (commonly used to resolve HomeKit compatibility issues)." : { "localizations" : { "zh-Hans" : {