Is there a way to tell (at build-time) if my 10.9 app will run on 10.8? - objective-c

I have an app I've been developing under 10.9 using the 10.9 SDK, and I want to distribute it to my friends who are running 10.8. I know I can't guarantee it'll work there without finding an OS X 10.8 system (maybe in a virtual machine) and running it there, but is there any way I can check that I'm not using any 10.9-only APIs? Or even get a list of 10.9-only APIs that my application uses?
My understanding is that:
"Deployment Target" doesn't do this -- this just sets the LC_VERSION_MIN_MACOSX, so that if you tried to run it on an earlier version of OS X, it would refuse to even start.
"Base SDK" doesn't do this -- this is the version of the API it's compiled with. Some features added in newer versions of the SDK are available even on older versions of OS X at runtime (e.g., NSArray -firstObject).
Xcode's static analysis is pretty good at identifying the source of symbols (classes / methods) that I use, so it seems like this should be fairly easy to do, but I don't know how to do it.

"Base SDK" does what you want in a legalistic sense. Yes you may get some false negatives - for methods like firstObject - but better those than false positives. You can check any reported non-existant APIs and put in code to check dynamically (respondsToSelector:) and code defensively for those cases, or ignore them if you must and are really sure they are available.

Related

NIDAQmx yosemite compatibility

I've installed osx 10.10 ( Yosemite ) and since then the device (NI-USB 6210) is not working anymore.
The problem is obviously driver related. I called National Instruments and they confirmed the issue, and they also told me that the problem will be probably fixed in the next release of the nidaqmx, that will happen not so soon.
So their suggestion is to downgrade to Mavericks, which kinda suck.
They also told me to check the compatibility table
http://www.ni.com/labview/os-support/i/
in order to know when if will be supported, until then I have to struggle with downgrade or find a workaround which would be the best thing. anybody found a solution to this problem lately?
Depending on your device and how you program it, you should be able to get it working on Yosemite using NI-DAQmx Base 14.0 [1].
NI-DAQmx Base 14.0 does not claim Yosemite support, but after inspecting the installer and running a few tests, here is what I have determined:
The installer, kernel extensions, frameworks, and applications are signed by National Instruments, which means Gatekeeper won't interrupt you with "are you sure you want to do this?" questions.
Both 32-bit and 64-bit LabVIEW APIs are provided.
Both 32-bit and 64-bit C APIs are provided, but a C or Cocoa application emits a warning on exit. It appears one of the components in the driver attempts to access UI elements from a background thread. My suspicion is that the LabVIEW Run-Time Engine, in which the DAQmx Base C API runs, is doing that.
Links
[1] NI-DAQmx Base 14.0 for Mac
http://www.ni.com/download/ni-daqmx-base-14.0/5060/en/
I had this same problem, and spent an evening figuring out the problem.
Apparently, the NiDaq framework tries to send a message setHandler:withData: to the appdelegate. On yosemite, this handler no longer exists, causing the exception.
If you haven't implemented such message in your own app delegate, things go bad.
But you can simply implement a dummy handler by adding this to your application delegate class :
- (id)setHandler:(id)a withData:(id) b
{
return nil;
}
this way, the framework doesn't crash !!! I still have to test if the measured data is correct, but at least i'm running again !

Discover calls to methods not available in earlier iOS versions

I am building my app using iOS 5.0 as base SDK and iOS 3.0 as deployment target.
I know I need to check for existence of methods and classes when I work with features that are not available in the earlier iOS versions, but lately I've lost a few hours on a problem just to discover I was calling a method not available in some iOS versions. I simply did not notice it was a new method and did no check before to call it. The app of course compiled with 0 errors and 0 warnings.
This is a big problem because if I forgot some other check somewhere in the app, I will not know it until I or, worst, some user will activate that specific part of code.
Maybe I am missing something, is there some compiler option I can set to detect the calls I make to methods not available in the iOS deployment target? How do you deal with such a problem?
This link might point you in the right direction. Supporting mutiple ios Versions in your apps. It explains how to deal with taking advantage of the newer ios features while maintaining backwards compatibility. Hope that helps.
The only way to check for compatibility with a prior version of iOS, currently, it to test the app on an old non-updated device running that version of the OS.
If you can't find a device that old, even just to borrow for short time, then there may not be a good buiness reason to set the Deployment target that low.

