Xcode 不断给我这段代码带来问题

问题描述 投票:0回答:1

Xcode 一直说

“ContentView”的重新声明无效 实例将立即被释放,因为属性“navigationDelegate”为“weak”*“weak”只能应用于类和类绑定协议类型,而不是“FilesView”*“WebViewCoordinator”类型的值没有成员“getDocumentsDirectory”*值类型“WebViewCoordinator”没有成员“sanitizeFileName” 类型“[URLResourceKey: Any]”的值没有成员“totalFileAllocationSize”

代码如下:l

`
import SwiftUI
import WebKit

@main
struct UDOWNLOADERZApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        TabView {
            BrowserView()
                .tabItem {
                    Label("Browser", systemImage: "globe")
                }
            FilesView()
                .tabItem {
                    Label("Files", systemImage: "folder")
                }
            SettingsView()
                .tabItem {
                    Label("Settings", systemImage: "gearshape")
                }
        }
    }
}

struct BrowserView: View {
    @State private var webView = WKWebView()

    var body: some View {
        WebView(webView: $webView)
            .onAppear {
                let urls = ["https://youtube.com", "https://soundcloud.com"]
                for url in urls {
                    if let url = URL(string: url) {
                        let request = URLRequest(url: url)
                        webView.load(request)
                    }
                }
                webView.navigationDelegate = WebViewCoordinator(filesView: nil)
            }
    }
}

struct WebView: UIViewRepresentable {
    @Binding var webView: WKWebView

    func makeUIView(context: Context) -> WKWebView {
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {}
}

class WebViewCoordinator: NSObject, WKNavigationDelegate {
    weak var filesView: FilesView?

    init(filesView: FilesView?) {
        self.filesView = filesView
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let jsCode = """
        (function() {
            var video = document.querySelector('video');
            var audio = document.querySelector('audio');
            var mediaElement = video || audio;
            if (mediaElement) {
                return {
                    src: mediaElement.src,
                    title: document.title || mediaElement.getAttribute('title') || 'Unknown'
                };
            }
            return null;
        })();
        """
        
        webView.evaluateJavaScript(jsCode) { [weak self] (result, error) in
            guard let resultDict = result as? [String: String], let urlString = resultDict["src"], let title = resultDict["title"], let url = URL(string: urlString) else { return }
            
            self?.downloadContent(url: url, title: title)
        }
    }

    func downloadContent(url: URL, title: String) {
        DispatchQueue.global().async {
            let destinationURL = getDocumentsDirectory().appendingPathComponent("\(sanitizeFileName(fileName: title)).mp4")

            URLSession.shared.downloadTask(with: url) { [weak self] (tempURL, response, error) in
                guard let self = self, let tempURL = tempURL, error == nil else { return }
                do {
                    try FileManager.default.moveItem(at: tempURL, to: destinationURL)
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("DownloadCompleted"), object: nil)
                        self.filesView?.reloadFilesList()
                    }
                } catch {
                    print("Download failed: \(error.localizedDescription)")
                }
            }.resume()
        }
    }
}

struct FilesView: View {
    @State private var downloadedFiles = [String]()
    @State private var storageTaken: String = ""

    var body: some View {
        VStack {
            List {
                ForEach(downloadedFiles, id: \.self) { file in
                    Text(file)
                }
            }
            Text("Storage Taken: \(storageTaken)")
        }
        .onAppear(perform: loadFiles)
        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("DownloadCompleted"))) { _ in
            loadFiles()
        }
    }

    func loadFiles() {
        DispatchQueue.global().async {
            do {
                let files = try FileManager.default.contentsOfDirectory(at: getDocumentsDirectory(), includingPropertiesForKeys: nil, options: [])
                DispatchQueue.main.async {
                    downloadedFiles = files.map { $0.lastPathComponent }
                    calculateStorageTaken(files: files)
                }
            } catch {
                print("Failed to load files: \(error.localizedDescription)")
            }
        }
    }

    func reloadFilesList() {
        loadFiles()
    }

    private func calculateStorageTaken(files: [URL]) {
        let size = files.reduce(0, { $0 + ($1 as NSURL).fileSize() })
        storageTaken = ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .file)
    }
}

struct SettingsView: View {
    var body: some View {
        VStack {
            Text("Contact: [email protected]")
            Text("Twitter: N/A")
        }
    }
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

func sanitizeFileName(fileName: String) -> String {
    let invalidCharacters = CharacterSet(charactersIn: "\\/:*?\"<>|")
    return fileName.components(separatedBy: invalidCharacters).joined(separator: "_")
}

extension NSURL {
    func fileSize() -> Int {
        guard`

`

我尝试重新调整代码,但仍然不起作用。

swift xcode
1个回答
0
投票
  1. Invalid redeclaration of 'ContentView’
    。在项目的某个地方,有另一个 ContentView 声明。在 Swift 中,不允许有多个同名的类、结构或协议。您应该找到它并删除或重命名。
  2. Instance will be immediately deallocated because property 'navigationDelegate' is 'weak’
    。如果你写
    weak var
    ,则表明你想维护一个对象的弱引用。然而,该对象必须至少有一个强引用,否则它将立即被释放。在您的情况下,您必须在具有强引用的地方保留 WebViewCoordinator,例如
    var webViewCoordinator: WebViewCoordinator
    ,然后将其分配给委托属性。
  3. 'weak' may only be applied to class and class-bound protocol types, not 'FilesView’
    。在 Swift 中,只有引用类型可以有弱引用。由于 Swift 中的结构是值类型,因此不能对它们使用弱引用。在您的场景中,存在一些概念上的误解。如果您想重新加载视图,则无需将视图传递给另一个类。
  4. 我无法提供与
    getDocumentsDirectory
    sanitizeFileName
    totalFileAllocatedSize
    相关的错误的反馈,因为在您的示例中,您已将它们移动到不再产生错误的位置。

总而言之,考虑通过引入 ViewModel 和服务来重构您的架构。例如,您可以创建一个服务来处理

getDocumentsDirectory
sanitizeFileName
等方法,并在必要时使用该服务。 此外,创建一个 ViewModel 并将其传递给“WebViewCoordinator”和“FilesView”。然后协调器可以请求文件重新加载,并且“FilesView”可以从 ViewModel 检索重新加载的文件。

© www.soinside.com 2019 - 2024. All rights reserved.