Can you dynamically assign CFBundleDocumentTypes to your Cocoa application? - macos

Can you dynamically assign CFBundleDocumentTypes to your Cocoa application? Meaning during run time can I assign more extensions for my app to handle.
Currently I set some extensions for my app to handle using CFBundleDocumentTypes in the Info.plist, but I would like to do this through code while the application is executing (during run time). Basically can I make Launch Services aware of new extensions without modifying the Info.plist file.
Thanks.

At the moment, there’s no public API1 for an application to dynamically (un)register document types with Launch Services during runtime.
Open Emu faces this very problem. Users are able to selectively download/install emulators, which are bundles whose Info.plist files define document types. Upon installing an emulator, the types defined in the bundle need to be part of the types as defined in the application Info.plist. Open Emu rewrites the application Info.plist in order to do so — see -updateInfoPlist in OEGameDocumentController.
Note that overwriting the bundle Info.plist is a violation of Mac App Store’s policy.
We have filed radars asking for runtime (un)registration of document types. I suggest you file another one, too, which should be closed as a duplicate of #2526726. Even if it’s a duplicate, it’s important to file it anyway so that Apple have an estimate of the number of people that need this feature.
1It might be possible via SPI, though. When I was looking into this, I stumbled upon _LSRegisterItemFromItemInfo() in Launch Services.

Related

Can I hide info.plist in a kext? or can I dynamic create info.plist?

Can I hide info.plist in a kext? or can I dynamic create info.plist for a kext?
I have a codeless kext where it only has info.plist, however, I dont want to expose info.plist to everybody so they can simply just copy my codes... so I was thinking either hide the info.plist or dynamically create info.plist while driver is loading or encrypt the entire kext?
You can't encrypt/obfuscate the Info.plist itself. It is part of the code signing process and requirement though, so it's not trivially modifiable.
You don't state it specifically, but I'm assuming there's some property in the I/O Kit Personality dictionary that you want to hide? Those properties can equivalently be set from code, specifically in the init() function of your driver class, unless they're required for matching. Note that any properties you've set are world-readable in the I/O Kit Registry at runtime though, so I suspect this isn't what you want.
If the information you're trying to hide is part of the matching conditions, for example you're attempting to hide product IDs of thus-far unreleased devices, you can, depending on your driver family's matching rules, probably implement this logic in code in the probe() function. I wouldn't make the matching rules in the Info.plist too broad though, or your kext will be loaded every time e.g. a provider with the given provider class turns up. This is unnecessarily inefficient.
Obviously, in both cases, your kext will no longer be codeless, but you can obfuscate to your heart's content in the C++/C/assembly code.
If you want a more specific answer than that, you'll need to be more specific in your question.

Can I put info about multiple executables inside the same bundle in Info.plist?

I have a Qt app that uses Assistant to display help.
On Mac, I am packaging he Assistant inside the bundle. The only way I can include all its libraries is by placing the Assistant executable inside the same MacOS folder as the app executable, and properly link all the library dependencies.
Is there a way to place information about both executables in the Info.plist ?
No, you can't put info about multiple executables inside the same Info.plist. (Well, you an always puts custom keys into the Info.plist and store whatever property list data you like there, but the system won't pay any attention to those keys.)
Why not bundle the Assistant into its own bundle and put that bundle inside the main app's bundle? The Assistant bundle would have its own Info.plist file. Also, if you create a question about whatever linking or dynamic loading problems made you think you had to put it all into the main bundle, you might find there's a better solution.
placing the Assistant executable inside the same MacOS folder
I recommend not to do this. The Assistant is a resource to the main application and so it should reside in the resources folder. If you want to launch the Assistant app from the main app, you can then locate it by name.
You can only define one application in the Info.plist. If you were to add more, there would be a conflict in keys.
For example, CFBundleIdentifier is a unique URI that names the bundle (e.g. com.apple.calculator). The OS uses the URI to register the application with the OS when an application is, for example, copied to the /Applications folder. The OS expects the key to be a child of the root dictionary and its value must be unique. If there were multiple keys named CFBundleIdentifier, it would not know which is valid.
Although you can throw almost any junk into a Mac application bundle, much good will not come to you.
If I understand right, you have both a Mac Application (bundled normally) and a side-application you call the "Assistant" you want embedded in the same application bundle.
You also mention libraries (.dylib's I guess) that must reside in the same directory as the assistant.
Now - if these libraries are only used by the Assistant side-application, I would recommend that you bundle the assistant as a Code-bundle (Apple provides lots of information about these, and you have easy to use templates from Xcode). You can then use Xcode to copy it into the right place within the main application's bundle (I'd choose "Plugins") and use NSBundle APIs to launch it.
However, if those .dylibs are shared between the main app and the assistant - then I'd say go ahead, stick your assistant, .dylibs and main app's binary files in the same "MacOS-X" directory, and use posix APIs, or shell command to launch the assistant. Of course it will share (if possible) every resource of the main application, because they are located at the same place. However, the main app's bundle can only have ONE CFBundleExecutable entry, and that should point to your main application's binary.

