App Launched from Safari Displays: Do you want to allow this page to open "(null)"? - objective-c

I am writing a Mac OS app in Go/Objective-C. Suffice it to say, I am not using Xcode and have assembled the application bundle by hand. Here is what it's filesystem hierarchy looks like
${APPNAME}.app
Contents
MacOS
${APPNAME} (binary)
Resources
Base.lproj
InfoPlist.strings (text)
Info.plist (text)
The bundle launches fine. Application works as expected. I have a CFBundleURLTypes dictionary in my Plist file which defines a URL scheme for my application.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>${APPNAME}</string>
<key>CFBundleURLSchemes</key>
<array>
<string>zzz</string>
</array>
</dict>
</array>
(Note: ${APPNAME} is something like "MyApp." It is not a Java-style, reverse DNS name string.)
When I click on a link in Safari that uses the zzz:// scheme, I get a message that says:
Do you want to allow this page to open "(null)"?
Why is that? I have defined my application name in both the Info.plist file and in the InfoPlist.strings file.
The InfoPlist.strings file simply contains this:
CFBundleName = "My Wonderful Application"

There apparently was some sort of caching mechanism happening. When deployed to another Mac system we managed to procure, which never had the software in question installed on it, this problem did not occur.
Note: The previous system which behaved erroneously had, at the beginning of each test, the software completely removed from it. Finder, Safari or some other Apple software must have secretly cached the app name as "(null)".
Answer: Install it on a new Mac machine, or completely restore (with no backup) the machine you are testing with.

Related

Is there a way to apply ITSAppUsesNonExemptEncryption in a Swift Playground?

