In-house OS X app updater - handling of "signature folder"? - macos

I am in the process of adapting our custom (auto-)updater to work with OS X apps. (These OS X apps will be distributed outside of the Mac App Store.)
After the new bundle is downloaded, I am selectively overwriting certain files. However, it is unclear to me whether there is a situation where I should also overwrite the _CodeSignature folder in the "old" app with the newer one.

As (currently) the Gatekeeper checks a downloaded app only the first time it is run, the above becomes a non-issue (again: for the time being).

Related

OS X Background Fetch Equivalent

I'm familiar with the Background Fetch in UIKit but I was wondering if there is an equivalent for OS X apps.
My application is bundled with a Safari App Extension that needs to update frequently. Auto update does not look like it's supported from what I've read in the forums on the App Extensions since it's bundled to the OS X app. I have a shared data storage between the app and the extension so my ideal solution would be having the app run (in the background wether the user has it open or not) periodically check for the latest version. Then when the user is actually engaging with my extension it will notify the user of the update. This is why a solution like Sparkle is not desired.
I have everything down, but I'm lost on running the background process. Appreciate any help or creative solutions!

Create an OS X today widget without a host app

Is it possible to create an OS X Yosemite Today Widget without a host app, like the builtin Weather, Stocks and World Clock apps?
You can not do that simply because your executable is still running in the companion app rather in the extension. It means that codes are actually belonged to the companion app. So, you must have your companion app.
Info from the official documentation:
An app extension is different from an app. Although you must use an
app to contain and deliver your extensions, each extension is a
separate binary that runs independent of the app used to deliver it.

How is OS X Deployment Target presented to the end user?

The build setting OS X Deployment Target in Mac OS X specify which minimum OS X version that is required to run the application.
From the docs:
This identifies the earliest OS version on which your software can run. By default, Xcode sets this to the version of the OS corresponding to the base SDK version and later.
If the end user tries to install and run the application on a lower version of Mac OS X than the Deployment Target, how is this presented to the end user?
Basically I want to know if the deployment target can be used to prevent users with out of date from using the application in a user friendly way, so they don't just get an "ERROR: CAN'T START" in their face.
The deployment target isn't presented to the end user, but there is an Info.plist key LSMinimumSystemVersion that tells users when their OS is too old.
On the latest versions of macOS, the user will see two things when his version of macOS is too old for a specific app:
The app icon has a cross overlay.
When the user starts the app, a message will be presented explaining that a newer version of OS X/macOS is needed to run the app.
Found out the hard way that OS X Deployment Target is not preventing the user from starting the application at all, even though they have a too old version of OS X.

OSX Sandbox: Launch a different executable based on OS version

I have an application in the Mac App Store. I'm trying to support users going back to Snow Leopard but this is becoming increasingly difficult.
Recently I've hit a roadblock due to the iTunesLibrary.framework, this framework must be linked to the main executable and yet doing so will always trigger a crash on load when running in Snow Leopard.
To workaround this problem, I want to compile a version of my app that doesn't use features and frameworks from newer versions of OSX. The problem is, how can I launch the compatibility build automatically?
I'm considering trying to make the main executable point to a shell script, but I don't really like that idea. I've also thought of the main executable being a helper that simply launches the full app and then exits. I expect this would work, but I worry about it getting approved by Apple. Finally, I'm wondering if the app bundle format itself can support this kind of setup, maybe via an advanced used of CFBundleExecutable that I'm unaware of.
Has anyone been down this road, what would you suggest?
Try weak linking the frameworks, more information about Weak Linking and Apple Frameworks here. Then also check in your code for the OS version or - (BOOL)respondsToSelector:(SEL)aSelector of any NSObject to determine what you can call and what not.
To have Snow Leopard as Base SDK you'll need an old Xcode and will have troubles submitting to Mac App Store.

confusion of how to make osx app backward compatible & how to test them