Windows Phone: Targets, Branding

i have an app that will be shipped by different providers. So i need to exchange the backgrounds etc, ss there is probably some kind of unique identifier for each app i also need different projects for that. What's the best practice to do this on windows phone ? Do i have to write own "Wrapper"-Projects ? (In iOS there is a concept called targets where i just link relevant branding files, appname, identifiers etc)
Thanks for your help !
In XAML, you can use Styling and Templating to dynamically change the whole look and feel of your application.
The same principal applies to Windows Phone apps as well. Then all you got to do is, maintain different style xaml files and apply them to create unique builds, or once the application launches.
Update: As willmel suggests below, which I forgot to mention, localization techniques mentioned here are a great way to maintain application strings.
Update 2: You can package your 'themes' into separate ZIP files, as demonstrated here and use post build events and VS commands to create different packages. You can always call msbuild from the command line as well and customize your build process even further. You can use different manifests this way as well.
If you have provider information which is language specified, you can download a sample project here:
http://www.pocketpc.ch/windows-phone-7-entwicklung/158405-textbox-string-integer.html#post1381376
or another here, or in VB
Once, you know the provider, you can select your resource file.
That article from Tim Heuer can show how you can work with less work for different situations like used in XCode iOS. Additional to strings you can use image URL as well.

Cocoa/Mac - external config settings for running app

On windows, we use registry or .ini or xml config etc for settings that apps can pull in at run time w/o making code changes.
On Mac/Cocoa, what're the best approaches to do that and what are the corresponding APIs?
See NSUserDefaults and the User Defaults Programming Topics. NSUserDefaults stores the data as a property list in the ~/Library/Preferences directory.
As #ughoavgfhw answered, per-user preferences should be stored in ~/Library/Preferences, and NSUserDefaults is available to support that.
If you are instead thinking of configuration information (the line between configuration and preferences being of course fuzzy) then you might wish to use the Application Support folder. There are two of these, per-user located at ~/Library/Application Support and system-wide at /Library/Application Support. In either of these create a folder named after your application or company and stored whatever you wish to in it. If you are planning on submitting to the Mac App Store only the per-user folder is allowed - you must replicate your configuration information for every user.

Two executables in one bundle on MAC

Is it possible to have two executables each with its own plist to share the same bundle. Then depends on the way app is executed (parameters) to load the appropriate executable.
Imagine the case where we have a main application (executable with UI) and the mini application (shorter version of the main app also with its own UI) and then depend on the parameters user used for starting the application execute the appropriate executable in the same bundle.
Cheers
Not exactly, but you could achieve something similar.
You could have a master Application bundle, which figures out which version of the code to run, and then have multiple plug-in bundles (as resources of the application) which actually implement the different versions. Each plug-in bundle would have its own Info.plist / nib files / etc.
See the documentation for NSBundle for details of how to load bundles and run their code.
I think I understand you. You want to share a plist between two executables. Just refer to the same plist in each case: tutorial for single executable plist.
Don't know if it's possible. Honestly I doubt it because the plist information is also used to define the icon and so on, so you would confuse the Finder if this would be possible (which icon should it display?). However, I am not an expert in Bundles, at all.
I give you a workaround. Create a demultiplexing script that runs the proper executable according to your parameters, and then associate the script with the plist information.

Resources