In Swift Playgrounds 4 you can upload apps to App Store Connect. Like in Xcode, by default App Store Connect will complain every build is missing compliance when you upload it and cannot be tested until you provide the information.
If you are building an application in Xcode that doesn't use non-exempt encryption you can set the key ITSAppUsesNonExemptEncryption in your Info.plist and App Store Connect will skip the compliance step for each build.
Swift Playgrounds don't have an info.plist, so is there a way to provide this value inside Swift Playgrounds or is this just a minor oversight?
If you open the .swiftpm file package, and look at the Package.swift file, you will see the .iOSApplication product. It takes an optional value, additionalInfoPlistContentFilePath. Give that a relative path to an Info.plist file you create, and values from that file will be merged into the app's final Info.plist when you build.
(I know the Package.swift file has a comment saying you shouldn't edit it because it is generated, but Apple employees on Twitter have said they try to be good about not overwriting valid changes made. I can confirm the plist one is working for me.)
Details here.

Modify plist file in xcode

I developed an application that has a Data.plist file, created by me.
The idea is that by UISwitch Data.plist, which works in the simulator iPhone Xcode, amend does not work on an actual device.
Why is that ?
How I can make it work?
Stay tuned to your answer,
Greetings.
Your bundle is read-only on a device.
The best solution would be to load your plist, save it in a directory of your chosing using the NSFileManager, and then work with the file in that directory.
Your plist inside the bundle would ONLY be used the very first time your user uses the app, as a blueprint if you will, and then you would work with the .plist you saved in the documents directory.
This small code snippet will explain how to copy a file from your bundle safely. He uses it with a database but it's really the same for any kind of file.

Apple Help Authoring

I'm following this guide to public some Apple help. The application I work on has had help built in for years, but it stopped working all of a sudden, and no changes were made to the application plist or any of the help files. We're presuming Apple changed something, so I made sure it met the specifications Apple were requiring. When I say "not working" I mean that our links using NSHelpManager will open the help viewer but bring back a page not found.
Things to check off the list:
There is an anchor with the correct name at the top of the page
The folder structure is a replica of what is in that article linked earlier
We are re-indexing the help pages
We do clear out all of the caches
Here's the code we use to open the help page:
NSString *locBookName = [[NSBundle mainBundle] objectForInfoDictionaryKey: #"CFBundleHelpBookName"];
[[NSHelpManager sharedHelpManager] openHelpAnchor:#"mypage" inBook:locBookName];
In this instance we'd have a page with a <a name="mypage"></a> at the top so it should link correctly. Our scripts are as follows:
hvfix (clears all caches):
rm -rf ~/Library/Caches/com.apple.help*
rm -rf ~/Library/Preferences/com.apple.help*
rm -rf ~/.Trash/*
killall helpd
defaults write com.apple.helpindexer IndexAnchors YES
updatehelpindex.sh (re-generates indexes)
#!/bin/sh
hiutil -C -f MyApp.help/Contents/Resources/English.lproj/MyApp.helpindex
MyApp.help/Contents/Resources/English.lproj/
We do a build, drop the folder into the Applications folder in order to register the application + the help. We even try a restart or logoff/logon and still we get nothing. I know it's a very fiddly process but nothing we try seems to work. All we want to be able to do is use the NSHelpManager to open a help anchor. Undoubtedly this works in 10.6+ as so many other apps do it (some reports suggest it won't work in 10.7/8, but they must be untrue).
Ideas?
EDIT (folder structure):
This is within the MyProj.help folder that's in a sub-directory of the overall Cocoa project called 'help'.
+ Contents
Info.plist
+ Resources
+ shrd
(a bunch of image files)
+ English.lproj
MyProj.helpindex
index.html
+ css
+ pgs
+ gfx
And in the folders are precisely what's as expected, 'css' has a bunch of CSS files in it, 'pgs' has the HTML pages and 'gfx' has image files.
It appears to be a bug in the way sandboxing affects the HelpViewer's directory search when a HelpBook is registered with the system (as outlined in this bug report), which fully explains why it shows up on 10.7 and 10.8, but not 10.6 and earlier. Even Apple's NSAlertTest suffers from it. Unfortunately, as the bug report remains unsolved as of the time of this post, there is no viable solution, but what few tests I've run have confirmed that NSHelpManager flat-out ignores the sandboxed help plist on my machine.
OK, this one's been quite a roller-coaster of confusion but it has something to do with with your folder structure setup in Xcode. Here's some things worth knowing:
People opt to put it in English.lproj. Don't do this, for a few reasons. First it won't display the sub-directories/files in Xcode if you dragged the help folder into your file listing, and secondly stuff in that folder is supposed to be flat, not structured.
Create a "help" folder in the root and put your files in that. You can then put them in a sub-directory called "English.lproj" if you want localisation.
Don't create a ".help" folder which contains all of your help files. This seems to break indexing. We don't know why.
Instead, have /help/Contents/stuff and drag and drop that folder into your project directory listing (mine's in "Resources" group). Make sure it's a blue folder and that you can see the entire directory (all of your HTML etc.)
Run the help indexer against it to generate the .helpindex file
Make sure your plist entries reflect the name of that folder and the meta tag name specified in your index.html file
If you follow the above rules things should work fine. It seems in ML that creating a .help folder breaks things from here on out, so basically, don't follow the Apple guide.
I am adding this response here because I found a very dumb way of fixing this. By using Apple's hiutil command line tool, I saw that all Apple's official help books use some sort of indexing using a redirector file:
$ hiutil -Df /Applications/Xcode.app/Contents/Resources/Xcode.help/Contents/Resources/en.lproj/search.helpindex
> <?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>dev01043b473</key>
> <array>
> <string>/redirect.html?topic=dev01043b473</string>
> </array>
> <key>dev0125622ec</key>
> <array>
> <string>/redirect.html?topic=dev0125622ec</string>
> </array>
> ...
Inspired by this, I attempted to generate a .searchindex file manually using NSUnarchiver to open the file created by hiutil, changing it, and using NSArchiver to write back to a file, but my anchors would still not work like I wanted.
I cloned TextEdit's help book based on Apple's undisclosed "Eagle" help engine (/Library/Documentation/Resources/Eagle/index.html), which produces the pretty help books all Apple apps use now. But because I was using HTML indexing, my anchors would lead to plain HTML files, which weren't prettified by Eagle.
Then I struck this dumb idea: It's a lot of work, but if you create a separate html file for each anchor, you can use the meta redirect head tag just like in the redirect.html, except your redirects will be static. Therefore, for my editor-prefs.html file, I created a editor-prefs-anchor.html file with the following contents:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Editor Options</title>
<meta http-equiv="refresh" content="0;url=../index.html?localePath=en.lproj#/editor-prefs" />
</head>
<body>
<a id="editor-prefs">
</body>
</html>
The meta redirect tag takes care of redirecting to the proper Eagle-powered URL, and it works!
If anyone was struggling with Eagle like me, I hope this helps you!
I ran into this same issue (anchors not working in my app's help book) and did some poking around in the help books of other Apple apps, specifically Safari. I found this interesting entry in the Info.plist in the Safari.help bundle in the Safari app:
<key>HPDBookIndexPath</key>
<string>search.helpindex</string>
I changed this to match the name of the .helpindex file in my app's help bundle, and anchors started working.

Drag and drop of file on app icon doesn't work unless the app is currently running? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I make an OS X application react when a file, picture, etc is dropped on its dock icon?
For some reason, if I drag and drop a file on my apps icon... it doesn't work unless the app is currently running.
Here is the current Info.plist entry for CFBundleDocumentTypes
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>*</string>
</array>
<key>CFBundleTypeName</key>
<string>NSFilenamesPboardType</string>
<key>CFBundleTypeRole</key>
<string>None</string>
</dict>
</array>
Thoughts, opinions, tips, tricks?
Repo here: https://bitbucket.org/crewshin/maketx_dnd
The launching behavior on drag/drop to icon comes from having the file types your application can handle defined in CFBundleDocumentTypes in your Info.plist file.
Your app is not launching because you declared that you do not understand any file type whatsoever.
<key>CFBundleTypeRole</key>
<string>None</string>
To declare your app can read a file type, you should use 'Viewer' or 'Editor' for the CFBundleTypeRole.
The documentation is somewhat unclear about using an * to specify CFBundleTypeExtensions. It used to be a valid way to specify your app can only all file types in 10.4 and earlier, but it may not work after OSX 10.6. Try setting it to an extension you can actually read.

Using preprocessor definitions in iOS App info.plist

I have an iOS app that uses SSO with Facebook as part of getting your app to work with Facebook's SSO you have to specify the FacebookAppId and callback url in the info.plist. I have 2 different Facebook groups one for testing and one for production. I want to be able to have the values of the two keys specified above set based on preprocessor directives.
In my MessageBomb-Prefix.pch i have the following, which works fine:
#ifdef TEST
//Development environments
#define PARSE_APP_ID "dev parse app id"
#define PARSE_CLIENT_ID "dev parse client id"
#define FB_APP_ID "dev facebook id"
#else
//Production environments
#define PARSE_APP_ID "prod parse app id"
#define PARSE_CLIENT_ID "prod parse client id"
#define FB_APP_ID "prod facebook id"
#endif
However in my info.plist i have done the below, but it doesn't seem to work:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fb${FB_APP_ID}</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>${FB_APP_ID}</string>
Is it even possible to do what i'm trying to do. I've set the project to preprocess the info.plist.
Thanks
Peter
If you go into Build Settings you can set Preprocess Info.plist File to YES and then set Info.plist Preprocessor Prefix File to a .h file you've placed in your project with #define directives.
So for example if I add a key to my Info.plist file: testKey with the value TEST_VALUE. Then I place test.h in my project with:
#define TEST_VALUE hello_world
And then I set Preprocess Info.plist File to YES and Info.plist Preprocessor Prefix File to test.h
The value of that key, when retrieved is now "hello_world". If you change the value of the macro a lot you may find you need to do Product/Clean to see changes because XCode seems to cache the compiled value.
To access in plist:
Create a new variable
Define it
Use it in your info plist
The Info.plist preprocessor will let you use build settings in your Info.plist, not #defines. So you can define FB_APP_ID as a custom user build setting in your target (and give it overrides for different schemes), and this value will then be available to Info.plist. However, user build settings don't get exposed to your code. That is, unless you muck with your Preprocessor Definitions build setting and add an entry that looks like
FB_APP_ID=#\"$(FB_APP_ID)\"
(the backslashes are required to get the double-quotes past the shell invocation)
If your app ID may contain spaces, then you'll need to add quotes to get past the shell invocation:
FB_APP_ID="#\"$(FB_APP_ID)\""
In the end, you'll have build settings that looks something like this: