重复执行程序 Swift

发布于 2025-01-11 15:04:45 字数 2554 浏览 0 评论 0原文

我有一个程序可以从 mac 获取一些系统信息,例如用户列表和上次会话。

我有一个包含一些值的配置 plist,我序列化了该 plist 并使用该数据创建了一个 AssessmentConfiguration 对象 我的 Plist:

<?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>OutputFile</key>
    <string>/tmp/empress_assessment_output.txt</string>
    <key>ErrorFile</key>
    <string>/tmp/empress_assessment_error.txt</string>
    <key>RunConfiguration</key>
    <dict>
        <key>RunInterval</key>
        <integer>30</integer>
        <key>Iterations</key>
        <integer>3</integer>
    </dict>
</dict>
</plist>

我的函数使用 plist 值来初始化 AssessmentConfiguration 对象

private func parseConfiguration(dictionary: Dictionary<String, Any>) throws -> AssessmentConfiguration {
        
        guard let outputFile = dictionary["OutputFile"] as? String else {
            throw ValidateError.empty
        }
        guard let errorFile = dictionary["ErrorFile"] as? String else {
            throw ValidateError.empty
        }
        guard let runConfiguration = dictionary["RunConfiguration"] as? Dictionary <String, Any> else {
            throw ValidateError.empty
        }
        
        guard let runInterval = runConfiguration["RunInterval"] as? TimeInterval else {
            throw ValidateError.empty
        }
        
        guard let iterations = runConfiguration["Iterations"] as? Int else {
            throw ValidateError.empty
        }
        
        return AssessmentConfiguration(
            outputFile: URL(fileURLWithPath: outputFile),
            errorFile: URL(fileURLWithPath: errorFile),
            runConfiguration: AssessmentConfiguration.RunConfiguration(runInterval: runInterval, iterations: iterations)
        )
    }
    
    func getConfiguration() throws -> AssessmentConfiguration {
        let path =  try getConfigurationFilePath()
        let myDict = try getDictionary(filePath: path)
        let configuration = try parseConfiguration(dictionary: myDict)
        return configuration
    }

该程序将执行多次。 RunConfiguration 对象将配置这将如何发生。 ‐RunInterval 表示命令集执行之间的时间量。 ‐Iterations 表示命令集将被执行的迭代次数。 eg:如果 RunInterval == 30 且 Iterations == 3,则命令集将在开始时运行,然后在 30 秒后再次运行,然后再次 util 所有命令已执行 3 次并以退出代码 0 终止。

最好的方法是什么通过 getConfiguration() 的返回来做到这一点?

I’ve a program that takes some system information from mac, like User List and Last Sessions.

I have a configuration plist with some values, I serialized this plist and created an AssessmentConfiguration object with this data
My Plist:

<?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>OutputFile</key>
    <string>/tmp/empress_assessment_output.txt</string>
    <key>ErrorFile</key>
    <string>/tmp/empress_assessment_error.txt</string>
    <key>RunConfiguration</key>
    <dict>
        <key>RunInterval</key>
        <integer>30</integer>
        <key>Iterations</key>
        <integer>3</integer>
    </dict>
</dict>
</plist>

My function using the plist values to init AssessmentConfiguration object

private func parseConfiguration(dictionary: Dictionary<String, Any>) throws -> AssessmentConfiguration {
        
        guard let outputFile = dictionary["OutputFile"] as? String else {
            throw ValidateError.empty
        }
        guard let errorFile = dictionary["ErrorFile"] as? String else {
            throw ValidateError.empty
        }
        guard let runConfiguration = dictionary["RunConfiguration"] as? Dictionary <String, Any> else {
            throw ValidateError.empty
        }
        
        guard let runInterval = runConfiguration["RunInterval"] as? TimeInterval else {
            throw ValidateError.empty
        }
        
        guard let iterations = runConfiguration["Iterations"] as? Int else {
            throw ValidateError.empty
        }
        
        return AssessmentConfiguration(
            outputFile: URL(fileURLWithPath: outputFile),
            errorFile: URL(fileURLWithPath: errorFile),
            runConfiguration: AssessmentConfiguration.RunConfiguration(runInterval: runInterval, iterations: iterations)
        )
    }
    
    func getConfiguration() throws -> AssessmentConfiguration {
        let path =  try getConfigurationFilePath()
        let myDict = try getDictionary(filePath: path)
        let configuration = try parseConfiguration(dictionary: myDict)
        return configuration
    }

The program will executed several times. The RunConfiguration object will configure how this will happen.
⁃RunInterval represents the amount of time between the executions of the commands set.
⁃Iterations represents the number of iterations that the commands set will be executed.
⁃ E.g.: If RunInterval == 30 and Iterations == 3, the commands set will run at start, then again after 30 seconds, and again util all the commands have been executed 3 times and terminate with exit code 0.

What's the best way to do this with the return of getConfiguration()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖微凉心微凉 2025-01-18 15:04:45

我发现您正在自行实施此调度行为。它基本上最终归结为使用 for 循环和 Timer,但我不建议这样做,因为:

  • 这个“主管”代码必须不断运行,浪费系统资源。
  • 这是更多的工作,因为你必须自己构建它。

相反,我建议您使用现有的工具,对于 macOS,是使用 launchd 来启动启动代理或守护程序。您只需定义一个作业(一个 plist 文件),它配置您要运行的内容,以及响应什么事件(可以是时间,但也支持响应文件夹中显示的文件而运行) 、插入 USB 设备等)。从那里,launchd 将负责在正确的时间启动您的程序。

请参阅 Apple 的守护程序和服务编程指南 了解完整详细信息。

I see you're going down the route of implementing this scheduling behaviour by yourself. It basically ultimately boils down to using a for loop and a Timer, but I wouldn't suggest this, because:

  • This "supervisor" code will have to be constantly running, wasting system resources.
  • It's more work, because you have to build it yourself.

Instead, I recommend you use the existing facilities, which for macOS, is to use launchd to launch a launch agent or daemon. All you have to define is a job (a plist file), which configures what you want to run, and in response to what events (it can be time, but there's also support for running in response to a file showing up in a folder, a USB device being plugged in, etc.). From there, launchd will take care of starting your program at the right time.

See Apple's Daemons and Services Programming Guide for the full details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文