【问题标题】:How to remove sandbox without xcode如何在没有 xcode 的情况下删除沙箱
【发布时间】:2021-01-25 02:41:54
【问题描述】:

Earlier I asked a question regarding generateCGImagesAsynchronously。值得庆幸的是,它得到了回答并且效果很好。

问题在于它在 xcode 上用作 Cocoa 应用程序。我现在正试图将此逻辑移动到可执行的 Swift 包中,但 AVFoundation 代码,例如 generateCGImagesAsynchronously,将不起作用。也就是说,没有引发错误,但这些函数似乎被嘲笑了。我认为这可能与我的包被沙盒化有关?我能够从我之前为其编写代码的 Cocoa 应用程序中删除沙箱,但我不知道如何为这个可执行文件执行此操作。

我是 Swift 的新手,并试图理解它,但想到我希望我的代码执行的操作取决于我正在使用的 IDE,这有点令人沮丧。

如果有人能指出我在文档或其他资源中的阅读方向,了解如何在不使用 xcode 的情况下制作程序,那就太好了。谢谢!

这是我的代码:

import Darwin
import Foundation
import AppKit
import AVFoundation
import Cocoa


@discardableResult func writeCGImage(
    _ image: CGImage,
    to destinationURL: URL
) -> Bool {
    guard let destination = CGImageDestinationCreateWithURL(
        destinationURL as CFURL,
        kUTTypePNG,
        1,
        nil
    ) else { return false }
    CGImageDestinationAddImage(destination, image, nil)
    return CGImageDestinationFinalize(destination)
}


func imageGenCompletionHandler(
    requestedTime: CMTime,
    image: CGImage?,
    actualTime: CMTime,
    result: AVAssetImageGenerator.Result,
    error: Error?
) {
    guard let image = image else { return }
    let path = saveToPath.appendingPathComponent(
        "img\(actualTime).png"
    )

    writeCGImage(image, to: path)
}


let arguments: [String] = Array(CommandLine.arguments.dropFirst())

// For now, we assume the second arg, which is the
// path that the user wants us to save to, always exists.
let saveToPath = URL(fileURLWithPath: arguments[1], isDirectory: true)

let vidURL = URL(fileURLWithPath: arguments[0])
let vidAsset = AVAsset(url: vidURL)
let vidDuration = vidAsset.duration

let imageGen = AVAssetImageGenerator(asset: vidAsset)
var frameForTimes = [NSValue]()
let sampleCounts = 20
let totalTimeLength = Int(truncatingIfNeeded: vidDuration.value as Int64)
let steps = totalTimeLength / sampleCounts

for sampleCount in 0 ..< sampleCounts {
    let cmTime = CMTimeMake(
        value: Int64(sampleCount * steps),
        timescale: Int32(vidDuration.timescale)
    )
    frameForTimes.append(NSValue(time: cmTime))
}

imageGen.generateCGImagesAsynchronously(
    forTimes: frameForTimes,
    completionHandler: imageGenCompletionHandler
)

【问题讨论】:

    标签: swift swift5


    【解决方案1】:

    正如我在对您之前的问题的评论中所说,这与 Xcode 本身无关。 Xcode 只是为您生成大量代码和构建命令。

    macOS 是一个复杂的操作系统,想要使用其更高级功能的程序必须遵循某些模式。其中一种模式称为运行循环。如果您创建一个 Cocoa 应用程序,您可以免费获得其中的大部分内容。

    由于您尝试执行一些异步操作,因此您需要一个运行循环。附加这个应该可以:

    RunLoop.current.run()
    

    否则,您的程序将在主线程(您的代码)完成时终止。然而,运行循环会导致程序运行一个循环并等待异步事件(例如,这也包括 UI 交互)发生。

    请注意,插入同一行也可以解决其他问题中的问题。

    【讨论】:

    • 谢谢,这正是我需要知道的。我在哪里可以阅读更多关于这些 Swift 模式以及与 MacOS 交互的信息?它有任何规范的来源吗?
    • @Algebra8 我不知道任何这样的来源,抱歉。您可以从 Apple 获得的最好的可能是 the AppKit documentation。此外,查看stackoverflow.com/questions/15694510/… 之类的文章(Internet 上还有更多)可能会有所帮助。但是,老实说,自上而下的方法会更好:首先熟悉标准堆栈。
    • 这是一个很好的观点——这些事情只是需要时间 :) 不管怎样,非常感谢你的帮助,你让我走上了正确的道路。
    猜你喜欢
    • 2013-10-23
    • 1970-01-01
    • 2012-01-13
    • 2015-02-05
    • 2020-11-19
    • 2015-07-01
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多