如何在OS X中调试屏幕保护程序

问题描述 投票:20回答:9

我想知道是否有任何不错的方法,除了NSLog-ing几乎所有东西 - 在OS X中正确调试Screensaver应用程序包?

“屏幕保护程序”是Xcode中的项目类型,但显然没有Build and Go调试。此外,我发现实际上我的捆绑包已经加载到了

/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app 

应用程序作为某种插件。

那么调试代码有一个不错的方法吗?查看崩溃报告和NSLoging到控制台有帮助,但它远非完美。

objective-c xcode macos debugging screensaver
9个回答
14
投票

有一篇旧的MacTech文章描述了屏幕保护程序的开发周期。文章中还有一个Part 2。查看“调试提示”部分。

我觉得这个方法很痛苦,所以我写了一个应用程序,基本的应用程序是一个窗口和一个控制器,用我的新屏幕保护程序包初始化ScreenSaverView。一旦工作正常,我必须做的就是测试一个变化,在Xcode中命中了Command-R。


7
投票

由于OS X 10.11 El Capitan的系统完整性保护功能,调试器无法附加到从/System/运行的任何内容。此外,此处的其他信息适用于旧版本的Xcode。

以下是我使用Xcode 7.2开发El Capitan的方法:

  1. /System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app/复制到/tmp/。 (由于.xcscheme引用了完全限定的路径,因此将其复制到公共场所最适合协作,而不是特定用户主目录中的某个位置。)
  2. 编辑项目的.xcscheme: 将“可执行文件”的“运行”操作设置为复制的应用程序,并添加参数:-debug -background -module "<product-name>"(其中<product-name>是没有.saver扩展名的包名称)。 添加一个预操作脚本(下面的源代码),其shell设置为/bin/bash,其构建设置来自该方案。它创建了一个符号链接到.saver中构建的~/Library/Screen Savers/

资源:

SCREEN_SAVER_PATH="${HOME}/Library/Screen Savers/${FULL_PRODUCT_NAME}"
if [[ -d "${SCREEN_SAVER_PATH}" || -f "${SCREEN_SAVER_PATH}" || -L "${SCREEN_SAVER_PATH}" ]]; then
    rm -Rf "${SCREEN_SAVER_PATH}"
fi
ln -s "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" "${SCREEN_SAVER_PATH}"

现在,当您点击Xcode的“运行”按钮时,屏幕保护程序将在桌面上以壁纸模式运行,您可以使用调试器。


6
投票

您可以通过执行将加载插件的应用程序来调试插件。

因此,要调试屏幕保护程序,请打开插件项目,从“项目”菜单中选择“新建自定义可执行文件”,然后将应用程序设置为屏幕保护程序引擎。

要调试屏幕保护程序,您可能还需要使用第二台Mac并使用remote debugging,这样您的用户界面操作就不会干扰屏幕保护程序。


3
投票

有几个Mac OS X应用程序将运行屏幕保护程序:SaverLab,Screenalicious等。只需在网络上找到其中一个并下载它,然后将其设置为目标可执行文件(如Peter N Lewis所说)。

为避免在每次构建后将构建产品复制到'〜/ Library / Screen Savers /',您可以添加自定义构建脚本(注意:我正在使用'/ bin / tcsh -x'作为shell):

#remove the old screen saver or link
rm -Rf "${SCRIPT_OUTPUT_FILE_0}"

#if this is a debug build…
if ("${CONFIGURATION}" == "Debug" ) then

# create a symbolic link from our screen saver to this users screen saver directory
ln -sfv "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"

#if this is a release build…
else if ("${CONFIGURATION}" == "Release" ) then

# copy our screen saver to this users CMM directory
cp -Rfv "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"

endif

然后将其输入文件设置为“$ {BUILT_PRODUCTS_DIR} / $ {FULL_PRODUCT_NAME}”,并将其输出文件设置为“$ {HOME} / Library / Screen Savers / $ {FULL_PRODUCT_NAME}”。

现在,当您构建/运行项目时,它将自动魔术链接到您的调试版本或复制您的版本构建。


3
投票

您还可以将屏幕保护引擎('/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app')作为目标可执行文件并将其传递给-background标志(因此它在所有内容后面而不是在所有内容之前运行) 。


2
投票

正如彼得所说,您可以通过执行将加载插件的应用程序来调试插件。

但是,您可以使用系统首选项,而不是使用屏幕保护程序引擎。当首选项出现时,导航到“桌面和屏幕保护程序”下的屏幕保护程序以加载插件。

它并不完美,因为您的视图不是全尺寸,但它比设置远程调试更容易。


1
投票

不一定是最好的方法,但你可以从另一台机器ssh并从gdb启动ScreenSaverEngine(未经测试)

编辑:

另外,您可以尝试添加新的应用程序目标并将您的ScreenSaverView添加到IB中的窗口,您可能需要手动配置设置之类的东西,但它可以帮助一些并且应该可以正常工作,因为ScreenSaverView是NSView的子类


0
投票

如果您制作ScreenSaverEngine应用程序的副本,并使用您的开发者ID进行签名,它将修复系统完整性保护阻止附加调试程序的情况。只需确保将可执行文件设置为您自己签名的副本。


0
投票

我想指出,@ Karl的解决方案对我来说是最好的。但是,如果你像我一样,你每晚重新启动电脑,你可能想要考虑:

cp -Rn /System/Library/CoreServices/ScreenSaverEngine.app /tmp

在他的回答中提到的pre-Build shell脚本的开头。这将自动为您执行复制步骤。

(虽然我相信这真的属于评论,我的xp还不够高)

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