The company I work for has developed a program and the last time the code was touched was 2 years ago. Now the program needs to become notarized so I was asked to take care of the program.
I ported the code to latest Xcode (10.2.1) and latest macOS. But Xcode warns me about the deprecation of a few API calls:
/Users/rowelz/Documents/Develop/Code/ThinPrint/in GIT/myProject/osx-client/src/com.myProject.bootstrap/EZPBootstrapper.m:116:51: 'SMJobCopyDictionary' is deprecated: first deprecated in macOS 10.10
NSDictionary *plist = (__bridge NSDictionary *) SMJobCopyDictionary( kSMDomainSystemLaunchd, (__bridge CFStringRef) (label));
/Users/rowelz/Documents/Develop/Code/ThinPrint/in GIT/myProject/osx-client/src/com.myProject.bootstrap/EZPBootstrapper.m:193:21: 'SMJobRemove' is deprecated: first deprecated in macOS 10.10
result = (BOOL) SMJobRemove(kSMDomainSystemLaunchd, (__bridge CFStringRef) label, self->_authRef, FALSE, &cfError);
/Users/rowelz/Documents/Develop/Code/ThinPrint/in GIT/myProject/osx-client/src/com.myProject.bootstrap/EZPAppDelegate.m:193:15: 'SMJobSubmit' is deprecated: first deprecated in macOS 10.10
submitted = SMJobSubmit(kSMDomainUserLaunchd, (__bridge CFDictionaryRef)(plist), NULL, &cfError);
/Users/rowelz/Documents/Develop/Code/ThinPrint/in GIT/ezeep/osx-client/src/com.myProject.bootstrap/EZPAppDelegate.m:214:13: 'SMJobRemove' is deprecated: first deprecated in macOS 10.10
removed = SMJobRemove(kSMDomainUserLaunchd, (__bridge CFStringRef)kEzeepServiceNameUpdaterBstrap, NULL, false, NULL);
My Supervisor in this project gave the following boundary conditions:
I would prefer not to make any changes to the code, since the warnings regarding SMJobCopyDictionary, SMJobRemove and SMJobSubmit means that there is a big change to do - the whole program has to be written anew. And this would be a big effort for a one year life-span.
My Question: I would like to write a little tool that checks for the availability of these API calls. I will then execute this tool on every beta of macOS until the final release of macOS 10.15. Of course if that tool shows a problem I will then rewrite the "now defective" program.
Would that be sufficient to detect a problem with the existence of the API? And what function can I use to detect the availability without actually calling them trying to install a launchd binary? I guess the above APIs are CoreFoundation ?
Thanks in advance for you help.
I found this here at stack overflow and it seems to work:
#include <dlfcn.h>
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
BOOL notFound = NO;
void *lib = dlopen("/System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement", RTLD_LAZY);
if(lib == NULL)
{
printf("Library not found. (/System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement).\n");
exit(1);
}
void *function1 = dlsym(lib, "SMJobCopyDictionary");
if(function1 == NULL)
{
printf("Function not found: SMJobCopyDictionary\n");
notFound = YES;
}
// .... and so on
dlclose(lib);
if(notFound)
{
exit(1);
}
printf("Ok, all functions found.\n");
}
return 0;
}
will that be sufficient to show a call to a deprecated and removed API?
This is speculation, but I feel confident in it: Apple will not remove these APIs from 10.15. Deprecating APIs is done regularly, but actually removing them breaks existing applications and is done very rarely.
It is possible (though unlikely I think) that they will remove the headers from the 10.15 SDK, in which case you will need to keep building against the 10.14 SDK (using Xcode 10).
And if the 10.15 SDK still contains the headers, the situation is the same as it is now and you won't have any problems.