如何在没有 xcode 的情况下删除沙箱
How to remove sandbox without xcode
。谢天谢地,它得到了答复并且效果很好。
问题是它仅 在 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
)
正如我在对您之前的问题的评论中所说,这与 Xcode 本身无关。 Xcode 只是为您生成大量代码和构建命令。
macOS 是一个复杂的操作系统,想要使用其更高级功能的程序必须遵循特定的模式。其中一种模式称为 运行 循环。如果您创建一个 Cocoa 应用程序,您将免费获得其中大部分内容。
由于您正在尝试执行一些异步操作,因此需要一个 运行 循环。附加这个应该有效:
RunLoop.current.run()
否则,您的程序将在主线程(您的代码)完成时终止。但是,运行 循环会使程序 运行 循环并等待异步事件(例如,这也包括 UI 交互)发生。
请注意,插入同一行也可以解决您在另一个问题中遇到的问题。
问题是它仅 在 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
)
正如我在对您之前的问题的评论中所说,这与 Xcode 本身无关。 Xcode 只是为您生成大量代码和构建命令。
macOS 是一个复杂的操作系统,想要使用其更高级功能的程序必须遵循特定的模式。其中一种模式称为 运行 循环。如果您创建一个 Cocoa 应用程序,您将免费获得其中大部分内容。
由于您正在尝试执行一些异步操作,因此需要一个 运行 循环。附加这个应该有效:
RunLoop.current.run()
否则,您的程序将在主线程(您的代码)完成时终止。但是,运行 循环会使程序 运行 循环并等待异步事件(例如,这也包括 UI 交互)发生。
请注意,插入同一行也可以解决您在另一个问题中遇到的问题。