Sign in Join
Wiki copytemporary

Cocoa Internals/OS Versions: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11The page cover issues of (backwards) compatibility and API deprecation across different macOS versions.
22
33## AppStore critical
44
55If you're building an application with LCL Cocoa, and having issues with uploading to AppStore, due to "Found private symbol usage", please bug report the issue if it is caused by a function or a method used in LCL Cocoa.
66
77The Cocoa Widgetset is expected to be AppStore friendly as AppStore is being made the core environment for the distribution of Apple apps.
88
99Please note that applications can still be distributed outside of the AppStore (unlike iOS).
1010
1111## macOS API Deprecation
1212
1313It's quite common for Apple to introduce methods in one version of the system and deprecate them in another version. The chances are high that a deprecated method will be removed in a later macOS version completely. Thus, if method is not verified in run-time, the application could stop working (ie the App could fail to load).
1414
1515Suggestions:
1616
1717- Use non-deprecated methods (there are plenty of APIs that are in effect since macOS 10.0 and are not planned for deprecation).
1818- If the deprecated method is in use and being replaced by some other newly introduced method - check the availability in runtime
1919 - if the latest method is available - use it first
2020 - if the latest method is not available - fallback to the original method.
2121
2222This would allow your application to execute the same code on earlier and later macOS versions.
2323
2424## Objective-C methods
2525
2626Use 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.
2727
2828``` pascal
2929 if Assigned(win) then
3030 begin
3131 if win.respondsToSelector( ObjCSelector('backingScaleFactor')) then
3232 Result := win.backingScaleFactor
3333 else if win.respondsToSelector( ObjCSelector('userSpaceScaleFactor')) then // for older macOS
3434 Result := win.userSpaceScaleFactor;
3535 end;
3636```
3737
3838## (Plain) Functions
3939
4040It'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 failure on earlier versions of macOS.
4141
4242In order to prevent that, a dynamic loading of the function needs to be used.
4343
4444``` pascal
4545uses ...
4646 dl, dynlibs;
4747...
4848 p := GetProcedureAddress(TLibHandle(RTLD_DEFAULT), 'CGDisplayCreateImage');
4949```
5050
5151The following needs to be taken into consideration:
5252
5353- the use of RTLD_DEFAULT - searches for the function name across all loaded libraries. The system library would likely 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).
5454
5555- if the symbol is not present, then the code should handle it gracefully (instead of calling to unspecified function).
5656
5757## AppKit Version
5858
5959In many cases you can call a certain functionality based on the AppKit version. **NSAppKitVersionNumber** is a shared global C-variable, thus the check of the value is performance friendly.
6060
6161Values to be compared to are constants (declared at cocoa_extra.pas):
6262
63-`NSAppKitVersionNumber10_4 = 824;`\
64-`NSAppKitVersionNumber10_5 = 949;`\
65-`NSAppKitVersionNumber10_6 = 1038;`\
66-`NSAppKitVersionNumber10_7 = 1138;`\
67-`NSAppKitVersionNumber10_8 = 1187;`\
68-`NSAppKitVersionNumber10_9 = 1265;`\
69-`NSAppKitVersionNumber10_10 = 1343;`\
70-`NSAppKitVersionNumber10_11 = 1404;`\
71-`NSAppKitVersionNumber10_12 = 1504;`\
72-`NSAppKitVersionNumber10_13 = 1561;`\
73-`NSAppKitVersionNumber10_14 = 1671; `
63+```
64+NSAppKitVersionNumber10_4 = 824;
65+NSAppKitVersionNumber10_5 = 949;
66+NSAppKitVersionNumber10_6 = 1038;
67+NSAppKitVersionNumber10_7 = 1138;
68+NSAppKitVersionNumber10_8 = 1187;
69+NSAppKitVersionNumber10_9 = 1265;
70+NSAppKitVersionNumber10_10 = 1343;
71+NSAppKitVersionNumber10_11 = 1404;
72+NSAppKitVersionNumber10_12 = 1504;
73+NSAppKitVersionNumber10_13 = 1561;
74+NSAppKitVersionNumber10_14 = 1671;
75+```
7476
7577Each version corresponds to a particular macOS release (or even sub-release in some cases). Major versions are denoted by an integer number, minor versions and release by the fractional part. To use macOS 10.13 and 10.14 as examples this is expressed as follows:
7678
7779| macOS version | Value of NSAppKitVersionNumber |
7880|---------------|--------------------------------|
7981| macOS 10.13 | 1561 |
8082| macOS 10.13.1 | 1561.1 |
8183| macOS 10.13.2 | 1561.2 |
8284| macOS 10.13.3 | 1561.3 |
8385| macOS 10.13.4 | 1561.4 |
8486| macOS 10.14.1 | 1671.1 |
8587| macOS 10.14.2 | 1671.2 |
8688| macOS 10.14.3 | 1671.3 |
8789| macOS 10.14.4 | 1671.4 |
8890| macOS 10.14.5 | 1671.5 |
8991
9092The values are taken from macOS header files provided with Xcode (eg NSapplication.h).
9193
9294## Version Specific
9395
9496### Mojave (10.14)
9597
9698#### Drawing Issues
9799
98100According to [AppKit release notes](https://developer.apple.com/documentation/appkit/appkit_release_notes_for_macos_10_14?language=objc) for 10.14 there are views are drawn Layer-backed.
99101
100-`Windows in apps linked against the macOS 10.14 SDK are displayed using Core Animation when the app is running in macOS 10.14. `\
101-`This doesn’t mean that all views are layer-backed; rather, it means that all views are either layer-backed or draw into `\
102-`a shared layer with other layers.`\
103-` `\
104-`This change should be mostly invisible to most apps, but you might notice one or more subtle changes as a result.`\
102+```
103+Windows in apps linked against the macOS 10.14 SDK are displayed using Core Animation when the app is running in macOS 10.14.
104+This doesn’t mean that all views are layer-backed; rather, it means that all views are either layer-backed or draw into
105+a shared layer with other layers.
106+
107+This change should be mostly invisible to most apps, but you might notice one or more subtle changes as a result.
105108
106-`Views that depend on drawing in the same backing store as their ancestors or lower-ordered siblings may find `\
107-`that they are instead drawing in separate layers. Views shouldn’t rely on being able to draw into the same `\
108-`backing store as their ancestors; instead, those ancestors should change as required. For example, to affect `\
109-`the background of a window, use the NSWindow properties opaque and backgroundColor`
109+Views that depend on drawing in the same backing store as their ancestors or lower-ordered siblings may find
110+that they are instead drawing in separate layers. Views shouldn’t rely on being able to draw into the same
111+backing store as their ancestors; instead, those ancestors should change as required. For example, to affect
112+the background of a window, use the NSWindow properties opaque and backgroundColor
113+```
110114
111115The change seems to impact CocoaWS a lot, causing problem with area invalidation. A number of Mojave-specific issues ([1](https://bugs.freepascal.org/view.php?id=34335)[2](https://bugs.freepascal.org/view.php?id=34358)) were reported.
112116
113117
114118**LCL solution** - make sure the code does the right thing. or force all LCL driven controsl to return wantsUpdateLayer as true.
115119
116120#### Dark Mode
117121
118122Dark mode is supported "out of the box", but only if an application was built using SDK for 10.14. For example, if an application was built with an earlier SDK (i.e. was compiled on macOS 10.13 High Sierra or earlier), then it would not pick up Dark Mode by default.
119123
120-`When an app links on the macOS 10.14 SDK, it’s automatically opted in to supporting the dark appearance, `\
121-`with its NSApp inheriting the NSAppearanceNameDarkAqua appearance from System Preferences.`
124+```
125+When an app links on the macOS 10.14 SDK, it’s automatically opted in to supporting the dark appearance,
126+with its NSApp inheriting the NSAppearanceNameDarkAqua appearance from System Preferences.
127+```
122128
123129
124130**Enable dark mode on LCL level.** Cocoa WS needs to be updated, to check if NSApplication object supports "appearance" and if it does, then enable the currently selected system theme. That allows to support "Dark Mode" even for applications built on an earlier version of the system.
125131
126132**Enable dark mode in manifest.** Add a switch into Info.plist NSRequiresAquaSystemAppearance and set the value to "false". (The key must be specified explicitly, if an app is build for an earlier SDK.)
127133
128134**Disable dark mode in manifest.** In the Info.plist, the key NSRequiresAquaSystemAppearance should be set to "true".
129135
130136#### Font Quality
131137
132138Smooth font rendering is somewhat disabled in the OS by default. It is issue in 10.14 and 10.15 (Catalina).
133139
134140- <https://ahmadawais.com/fix-macos-mojave-font-rendering-issue/>
135141- <https://discussions.apple.com/thread/250730319>
136142
137143Solution: open Terminal and enter the command:
138144
139-`defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO`
145+```
146+defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO
147+```
140148
141149then log off or restart.
142150
143151## See Also
144152
145153- [[Cocoa Internals]]
146154- [Apple Release Notes for macOS 10.14](https://developer.apple.com/documentation/appkit/appkit_release_notes_for_macos_10_14?language=objc)
147155- [Apple Release Notes for macOS 10.13](https://developer.apple.com/library/archive/releasenotes/AppKit/RN-AppKit/index.html)
148156- [Apple Release Notes for macOS 10.12 and earlier](https://developer.apple.com/library/archive/releasenotes/AppKit/RN-AppKitOlderNotes/)
149157
150158- [Issue \#33672](https://bugs.freepascal.org/view.php?id=33672) - the bug covers some problems linking the app
151159
152160---
153161*From the Free Pascal wiki, page "Cocoa Internals/OS Versions", as it stood on 2020-09-19 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history