Introduction
This online notebook is intended to serve as an auxiliary documentation resource. It will be used to collate resources and documentation on a variety of topics in different languages, libraries, and frameworks. The primary objective of this resource is to bring together useful information that is obscure, old, or otherwise difficult to obtain. Such information may still be useful, though it may be fragmented and and spread over the vastness of the internet on multiple sites, such as forums and documentation archives. Where possible, usable examples of each topic will be included.
Swift
Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, iPadOS, macOS, watchOS, tvOS, and Linux [1].
Useful pages
SO: Object collision in SpriteKit
SO: Storyboard and SwiftUI in the same project
SO: Combining ARKit and SwiftUI without Storyboard
SO: Recreating share sheet modal in iOS 13
Apple: Combining SwiftUI and UIKit
Other: Using SwiftUI with ARKit and SceneKit
Other: iPhone X printable templates
Other: MediaPlayer framework secrets
Other: Extensive guide to WKWebView
Other: Animation with CABasicAnimation
Other: Adopting Dark Mode in iOS apps
Other: Supporting Dark Mode in iOS
Other: Advanced Property Wrappers
Other: From iOS to macOS development
Foundation
The Foundation framework provides a base layer of functionality for apps and frameworks, including data storage and persistence, text processing, date and time calculations, sorting and filtering, and networking [1].
Bundle
paths
UIKit
The UIKit framework provides the required infrastructure for your iOS or tvOS apps. It provides the window and view architecture for implementing your interface, the event handling infrastructure for delivering Multi-Touch and other types of input to your app, and the main run loop needed to manage interactions among the user, the system, and your app. Other features offered by the framework include animation support, document support, drawing and printing support, information about the current device, text management and display, search support, accessibility support, app extension support, and resource management [1].
UIPageViewController
The UIPageViewController class is a container view for presenting multiple view controllers as a series of pages that can be cycled through.
import UIKit
class PageViewController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Used when adding UIPageViewControllerDataSource
// dataSource = self
}
// Class definition
}
orderedViewControllers
The orderedViewControllers: [UIViewController] variable contains a generated list of the view controllers to be used in a UIPageViewController. The view controllers are displayed in the order in which they appear in the list returned by the orderedViewControllers variable.
private(set) var orderedViewControllers: [UIViewController] = {
func newViewController(_ name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "page")
}
let viewOrder = ["page1", "page2", "page3"]
let controllers = viewOrder.map { newViewController($0) }
return controllers
}()
The above example uses a scoped function newViewController(_:) -> UIViewController to instantiate a new view controller using the storyboard identifier page. viewOrder.map { newViewController($0) } assigns a new list of view controllers to the controllers variable using the strings in viewOrder. Notice, however, that these strings are never passed to the newly instantiated view controllers. The below example shows how to send the data to a view controller, though this is not a necessary requirement of the UIPageViewController.
// Assume pages use a view controller similar to this
class ViewController: UIViewController {
var title: String = "default value"
// rest of view controller declaration
}
class PageViewController: UIPageViewController {
private(set) var orderedViewControllers: [UIViewController] = {
func newViewController(_ name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "page")
}
let viewOrder = ["page1", "page2", "page3"]
let controllers = viewOrder.map { newViewController($0) as! ViewController }
for i in 0 ..< controllers.count {
controllers[i].page = viewOrder[i]
}
return controllers
}()
// rest of page view controller declaration
}
setViewControllers
The setViewControllers(_:, direction:, animated:, completion:) function is used to set the view controller to present to the user.
This can be used to set the initial view controller to present when the controller first loads.
class PageViewController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let firstViewController = orderedViewControllers.first {
setViewControllers(
[firstViewController],
direction: .forward,
animated: true,
completion: nil
)
}
}
}
Customising the page dots
Customisation of the page controller dots can be achieved by modifying UIPageControl.appearance().
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.red.withAlphaComponent(0.6)
appearance.currentPageIndicatorTintColor = .red
appearance.backgroundColor = .yellow
UIPageViewControllerDataSource
The UIPageViewControllerDataSource protocol is used to determine which view controller to present to the user. It can be implemented using:
class PageViewController: UIPageViewController, UIPageViewControllerDataSource {
// Class definition
// Extension function implementations
}
or separated for clarity using extensions:
class PageViewController: UIPageViewController {
// Class definition
}
extension PageViewController: UIPageViewControllerDataSource {
// Extension function implementations
}
viewControllerBefore
The pageViewController(pageViewController:, viewControllerBeforeViewController:) function is used to specify the view controller to present when moving backwards through the pages.
func pageViewController(
pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController
) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
To loop back to the last view controller when moving backwards from the first view controller in the sequence, use the modified implementation below.
func pageViewController(
pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController
) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
// User is on the first view controller and swiped left to loop to the last view controller.
guard previousIndex >= 0 else {
return orderedViewControllers.last
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
viewControllerAfter
The pageViewController(pageViewController:, viewControllerAfterViewController:) function is used to specify the view controller to present when moving forwards through the pages.
func pageViewController(
pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController
) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to the first view controller.
guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
To loop back to the first view controller when moving forwards from the last view controller in the sequence, use the modified implementation below.
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController
) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to the first view controller.
guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
presentationCount
To show page dots in a UIPageViewController the presentationCount(for:) -> Int function informs the controller data source as to how many pages there are, and how many dots should be shown.
extension PageViewController: UIPageViewControllerDataSource {
func presentationCount(for pvc: UIPageViewController) -> Int {
return orderedViewControllers.count
}
}
presentationIndex
To show page dots in a UIPageViewController the presentationIndex(for:) -> Int function informs the controller data source as to which page is currently presented.
extension PageViewController: UIPageViewControllerDataSource {
func presentationIndex(for pvc: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first, let firstViewControllerIndex = orderedViewControllers.firstIndex(of: firstViewController) else {
return 0
}
return firstViewControllerIndex
}
}
UITableView
didSelectRowAt
UITableViewDataSource
numberOfRowsInSelection
cellForRowAt
AppKit
AppKit contains all the objects you need to implement the user interface for a macOS app—windows, panels, buttons, menus, scrollers, and text fields—and it handles all the details for you as it efficiently draws on the screen, communicates with hardware devices and screen buffers, clears areas of the screen before drawing, and clips views.
The framework also provides APIs you use to make your app accessible to users with disabilities (see Accessibility); to learn more about localizing your app for different languages, countries, or cultural regions, see Internationalization and Localization Guide [1].
NSView
C/C++
Useful Pages
SO: Accessing files in macOS bundle
SO: Get home directory in Linux
Kotlin
Kotlin is a modern language developed by JetBrains.
Useful Pages
Unreal Engine 4
Useful Pages
Other: Create nice and feasible volumetric cloud in Unreal Engine 4
Web Technologies
HTML
CSS
JavaScript
Windows 32 API
CreateProcessA
CreateProcess used to be the fundamental way to create a new process, used internally by higher level functions such as ShellExecute.
With the advent of User Access Control security, UAC, one needs to use ShellExecute (or family member) to run a process with elevated access.
Where the process to be started is a console subsystem process, it can often be more convenient to use the C++ standard library's system function, which uses the cmd.exe command interpreter to run a specified command, waits for that to end, and returns the process exit code.
As stated in MSDN, CreateProcessA's 2nd argument : lpApplicationName is playing the role of the command line to be executed. Unless lpApplicationName points to an exe in a directory, the system will look for it in the following order:
- The directory from which the application loaded.
- The current directory for the parent process.
- The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory
- The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
Therefore, unless the second argument of CreateProcessA is in the form {directory}/{executable_name}.{ext}, you'll have to either :
- Place executable_name in the same directory from which the application loaded
- Place executable_name in the same directory of the parent process
- Place executable_name in the Windows System32 directory : C:\Windows\System32
- Place executable_name in the Windows directory : C:\Windows
- Include the directory where executable_name is in the PATH
The second parameter in CreateProcess should be a writable buffer. If your executable path does not include command line arguments then put the executable path in the first parameter, and leave the second parameter NULL
GetExitCodeProcess
GetExitCodeProcess is used to check the exit code of a process. By convention in Windows, Unix and in C++, exit code 0 (e.g. as returned from main) denotes success. In C++ this value is available as the macro symbol EXIT_SUCCESS from <stdlib.h>. On other systems EXIT_SUCCESS needs not be 0, but in C++ exit code 0 always denotes success, possibly in addition to the value of EXIT_SUCCESS.
The Windows and Unix-land convention is that any other exit code denotes failure, but the only portable failure value in C++ is the one denoted by EXIT_FAILURE. In Windows this is conventionally the value 1. Unfortunately that conflicts with the value of a Windows error code, about “incorrect function” (as reported by errlook.exe). For this reason one may choose to use Windows' own general failure value E_FAIL to indicate a general failure, instead of using the portable but imperfect EXIT_FAILURE.
Two relevant differences between Windows and Unix-land:
- In Windows a non-zero exit code is often an error code that tells you something about the cause of failure. It can be passed to a tool such as Microsoft's errlook to get a textual description, the same as via the API function FormatMessage. In Unix-land process exit codes used as failure cause indications are much less common.
- In Unix-land tools can generally be relied on to indicate failure or success via the exit code. This is not so in Windows. Even many of the built-in and standard commands fail to do so.
Especially the latter point is important for use of GetExitCodeProcess. You need to know that the process you're checking, is one that produces a meaningful exit-code.
Also note well that the code STILL_ACTIVE is defined as a low number, as I recall around 270 or thereabouts, and can be produced by a process, so that it is not a reliable indicator of whether a process is still active or not. I.e., don't use GetExitCodeProcess to poll for a process to finish. Depending on the process & circumstances, such code might hang.
WaitForSingleObject
Instead of waiting for a process to end by polling its exit code with GetExitCodeProcess, which might hang as explained above, use e.g. WaitForSingleObject, or a family member.
WaitForSingleObject(pi.hProcess, INFINITE)
val exitCode: DWORDVar = alloc()
val result = GetExitCodeProcess(pi.hProcess, exitCode.ptr).convert<Int>()
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
return if (result == 0) { // If result is 0, GetExitCodeProcess failed
-1
} else {
exitCode.value.convert()
}
POSIX
POSIX is a set of standards for providing compatibility between operating systems.
Useful Pages
system
The int system(char* command) function executes the specified shell command in a new process and waits for the process to complete. The return value is the exit code of the executed command. As such, it cannot be assumed that a value of 0 means success as this is dependent on the command. system() is implemented using fork() and execl().
int system("ls");
If command is null then a return value of 0 indicates a shell is available on the system. A non-zero value indicates there is no available shell.
If a child process cannot be created, system() returns -1 and the global errno value is set.
fork
The int fork() function creates a new process as a duplicate of the current process. The return value indicates the status of the child process creation.
val pid: Int = fork()
when {
pid == 0 -> { // If result is 0, fork succeeded and we are the child
// Code run only by child
}
pid < 0 -> { // If result < 0, fork failed and we are the parent
// Code run only by parent
}
else -> { // If result > 0, fork succeeded and we are the parent
// Code run only by parent
}
}
// Code run by:
// - Parent
// - Child if did not return or exit already
exec
The int exec() family of functions replace the current process with a new one.
Variants
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
| Function | Description |
|---|---|
execl() | execute file at specified path with arguments given as a varargs list |
execlp() | execute a file on the PATH with arguments given as a varargs list |
execle() | execute file at specified path with arguments given as a varargs list and environment parameters given as a vector list |
execv() | execute file at specified path with arguments given as a vector list |
execvp() | execute file on the PATH with arguments given as a vector list |
execvpe() | execute file on the PATH with arguments given as a vector list and environment parameters given as a vector list |
Failure
If an exec variant fails to execute successfully, the currently executing process will not be replaced, and the global errno constant will be updated with an error value that indicates the cause of the problem. The full list of errors can be viewed here.
execl
The int execl(const char *path, const char *arg, ...) function is used to replace the current process by executing a file at the specified path with arguments given as a varargs list.
char* command = "/bin/ls"; // The file to execute
char* p1 = "ls"; // The first argument must be the file to execute
char* p2 = "."; // Arguments to the command
char* p3 = "-al"; // Arguments to the command
char* p4 = NULL; // The last argument must be the null terminating character
int result = execl(command, p1, p2, p3, p4); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
execlp
The int execlp(const char *file, const char *arg, ...) function is used to replace the current process by executing a file at the specified path with arguments given as a varargs list.
char* command = "ls"; // The file to execute
char* p1 = "ls"; // The first argument must be the file to execute
char* p2 = "."; // Arguments to the command
char* p3 = "-al"; // Arguments to the command
char* p4 = NULL; // The last argument must be the null terminating character
int result = execlp(command, p1, p2, p3, p4); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
execle
The int execle(const char *path, const char *arg, ...) function is used to replace the current process by executing a file at the specified path with arguments given as a varargs list and environment parameters given as a vector list.
char* command = "/bin/ls"; // The file to execute
char* p1 = "ls"; // The first argument must be the file to execute
char* p2 = "."; // Arguments to the command
char* p3 = "-al"; // Arguments to the command
char* p4 = NULL; // The last argument must be the null terminating character
char* env[] = {}; // The list of environmental parameters
int result = execle(command, p1, p2, p3, p4, environ); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
execv
The int execv(const char *file, char *const argv[]) function is used to replace the current process by executing a file at the specified path with arguments given as a vector list.
char* command = "/bin/ls"; // The file to execute
char* argv[4]; // The list of arguments to pass (size >= 2)
argv[0] = "ls"; // The first argument must be the file to execute
argv[1] = "."; // Arguments to the command
argv[2] = "-al"; // Arguments to the command
argv[3] = NULL; // The last argument must be the null terminating character
int result = execv(command, argv); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
execvp
The int execvp(const char *path, char *const argv[]) function is used to replace the current process by executing a file on the PATH with arguments given as a vector list.
char* command = "ls"; // The file on the path to execute
char* argv[4]; // The list of arguments to pass (size >= 2)
argv[0] = "ls"; // The first argument must be the file to execute
argv[1] = "."; // Arguments to the command
argv[2] = "-al"; // Arguments to the command
argv[3] = NULL; // The last argument must be the null terminating character
int result = execvp(command, argv); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
execvpe
The int execvpe(const char *path, char *const argv[]) function is used to replace the current process by executing a file on the PATH with arguments given as a vector list and environment parameters given as a vector list.
char* command = "ls"; // The file on the path to execute
char* argv[4]; // The list of arguments to pass (size >= 2)
argv[0] = "ls"; // The first argument must be the file to execute
argv[1] = "."; // Arguments to the command
argv[2] = "-al"; // Arguments to the command
argv[3] = NULL; // The last argument must be the null terminating character
char* env[] = {}; // The list of environmental parameters
int result = execvp(command, argv, environ); // Replace the current process
// If result is -1, exec failed
// Code beyond this point will not execute unless exec failed
// If exec failed, errno can be checked to determine the cause
errno
The global errno constant is set when certain function calls fail. Below is a list of errno values with associated descriptions.
| Enum Value | Value | Description |
|---|---|---|
| EPERM | 1 | Operation not permitted |
| ENOENT | 2 | No such file or directory |
| ESRCH | 3 | No such process |
| EINTR | 4 | Interrupted system call |
| EIO | 5 | I/O error |
| ENXIO | 6 | No such device or address |
| E2BIG | 7 | Arg list too long |
| ENOEXEC | 8 | Exec format error |
| EBADF | 9 | Bad file number |
| ECHILD | 10 | No child processes |
| EAGAIN | 11 | Try again |
| ENOMEM | 12 | Out of memory |
| EACCES | 13 | Permission denied |
| EFAULT | 14 | Bad address |
| ENOTBLK | 15 | Block device required |
| EBUSY | 16 | Device or resource busy |
| EEXIST | 17 | File exists |
| EXDEV | 18 | Cross-device link |
| ENODEV | 19 | No such device |
| ENOTDIR | 20 | Not a directory |
| EISDIR | 21 | Is a directory |
| EINVAL | 22 | Invalid argument |
| ENFILE | 23 | File table overflow |
| EMFILE | 24 | Too many open files |
| ENOTTY | 25 | Not a typewriter |
| ETXTBSY | 26 | Text file busy |
| EFBIG | 27 | File too large |
| ENOSPC | 28 | No space left on device |
| ESPIPE | 29 | Illegal seek |
| EROFS | 30 | Read-only file system |
| EMLINK | 31 | Too many links |
| EPIPE | 32 | Broken pipe |
| EDOM | 33 | Math argument out of domain of func |
| ERANGE | 34 | Math result not representable |
| EDEADLK | 35 | Resource deadlock would occur |
| ENAMETOOLONG | 36 | File name too long |
| ENOLCK | 37 | No record locks available |
| ENOSYS | 38 | Function not implemented |
| ENOTEMPTY | 39 | Directory not empty |
| ELOOP | 40 | Too many symbolic links encountered |
| ENOMSG | 42 | No message of desired type |
| EIDRM | 43 | Identifier removed |
| ECHRNG | 44 | Channel number out of range |
| EL2NSYNC | 45 | Level 2 not synchronized |
| EL3HLT | 46 | Level 3 halted |
| EL3RST | 47 | Level 3 reset |
| ELNRNG | 48 | Link number out of range |
| EUNATCH | 49 | Protocol driver not attached |
| ENOCSI | 50 | No CSI structure available |
| EL2HLT | 51 | Level 2 halted |
| EBADE | 52 | Invalid exchange |
| EBADR | 53 | Invalid request descriptor |
| EXFULL | 54 | Exchange full |
| ENOANO | 55 | No anode |
| EBADRQC | 56 | Invalid request code |
| EBADSLT | 57 | Invalid slot |
| EBFONT | 59 | Bad font file format |
| ENOSTR | 60 | Device not a stream |
| ENODATA | 61 | No data available |
| ETIME | 62 | Timer expired |
| ENOSR | 63 | Out of streams resources |
| ENONET | 64 | Machine is not on the network |
| ENOPKG | 65 | Package not installed |
| EREMOTE | 66 | Object is remote |
| ENOLINK | 67 | Link has been severed |
| EADV | 68 | Advertise error |
| ESRMNT | 69 | Srmount error |
| ECOMM | 70 | Communication error on send |
| EPROTO | 71 | Protocol error |
| EMULTIHOP | 72 | Multihop attempted |
| EDOTDOT | 73 | RFS specific error |
| EBADMSG | 74 | Not a data message |
| EOVERFLOW | 75 | Value too large for defined data type |
| ENOTUNIQ | 76 | Name not unique on network |
| EBADFD | 77 | File descriptor in bad state |
| EREMCHG | 78 | Remote address changed |
| ELIBACC | 79 | Can not access a needed shared library |
| ELIBBAD | 80 | Accessing a corrupted shared library |
| ELIBSCN | 81 | .lib section in a.out corrupted |
| ELIBMAX | 82 | Attempting to link in too many shared libraries |
| ELIBEXEC | 83 | Cannot exec a shared library directly |
| EILSEQ | 84 | Illegal byte sequence |
| ERESTART | 85 | Interrupted system call should be restarted |
| ESTRPIPE | 86 | Streams pipe error |
| EUSERS | 87 | Too many users |
| ENOTSOCK | 88 | Socket operation on non-socket |
| EDESTADDRREQ | 89 | Destination address required |
| EMSGSIZE | 90 | Message too long |
| EPROTOTYPE | 91 | Protocol wrong type for socket |
| ENOPROTOOPT | 92 | Protocol not available |
| EPROTONOSUPPORT | 93 | Protocol not supported |
| ESOCKTNOSUPPORT | 94 | Socket type not supported |
| EOPNOTSUPP | 95 | Operation not supported on transport endpoint |
| ENOTSUP | 95 | Operation not supported (POSIX.1-2001). |
| EPFNOSUPPORT | 96 | Protocol family not supported |
| EAFNOSUPPORT | 97 | Address family not supported by protocol |
| EADDRINUSE | 98 | Address already in use |
| EADDRNOTAVAIL | 99 | Cannot assign requested address |
| ENETDOWN | 100 | Network is down |
| ENETUNREACH | 101 | Network is unreachable |
| ENETRESET | 102 | Network dropped connection because of reset |
| ECONNABORTED | 103 | Software caused connection abort |
| ECONNRESET | 104 | Connection reset by peer |
| ENOBUFS | 105 | No buffer space available |
| EISCONN | 106 | Transport endpoint is already connected |
| ENOTCONN | 107 | Transport endpoint is not connected |
| ESHUTDOWN | 108 | Cannot send after transport endpoint shutdown |
| ETOOMANYREFS | 109 | Too many references: cannot splice |
| ETIMEDOUT | 110 | Connection timed out |
| ECONNREFUSED | 111 | Connection refused |
| EHOSTDOWN | 112 | Host is down |
| EHOSTUNREACH | 113 | No route to host |
| EALREADY | 114 | Operation already in progress |
| EINPROGRESS | 115 | Operation now in progress |
| ESTALE | 116 | Stale NFS file handle |
| EUCLEAN | 117 | Structure needs cleaning |
| ENOTNAM | 118 | Not a XENIX named type file |
| ENAVAIL | 119 | No XENIX semaphores available |
| EISNAM | 120 | Is a named type file |
| EREMOTEIO | 121 | Remote I/O error |
| EDQUOT | 122 | Quota exceeded |
| ENOMEDIUM | 123 | No medium found |
| EMEDIUMTYPE | 124 | Wrong medium type |
| ECANCELED | 125 | Operation canceled (POSIX.1-2001). |
| ENOKEY | 126 | Required key not available. |
| EKEYEXPIRED | 127 | Key has expired. |
| EKEYREVOKED | 128 | Key has been revoked. |
| EKEYREJECTED | 129 | Key was rejected by service. |
| EOWNERDEAD | 130 | Owner died (POSIX.1-2008). |
| ENOTRECOVERABLE | 131 | State not recoverable (POSIX.1-2008). |
| ERFKILL | 132 | Operation not possible due to RF-kill. |
| EHWPOISON | 133 | Memory page has hardware error. |
| EWOULDBLOCK | EAGAIN | Operation would block |
| EDEADLOCK | EDEADLK |
Tools
Xcode
Useful Pages
SO: Building a macOS bundle manually
SO: Adding music to Xcode simulators
Other: Submitting to the app store, Part 2