making app compatible with previous iOS versions

I just released my app but I am only able to make it compatible from 4.3 and up.
When I try to go any lower than 4.3 (xcode), it says I need to add code to make this work.
Does anyone know how to do this or has any suggestions? I would like my app to be compatible with 3.0 and onwards.
Thank you very much
You have to reach the least common code, what I mean by this is that you must find all the methods that are all incompatible within all of these versions of the OS. After that you will have to find each and every of it's functional equivalents. Then you can use conditional statements to check for every version and see what fits better or you can use the respondsToSelector method inherited from the NSObject class. In the end you have to test it on each device you are targeting :P
You can run this checkup list that I have always liked.
Edit:
I think I misunderstood your question though it has already been mentioned, be sure to check your deployment target in your build settings.
Checklist:
In your project's build settings…
Did you set the "iOS Deployment Target" to iOS 3?
Did you include the armv6 architecture in both, the built and the valid architectures?
In general:
Do you link to any framework that is not supported on iOS 3?
Do you use any methods, classes or other features that have been added later?

Is there a tool to determine what minimum OS my deployment target should be?

I've read several of the posts on stack overflow already about this topic, but none of them seem to have real answers.
Here is my question:
The Apple documentation clearly shows what OS is required for each method, so why isn't there a tool to let me know if I'm using any methods that require an OS later than my deployment target?
If there is such a tool I'd like to know.
I'm currently building an App that I think will run fine on iOS 3.2, but I want to make sure. It seems to work fine in the 3.2 iPad simulator, but like I said, I want to make sure.
I don't want to go through each method one by one, and I don't want to set the deployment target to anything >= 4.0 because of how many people with 3Gs phones haven't upgraded to 4.0.
BTW:
I'm running XCode 4.0.2
Generally one sets this to the oldest firmware version one has tested on, if you aren't entirely sure about what APIs you're using.
Protip: Get an old device if you want to test on old versions. Set your deployment target ALWAYS to the oldest firmware version you've tested on.
It looks like there is no tool that does exactly what I'm asking. If anyone else discovers something, please let me know. It seems like it would be fairly easy for Apple to implement something like this.

Updating sqlite3 API

I want to update/upgrade the standard Leopard install of Sqlite3 to >3.5 to use the new sqlite_xxx_v2 methods from a Cocoa project.
I can't seem to find any information on how to do this. Does anyone have any tips or a site that outlines the update procedure.
Also is 3.5+ supported on the iPhone. I understand it's embedded so shouldn't be an issue...
What you want to do is grab the amalgamation sources from http://sqlite.org/download.html . Then just compile that into / add it to your project. You don't want to replace the system sqlite- that'll have unintended consequences in other applications. Plus, I'm pretty sure the system sqlite isn't a stock sqlite... Apple has probably made their own modifications to it that core data relies on.
You can read up on the amalgamation stuff here: http://sqlite.org/amalgamation.html , but in short: '''The amalgamation is a single C code file, named "sqlite3.c", that contains all C code for the core SQLite library and the FTS3 and RTREE extensions'''
I'd also suggest not using the sqlite calls directly, they weren't designed to be used that way (says the author of sqlite). Instead, there are a number of cocoa wrappers out there, including fmdb: http://code.google.com/p/flycode/source/browse/trunk/fmdb/ (which I wrote) :)
-gus
You don't really want to upgrade the system version of SQLite on Mac OS X. The reason is that all Mac OS X software is qualified against the versions of the packages that it includes, as built by Apple's build process. Installing a different version of a package, or even building the same version yourself but doing so slightly differently than Apple does, may result in a system that behaves unexpectedly.
Finally, if you embed a newer version of SQLite — or any Open Source library or framework included with Mac OS X — into your own application, you should be sure to integrate the Darwin changes for it from Apple's public source site. That way you can be sure you'll get as close to the same behavior as possible from the library you've built yourself as the version Apple ships, which is especially important when it comes to functionality like file locking in databases.
I don't believe i've updated my version, but it's currently at 3.4.2, and i'm able to use the new methods with the current version.
And i'm running 10.5.5 with the latest (public) iPhone SDK.
It would likely be easier to just drop the library into your project and link it in from there.