after reading the apple SDK guide
https://developer.apple.com/library/mac/#documentation/developertools/conceptual/cross_development/Overview/overview.html
I'm still confused of how to make the mac app backward compatible & how to test them properly
I have an app, I run it and tested it on Mountain Lion 10.8 without any problem, however I want to make this app backward compatible so that other users can run it on a mac 10.6 - 10.7 machine.
I have an apple developer id and I can download the old versions of 10.7 and 10.6, but the problem is, I have a 2011 macbook air which is currently running 10.8, and that's the only apple machine that I have. Can I test the 10.7 and 10.6 by using vmware or parallels?
in my project settings, I set the target deployment to 10.6 (as I want 10.6 users to run my app), but should I set my SDK to 10.8 or 10.7? if I set the SDK to 10.8 but having the target deployment set to 10.6, if I fix all the xcode warnings will it run successfully on 10.6??
from the SDK drop down, I can only set to 10.8 or 10.7, but 10.6 is missing, how do I fix that?
thanks in advance
I develop on a 10.8 box and support back to 10.5. Just a couple of months ago we dropped 10.4 PPC support, and I'm still cleaning out some of the 10.2-specific code. This may get a little rant-y, but I've been doing old versions for a long time. I have some opinions on the matter.
No matter what Apple says in their docs, if you want to support 10.6, then build with the 10.6 SDK. Do not rely on distribution target.
I have had this discussion with the Xcode engineers, and while they hold to Apple's party line that you should always build with the latest SDK, they also acknowledge that it's generally insane to do so. If you build against the 10.8 SDK and mark your deployment target at 10.6, you will get no warnings for using methods that do not exist on 10.6. The only way you will discover that you've used a nonexistent method is that it might give you strange bugs when run on 10.6. That's insane.
Remember, OS X doesn't crash when you send an unknown selector. It just aborts the current runloop. So the bugs are even harder to track down then on iOS, where it crashes the app.
Sure, you can do weak linking. Talk about dangerous.... Yes, there are a few times this is useful, but the compiler gives you no warning if you don't do it correctly. If I'm going to do weak linking like this, I go the other way, linking against the old SDK and copying the new function's prototype into my implementation. That way I have documentation of every function I think I'm going to weak-link.
Download the old SDKs and symlink them into your Xcode distribution.
Guard them jealously. Apple will try to delete them every time you upgrade Xcode. Make your own copies and stick them in /SDKs or somewhere else away from Xcode. I provide a script called fix-xcode to manage the symlinks automatically. Am I bitter at Apple for their relentless insistance on deleting my old SDKs? Yes, I am.
You can run 10.6 Server in a VM legally. You can run 10.7+ Desktop in a VM legally. These are good ways to test your code.
Or you can do what I do and have a small pile of old MacBooks each with two or three partitions on them that you reboot all the time.
Now that 10.7 comes from App Store, it's a little harder to make VMs. My strong recommendation is to snapshot your image immediately after install, and make a clean backup copy of it. You'll want to be able to clone that image from time to time when you need to get back to a "raw" machine.
Get in the habit of squirreling away SDKs as they come out. 10.8 will be old some day. You might as well make a copy now while it's easy.
Whether you support individual dot-releases or not, it can be very helpful to keep around the upgrade packages for individual dot releases. When you encounter customers running non-current releases, it's nice to be able to check whether an "unreproducible" bug in fact is easily reproducible on their specific version. Whether this is worth it or not depends heavily on your product and customers. It was a life-saver for me when 10.4.11 made major changes to WebKit during a dot release...
Invest in a small NAS or a big external USB drive (though I've had trouble with those failing when used extensively, so I prefer a RAID). You'll need the space. You want to hold onto lots of VMs and lots of SDKs and sometimes even old versions of Xcode.
Adding to Rob Napier's great in-depth answer:
To use an old SDK, put the SDK (or a symlink) to it here:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
With XCode 7.3 or later, you need you to open this file and change "MinimumSDKVersion" (otherwise XCode will refuse to use the old SDK):
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist
You can install multiple versions of Mac OS on a single machine, booting between each.
The SDK should be the latest (10.8).
See 2.
One alternative to 1 that I've considered (I am in the same boat) is to create a Snow Leopard Hackintosh using an old PC and just installing Lion and Mountain Lion on my MBP.
You need to do these settings :
1.Set the Base SDK to Current version of Mac (ex. 10.7)
2.Set the Deployment SDK to older version (ex.1.4)

Resources