Difference between revisions of "Cocoa Internals/OS Versions"

From Lazarus wiki
Jump to navigationJump to search
(starting the page)
 
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
 +
==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.
 +
<source lang="delphi>
 +
  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;
 +
</source>
 +
 
==(Plain) Functions==
 
==(Plain) Functions==
 
It's possible that a new feature requires a function that has been introduced in a later version of macOS.
 
It's possible that a new feature requires a function that has been introduced in a later version of macOS.

Revision as of 05:59, 7 July 2018

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

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)