我正在尝试实现注册过程,该过程允许我的iOS应用程序显示在其他应用程序的"打开方式"列表中(如Apple的文档交互编程主题中所述).我希望我的应用程序能够处理来自任何提供标准音频文件格式(MP3,AIFF,WAV等)的应用程序的音频.
据我所知,我需要做的就是将CFBundleDocumentTypes
关键字和相关的子数据添加到我的应用程序的Info.plist中.这是我放入的(通过Xcode 4的文档类型编辑器):
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>scrubbulator-icon</string>
</array>
<key>CFBundleTypeName</key>
<string>Audio</string>
<key>LSHandlerRank</key>
<string>Alternative</string>
<key>LSItemContentTypes</key>
<array>
<string>public.mp3</string>
</array>
</dict>
</array>
Run Code Online (Sandbox Code Playgroud)
添加此代码不会在应用程序的"打开方式"菜单中显示我的应用程序(我在iPhone上测试,使用Dropbox中的MP3作为文件源.应用程序AudioMemos和Evernote都显示为Dropbox中的MP3文件,所以我知道支持的格式).有什么明显的东西我做错了,还是还有其他我需要实现的东西?
(注意:我没有UTExportedTypeDeclarations
在我的Info.plist中设置一个项目,因为我理解这些只是自定义UTI所必需的.因为我使用的是系统UTI,我认为它不应该是必要的,但如果我有正确的请纠正我我错了.)
编辑
我添加了以下Exported Type UTI,但没有成功:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>kUTTypeMP3</string>
</array>
<key>UTTypeDescription</key>
<string>Audio file</string>
<key>UTTypeIdentifier</key>
<string>kUTTypeMP3</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mp3</string>
</array>
</dict>
</dict>
</array>
Run Code Online (Sandbox Code Playgroud) 我正在开发一个Cocoa应用程序,它使用自定义方案的URL启动/激活,该方案在Info.plist文件中注册,如下所示:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Open myscheme:// URLs</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myscheme</string>
</array>
</dict>
</array>
Run Code Online (Sandbox Code Playgroud)
我的问题是,一旦应用程序启动或激活,我该如何判断启动应用程序的URL是什么?在iOS上,使用-application:openURL:sourceApplication:annotation:UIApplicationDelegate上的方法很容易,因为它传递了NSURL实例.
我希望能够通过myscheme:// do/something/awesome等URL将数据传入我的应用程序
你能动态地将CFBundleDocumentTypes分配给你的Cocoa应用程序吗?运行时的含义可以为我的应用分配更多扩展名来处理.
目前我为我的应用程序设置了一些扩展,以便在Info.plist中使用CFBundleDocumentTypes来处理,但我希望在应用程序执行时(在运行时)执行此操作.基本上我可以让Launch Services知道新的扩展而无需修改Info.plist文件.
谢谢.
在我的objective-c程序中,无论系统的默认浏览器是什么,我都需要在Safari中打开一个URL.这意味着这不起作用,因为它可以启动Firefox或其他任何浏览器:
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws openURL: url];
Run Code Online (Sandbox Code Playgroud)
我想我很接近这个:
[ws launchAppWithBundleIdentifier: @"com.apple.Safari"
options: NSWorkspaceLaunchWithoutActivation
additionalEventParamDescriptor: NULL
launchIdentifier: nil];
Run Code Online (Sandbox Code Playgroud)
只需要弄清楚如何传递URL作为参数......有更简单的方法吗?
谢谢!
更新:以下代码使用我想要的URL启动Safari,但Safari立即终止!任何想法为什么会这样?
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws openURLs: urls withAppBundleIdentifier:@"com.apple.Safari"
options: NSWorkspaceLaunchDefault
additionalEventParamDescriptor: NULL
launchIdentifiers: NULL];
Run Code Online (Sandbox Code Playgroud)
我观察到了同样的行为LSOpenFromURLSpec
.如果Safari实例正在运行,它可以正常工作.如果没有运行Safari实例,它将启动一个新实例并立即终止它.
更新2: Safari仅在嵌入了Flash的网站崩溃.根据上面的代码,我可以很好地打开google.com,例如,Safari会崩溃为YouTube视频.
我使用Qt 5.3.2开发了一个Mac应用程序.此应用程序处理具有特定扩展名的文件(假设.xyz
).
我创建了一个名为XYZ.icns的图标文件,并将其添加到我的应用程序包资源文件夹(MyApp.app/Contents/Resources/XYZ.icns
)中.
我还修改了bundle的Info.plist文件以设置文件关联.我添加了这个条目:
<key>CFBundleDocumentTypes</key>
<array>
<!-- Registered file accociation -->
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleTypeName</key>
<string>XYZ</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>xyz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>XYZ</string>
</dict>
<array>
Run Code Online (Sandbox Code Playgroud)
结果:文件关联工作(双击文件确实打开了我的应用程序)但是,图标没有被替换(仍然显示空白文档图标).
有什么我错过了吗?我查看了其他应用程序的示例,似乎没有什么比我做的更多.
编辑:我做了一些测试.我使用以下命令转储了启动服务数据:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/Current/Support/lsregister -dump
Run Code Online (Sandbox Code Playgroud)
在结果中,我可以在文件中找到包含图标信息的文件类型:
...
--------------------------------------------------------------------------------
Container mount state: mounted
bundle id: 105396
...
path: /Applications/MyApp.app
name: MyApp
...
--------------------------------------------------------
claim id: 27628
name: XYZ
rank: Default
reqCaps:
roles: Editor
flags: relative-icon-path doc-type
icon: Contents/Resources/XYZ.icns
bindings: .xyz
--------------------------------------------------------------------------------
...
Run Code Online (Sandbox Code Playgroud)
编辑2:过了一段时间,它终于开始自己工作了.一夜之间,有一个操作系统更新已安装,我还必须关闭计算机(启动服务可能自己刷新了一些东西).我会将我的问题更新为:如何确保启动服务在安装或修改应用程序时刷新关联的文件图标?
我正在寻找一个解决方案来枚举安装在(Mac)OS X系统上的所有应用程序,即使用LaunchServices注册的所有应用程序包.
(请注意:lsregister
可以在下面找到/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister
).
目前我正在使用输出lsregister -dump | grep -E '^.*[ \\t]*path:[ \\t]+(\/.*)$' | grep -Eo '\/.*'
,其中有一些问题:
.app
带有换行符的捆绑包(\n
在UNIX上有效)无法正确处理(通过编写正确的解析器可以解决此问题)lsregister
没有正确处理奇怪的文件名(例如包含RTL标记).lsregister
似乎忽略了名称中带有RTL标记的文件.如果需要,可以通过运行以下命令在名称中创建一个RTL文件.
python -c 'import shutil; shutil.copytree(u"/Applications/TextEdit.app", u"/Applications/ThisIsAWeird\u202EApp.app")'
Run Code Online (Sandbox Code Playgroud)
这样做了以后,lsregister -dump | grep ThisIsAWeird
会不会透露它.但是,当您右键单击文本文件并转到"打开方式"时,您将启动LaunchServices和Finder仍然支持该文件.
简单地枚举所有文件/Applications
和其他目录都不起作用,因为LaunchServices知道任意文件夹中的应用程序包,我也需要这些应用程序.
显然,有一个私有的API函数_LSFindApplications
,它正是我需要做的,但我不能让它工作,并没有在互联网上找到任何非官方的文档.(证明它存在:nm /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/LaunchServices | grep __LSFindApplications$
)
直到现在我虽然system_profiler
@Anoop建议的方法有效,但今天我发现lsregister
仍然可以获得更多的二进制文件.在所有机器上都有一些或丢失,有些似乎只是在system_profiler
你用另一个OS X安装外部卷时丢失了.这是一个列表system_profiler
,在lsregister
我的一台机器的输出中缺少(但存在):
/Applications/Automator.app/Contents/Resources/Application Stub.app
/Applications/Google Chrome.app/Contents/Versions/30.0.1599.69/Google …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用统一类型标识符的应用程序.具体来说,我正在调用UTTypeCreateAllIdentifiersForTag()
并传递各种MIME类型.
我希望这个功能(不同于UTTypeCreatePreferredIdentifierForTag()
)将给我最具体的UTI以及它所符合的所有UTI.这似乎不是这种情况 - 它要么返回单个UTI,要么辅助UTI是虚假的.
UTTypeConformsTo()
在同一个头文件中定义了函数,但我更喜欢一个返回此UTI符合的所有类型的数组的函数.
对我来说似乎有希望,因为这MDItemCopyAttributeList()
将返回这样的清单.也就是说,它需要一个MDItemRef
,可以从文件路径或URL创建 - 这不是很好.有时我的数据只存储在内存中,我只有一个MIME类型.
我是否必须遍历UTI的整个数据库以获取此信息,或者我是否遗漏了某些内容?
有没有人知道找到(在文件系统中)具有给定包标识符的每个应用程序的好方法?NSWorkspace
和启动服务允许您按包标识符查找应用程序,但只返回单个结果.我怀疑Spotlight(NSMetadataQuery
)可能有所帮助,但我对它的API有点不清楚,所以我不确定是否有合适的密钥.
有一个命令行lsregister
工具(在LaunchServices.framework内部),可以告诉它(重新)注册系统上的所有内容,然后转储它所知道的所有内容的报告.依赖于它似乎不太理想,因为它没有文档,解析它的输出可能是一个痛苦.
(背景:我正在构建一个用于游戏修改的应用程序,并希望提供用于从支持的游戏的简短列表中快速选择的UI,而不是要求用户在Open面板中挖掘整个文件系统.但是,我希望它相当可能是用户安装了多个游戏副本:发行版和测试版,用于修改的额外副本等)
在iOS Safari中单击“共享”按钮时(通过工具栏或长按链接),我希望我的应用程序显示为“在...中打开”选项(例如,“在新闻中打开” ”),以便我的应用(这是另一种网络浏览器)可以打开Safari共享的任何内容http://
或https://
URL。
我已经在苹果info.plist
文件中注册了文档类型“ URL”(我相信这是正确的类型,如果此假设是错误的,请更正!),我CFBundleDocumentTypes
可以从Apple的“注册应用程序支持的文件类型”文档中猜到,他们的技术问答以及与之相关的StackOverflow帖子1 2 3:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>appIcon320</string>
<string>appIcon64</string>
</array>
<key>CFBundleTypeName</key>
<string>URL</string>
<key>CFBundleTypeRole</key>
<string>Editor</string> <!-- Note: I have also tried 'Viewer' -->
<key>LSHandlerRank</key>
<string>Owner</string> <!-- Note: I have also tried 'Default' -->
<key>LSItemContentTypes</key>
<array>
<string>public.url</string>
</array>
</dict>
</array>
Run Code Online (Sandbox Code Playgroud)
我也用以下代码编写了这个存根方法AppDelegate.swift
(尽管我认为实际上与使我的应用程序显示为“打开方式...”选项的第一阶段的成功无关):
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {opening-in-app-getting-uiapplicationlaunchoptionsurlkey-from-launchoptions?rq=1
print("Received URL: \(url); from …
Run Code Online (Sandbox Code Playgroud) launch-services ×10
macos ×7
cocoa ×3
info.plist ×2
ios ×2
uti ×2
defaults ×1
nsworkspace ×1
qt ×1
safari ×1
url ×1
url-scheme ×1