Difference between revisions of "Cocoa Internals/OS Versions"

From Lazarus wiki
Jump to navigationJump to search
Line 1: Line 1:
 
The page coverages on issues of (backwards) compatibility and API deprecation across different macOS version
 
The page coverages on issues of (backwards) compatibility and API deprecation across different macOS version
 +
==MacOS deprecation==
 +
It's quite common for Apple to introduce methods in one version of the system and deprecate in another version.
 +
Chances are high, that a certain method would be removed in later version completely (Thus, if method is not verified in run-time, the application could stop working, i.e. failing to load the app).
 +
 +
Suggestions:
 +
* use non-deprecated methods (there are plenty of APIs that are in effect since macOS 10.0 and are not planned for deprecation)
 +
* if deprecated method is in use and being replaced by some other newly introduced method - check the availability in runtime
 +
:if the latest method is available - use it first
 +
:if the latest method is not available - fallback to the original method
 +
That would allow to execute the same code on earlier and later macOS versions.
 +
 
==Objective-C methods==
 
==Objective-C methods==
 
use ObjCSelector with respondsToSelector() check, prior to the explicit call.
 
use ObjCSelector with respondsToSelector() check, prior to the explicit call.

Revision as of 06:07, 7 July 2018

The page coverages on issues of (backwards) compatibility and API deprecation across different macOS version

MacOS deprecation

It's quite common for Apple to introduce methods in one version of the system and deprecate in another version. Chances are high, that a certain method would be removed in later version completely (Thus, if method is not verified in run-time, the application could stop working, i.e. failing to load the app).

Suggestions:

  • use non-deprecated methods (there are plenty of APIs that are in effect since macOS 10.0 and are not planned for deprecation)
  • if deprecated method is in use and being replaced by some other newly introduced method - check the availability in runtime
if the latest method is available - use it first
if the latest method is not available - fallback to the original method

That would allow to execute the same code on earlier and later macOS versions.

Objective-C methods

use ObjCSelector with respondsToSelector() check, prior to the explicit call. If an object gets a selector it's unable to handle, ObjectiveC would throw an exception and the application would crash.

  if Assigned(win) then
  begin
    if win.respondsToSelector( ObjCSelector('backingScaleFactor')) then
      Result := win.backingScaleFactor
    else if win.respondsToSelector( ObjCSelector('userSpaceScaleFactor')) then // for older OSX
      Result := win.userSpaceScaleFactor;
  end;

(Plain) Functions

It's possible that a new feature requires a function that has been introduced in a later version of macOS. In this case a straight use of the function would cause a load-time fail on earlier versions of OSX.

In order to prevent that, a dynamic loading of the function needs to be used.

uses ... 
  dl, dynlibs;
...
  p := GetProcedureAddress(TLibHandle(RTLD_DEFAULT), 'CGDisplayCreateImage');

The following needs to be taken into consideration:

  • the use of RTLD_DEFAULT - searches for the function name across all loaded libraries. The system library would like be loaded by that time. However, if not the actual library name needs to be loaded. (unlike Linux, macOS doesn't require the full library path to be specified)
  • if the symbol is not present, then the code should handle it gracefully (instead of calling to unspecified function)