XCode version 13.2.1
I enabled os_log messages using the following code:
let myLog = OSLog(subsystem: "testing", category: "exploring")
override func viewDidLoad() {
os_log("LOGGING TEST BLAH BLAH", log: myLog)
print("Starting ViewDidLoad")
super.viewDidLoad()
os_log("LOGGING TEST BLAH BLAH", log: myLog)'
...
However, I do not see anything on the XCode console - just the print ("Starting ViewDidLoad").
Is there a setting in XCode to echo messages from the logger that needs to be turned on?
I understand that Logger is the preferred method now instead of os_log, but both should echo the log messages on XCode debug console from what I can tell..
Thanks!
Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.
Post
Replies
Boosts
Views
Activity
I am trying to write a safari web extension that redirects users to Y URL if they type X URL without ever loading the X URL.
The piece of code that I have attached below works smoothly on chrome, but not on safari.
background.js
function onBeforeNavigate(event) {
const redirectURL = "https://google.com/"
chrome.tabs.update(event.tabId, { url: redirectURL })
}
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate,{
url: [
{urlMatches: "https://girlcodeit.com/*"},
{urlMatches: "http://girlcodeit.com/*"}
]
})
manifest.json
"manifest_version": 2,
"name": "",
"description": "",
"version": "1.0",
"background": {
"scripts": [
"background.js"
]
},
"permissions": [
"webNavigation",
"tabs"
]
}
I have tried writing browser.tabs.update and just tabs.update in place of chrome.tabs.update in safari version, no change.
I want to achieve the redirection anyhow through a safari web extension, please suggest changes in this one or share any other approaches.
webRequestBlocking is not supported by Safari, so that doesn't work either.
I have given location permission for the app i'm developing. Now i need to reset location permission and want to see the permission pop-up.
I have tried tccutil reset and /var/db/locationd/clients.plist is not accessible. Both are failing even with sudo.
Please suggest any methods.
Hi everyone,
We are integrating Apple Pay on the Web, and we're trying to get the automatic renewal of the domain verification working according to the documentation: https://developer.apple.com/documentation/apple_pay_on_the_web/maintaining_your_environment
Initially the domain verification is successful, but then the automatic renewal does not work. We keep getting the emails with the subject "Your domain will expire soon.", but they only say "We were unable to automatically to reverify your domain." without any further details.
We confirmed that the site's SSL certificate has already been renewed by the time Apple attempted the renewal of verification, the certs are renewed 30 days before their expiry (using Let's Encrypt). So according to the docs, at least the renewal attempts 15, and then 7 days before the expiry should be successful.
One example domain is this one: https://www.kayak.com/.well-known/apple-developer-merchantid-domain-association.txt, but we have the same issue for all our other domains as well.
Does anyone have suggestions how to troubleshoot this further?
(I tried creating a support ticket, but they basically replied that they're non-technical, and just linked me to the documentation.
I've seen others complaining about this too, but couldn't find a conclusive solution, so I thought I'd signal boost and create a fresh topic to see if there are any more recent findings about this problem.)
Thanks!
Regards,
Mark
I'm trying to use task_for_pid in a project but I keep getting error code 5 signaling some kind of signing error. Even with this script I cant seem to get it to work.
#include <mach/mach_types.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_traps.h>
#include <stdio.h>
int main(int argc, const char * argv[]) {
task_t task;
pid_t pid = argc >= 2 ? atoi(argv[1]) : 1;
kern_return_t error = task_for_pid(mach_task_self(), pid, &task);
printf("%d -> %x [%d - %s]\n", pid, task, error, mach_error_string(error));
return error;
}
I've tried signing my executables using codesign and also tried building with Xcode with the "Debugging Tool" box checked under hardened runtime. My Info.plist file includes the SecTaskAccess key with the values "allowed" and "debug." Hoping someone can point me towards what I'm missing here. Thanks!
[Q] What is the thread safety status of the IOBluetooth framework?
Is it possible call any class from the IOBluetooth framework from a secondary thread?
I haven't found so far information about this in the documentation and the only pieces of info you can find through a google search say the framework is not thread safe but these are old pieces of info.
With "Automatically Manage Signing" enabled in Signing & Capabilities I got a message when uploading to the App Store complaining that my provisioning profile was missing Family Control capabilities.
I do have the capability enabled in XCode, and I can deploy directly to devices to see that the app works correctly (that is, it has the capability).
Further, I can see the same capability checked in the App Id under my developer profile.
Further, if I generate a profile manually it claims to include Family Controls in the info screen.
But still it won't let me upload the app.
I've tried:
deleting all automatically generated profiles and regenerating them.
adding and removing the capability in Xcode and in the App Id
generating a manual provisioning profile and downloading it (this one complains about the missing capability when I download it).
Any ideas?
Using the new date formatting API available in iOS 15, I would like to respect the 12 vs 24 hour setting on a user-by-user basis.
With DateFormatter it can be done as follows, for example, to force a 24 hour time irrespective of the user locale.
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm" // or hh:mm for 12 h
However, I cannot figure out how to force the new date formatting API in iOS 15 to do the same thing, i.e. force displaying 12 vs 24 h.
I'm using a format style like this:
var formatStyle = dateTime
formatStyle.calendar = calendar
if let timeZone = timeZone {
formatStyle.timeZone = timeZone
}
return formatStyle
And applying it like this, for example, for a given Date instance:
date.formatted(formatStyle.hour(.defaultDigits(amPM: .abbreviated)))
However, this seems to always give a formatted string relevant to the locale, for example, it's always 12h for the US and always 24h for the UK. This is not the behaviour I really need though, and I'd like to allow each individual user to control what they see irrespective of the locale setting.
(Note that there is an in-app setting that allows the user to toggle between the 12 and 24 hour preference, which is the value I'd like to use to set the preference.)
In another question on this forum (https://developer.apple.com/forums/thread/124775) eskimo stated that launching a system extension from an daemon is not the right approach and that the OSSystemExtensionRequest.activationRequest API should be called from an App.
My question is, does this same restriction apply to a LaunchAgent started App?
If so, to ensure activation as soon as possible is the only option to use a SMLoginItemSetEnabled helper to start the App on login?
According to the WWDC19 video (Introducing Parameters for Shortcuts), the parameters are supposed to be resolved in the order you have placed them in the Intents Definition file in Xcode (see timestamp 13:02 through 13:16).
In my objective C implementation, this is not happening. I deleted the derivedData and clean the build file, but that did not help. Here is a screenshot of my intents definition parameters:
In my implementation, it seems to first process the parameters that do not have "Dynamic Options" check. Then it circles back and works on the ones that have "Dynamic Options". So in my case, it starts with partName, quantity, dimensions, thickness, width, and length. Then it works on partsListName.
Furthermore, while the "Disambiguation Prompt" is spoken/written, the "Disambiguation Introduction" is NOT spoken/written.
Is this a bug that is causing the parameters to be resolved in the wrong order, or do I need to do something differently to force it to resolve parameters in the order that I need it to go in? And are the "Disambiguation Introduction" supposed to work?
StoreKit2 provide great API AppStore.showManageSubscription(in:) to downgrade, upgrade or cancel the user's subscription, however, can the App detect the cancellation in App? (without server to server notification)
I understand the upgrade and downgrade can be detected in Transaction.updates, but I'm not sure about the cancellation.
I want to update my label's text from Next billing date: \(date) to Expires \(date) if the user cancels the subscription in showManageSubscription(in:) sheet.
Can I implement that?
I am trying to encode an AttributedString to JSON and then decode it back to an AttributedString. But when the AttributedString both (1) contains emoji, and (2) has any attributes assigned, the decoding seems to fail, producing a truncated AttributedString. By dump-ing the decoded value, I can see that the full string is still in there (in the guts property) but it is missing in normal uses of the AttributedString.
Below is an example that reproduces the problem.
import Foundation
// An arbitrary AttributedString with emoji
var attrString = AttributedString("12345💕☺️💕☺️💕☺️12345")
// Set an attribute (doesn't seem to matter which one)
attrString.imageURL = URL(string: "http://www.dummy.com/dummy.jpg")!
// Encode the AttributedString
var encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(attrString)
// Print the encoded JSON
print("encoded JSON for AttributedString:")
print(String(data: data, encoding: .utf8)!)
// Output from above omitted, but it looks correct with the full string represented
// Decode the AttributedString and print it
let decoder = JSONDecoder()
let decodedAttrString = try! decoder.decode(AttributedString.self, from: data)
print("decoded AttributedString:")
print(decodedAttrString)
// Output from above is a truncated AttributedString:
//
// 12345💕☺️ {
// NSImageURL = http://www.dummy.com/dummy.jpg
// }
print("dump of AttributedString:")
dump(decodedAttrString)
// Interestingly, `dump` shows that the full string is still in there:
//
// ▿ 12345💕☺️ {
// NSImageURL = http://www.dummy.com/dummy.jpg
// }
// ▿ _guts: Foundation.AttributedString.Guts #0
// - string: "12345💕☺️💕☺️💕☺️12345"
// ▿ runs: 1 element
// ...
//
I am having problems on Xcode13.3.1, Monterey 12.2.1, Apple M1 Max.
Sending an UpdateApplicationContext update from a paired iPhone simulator is not received on the paired Apple Watch Simulator in the didRecieveApplicationContext. However, sendMessage from the apple watch simulator does update the iphone simulator app properly. It is however, not possible to send anything from the paired iPhone simulator to the paired Apple Watch Simulator.
When working with actual devices everything works properly with WatchConnectivity with passing information back and forth via updateapplicationcontext and sendmessage calls.
Can anyone confirm this is a bug or if there is something wrong with my setup?
The unified system log on Apple platforms gets a lot of stick for being ‘too verbose’. I understand that perspective: If you’re used to a traditional Unix-y system log, you might expect to learn something about an issue by manually looking through the log, and the unified system log is way too chatty for that. However, that’s a small price to pay for all its other benefits.
This post is my attempt to explain those benefits, broken up into a series of short bullets. Hopefully, by the end, you’ll understand why I’m best friends with the system log, and why you should be too!
If you have questions or comments about this, start a new thread and tag it with OSLog so that I see it.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Your Friend the System Log
Apple’s unified system log is very powerful. If you’re writing code for any Apple platform, and especially if you’re working on low-level code, it pays to become friends with the system log!
The Benefits of Having a Such Good Friend
The public API for logging is fast and full-featured.
And it’s particularly nice in Swift.
Logging is fast enough to leave log points [1] enabled in your release build, which makes it easier to debug issues that only show up in the field.
The system log is used extensively by the OS itself, allowing you to correlate your log entries with the internal state of the system.
Log entries persist for a long time, allowing you to investigate an issue that originated well before you noticed it.
Log entries are classified by subsystem, category, and type. Each type has a default disposition, which determines whether that log entry is enable and, if it is, whether it persists in the log store. You can customise this, based on the subsystem, category, and type, in four different ways:
Install a configuration profile created by Apple (all platforms).
Add an OSLogPreferences property to your app’s Info.plist (all platforms).
Run the log tool with the config command (macOS only)
Create and install a custom configuration profile with the com.apple.system.logging payload (macOS only).
When you log a value, you may tag it as private. These values are omitted from the log by default but you can configure the system to include them. For information on how to do that, see Recording Private Data in the System Log.
The Console app displays the system log. On the left, select either your local Mac or an attached iOS device. Console can open and work with log snapshots (.logarchive). It also supports surprisingly sophisticated searching. For instructions on how to set up your search, choose Help > Console Help.
Console’s search field supports copy and paste. For example, to set up a search for the subsystem com.foo.bar, paste subsystem:com.foo.bar into the field.
Console supports saved searches. Again, Console Help has the details.
Console supports viewing log entries in a specific timeframe. By default it shows the last 5 minutes. To change this, select an item in the Showing popup menu in the pane divider. If you have a specific time range of interest, select Custom, enter that range, and click Apply.
Instruments has os_log and os_signpost instruments that record log entries in your trace. Use this to correlate the output of other instruments with log points in your code.
Instruments can also import a log snapshot. Drop a .logarchive file on to Instruments and it’ll import the log into a trace document, then analyse the log with Instruments’ many cool features.
The log command-line tool lets you do all of this and more from Terminal.
The log stream subcommand supports multiple output formats. The default format includes column headers that describe the standard fields. The last column holds the log message prefixed by various fields. For example:
cloudd: (Network) [com.apple.network:connection] nw_flow_disconnected …
In this context:
cloudd is the source process.
(Network) is the source library. If this isn’t present, the log came from the main executable.
[com.apple.network:connection] is the subsystem and category. Not all log entries have these.
nw_flow_disconnected … is the actual message.
There’s a public API to read back existing log entries, albeit one with significant limitations on iOS (more on that below).
Every sysdiagnose log includes a snapshot of the system log, which is ideal for debugging hard-to-reproduce problems. For more details on that, see Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. For general information about sysdiagnose logs, see Bug Reporting > Profiles and Logs.
But you don’t have to use sysdiagnose logs. To create a quick snapshot of the system log, run the log tool with the collect subcommand. If you’re investigating recent events, use the --last argument to limit its scope. For example, the following creates a snapshot of log entries from the last 5 minutes:
% sudo log collect --last 5m
For more information, see:
os > Logging
OSLog
log man page
os_log man page (in section 3)
os_log man page (in section 5)
WWDC 2016 Session 721 Unified Logging and Activity Tracing
[1] Well, most log points. If you’re logging thousands of entries per second, the very small overhead for these disabled log points add up.
Foster Your Friendship
Good friendships take some work on your part, and your friendship with the system log is no exception. Follow these suggestions for getting the most out of the system log.
The system log has many friends, and it tries to love them the all equally. Don’t abuse that by logging too much. One key benefit of the system log is that log entries persist for a long time, allowing you to debug issues with their roots in the distant past. But there’s a trade off here: The more you log, the shorter the log window, and the harder it is to debug such problems.
Put some thought into your subsystem and category choices. One trick here is to use the same category across multiple subsystems, allowing you to track issues as they cross between subsystems in your product. Or use one subsystem with multiple categories, so you can search on the subsystem to see all your logging and then focus on specific categories when you need to.
Don’t use too many unique subsystem and context pairs. As a rough guide: One is fine, ten is OK, 100 is too much.
Choose your log types wisely. The documentation for each OSLogType value describes the default behaviour of that value; use that information to guide your choices.
Remember that disabled log points have a very low cost. It’s fine to leave chatty logging in your product if it’s disabled by default.
No Friend Is Perfect
The system log API is hard to wrap. The system log is so efficient because it’s deeply integrated with the compiler. If you wrap the system log API, you undermine that efficiency. For example, a wrapper like this is very inefficient:
-*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*-
void myLog(const char * format, ...) {
va_list ap;
va_start(ap, format);
char * str = NULL;
vasprintf(&str, format, ap);
os_log_debug(sLog, "%s", str);
free(str);
va_end(ap);
}
-*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*-
This is mostly an issue with the C API, because the modern Swift API is nice enough that you rarely need to wrap it.
If you do wrap the C API, use a macro and have that pass the arguments through to the underlying os_log_xyz macro.
iOS has very limited facilities for reading the system log. Currently, an iOS app can only read entries created by that specific process, using .currentProcessIdentifier scope. This is annoying if, say, the app crashed and you want to know what it was doing before the crash. What you need is a way to get all log entries written by your app (r. 57880434).
There are two known bugs with the .currentProcessIdentifier scope. The first is that the .reverse option doesn’t work (r. 87622922). You always get log entries in forward order. The second is that the getEntries(with:at:matching:) method doesn’t honour its position argument (r. 87416514). You always get all available log entries.
Xcode 15 beta has a shiny new console interface. For the details, watch WWDC 2023 Session 10226 Debug with structured logging. For some other notes about this change, search the Xcode 15 Beta Release Notes for 109380695.
In older versions of Xcode the console pane was not a system log client (r. 32863680). Rather, it just collected and displayed stdout and stderr from your process. This approach had a number of consequences:
The system log does not, by default, log to stderr. Xcode enabled this by setting an environment variable, OS_ACTIVITY_DT_MODE. The existence and behaviour of this environment variable is an implementation detail and not something that you should rely on.
Xcode sets this environment variable when you run your program from Xcode (Product > Run). It can’t set it when you attach to a running process (Debug > Attach to Process).
Xcode’s Console pane does not support the sophisticated filtering you’d expect in a system log client.
When I can’t use Xcode 15, I work around the last two by ignoring the console pane and instead running Console and viewing my log entries there.
If you don’t see the expected log entries in Console, make sure that you have Action > Include Info Messages and Action > Include Debug Messages enabled.
The system log interface is available within the kernel but it has some serious limitations. Here’s the ones that I’m aware of:
Prior to macOS 14.4, there was no subsystem or category support (r. 28948441).
There is no support for annotations like {public} and {private}.
Adding such annotations causes the log entry to be dropped (r. 40636781).
Metal shaders can log using the interface described in section 6.19 of the Metal Shading Language Specification.
Revision History
2024-10-22 Added some notes on interpreting the output from log stream.
2024-09-17 The kernel now includes subsystem and category support.
2024-09-16 Added a link to the the Metal logging interface.
2023-10-20 Added some Instruments tidbits.
2023-10-13 Described a second known bug with the .currentProcessIdentifier scope. Added a link to Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem.
2023-08-28 Described a known bug with the .reverse option in .currentProcessIdentifier scope.
2023-06-12 Added a call-out to the Xcode 15 Beta Release Notes.
2023-06-06 Updated to reference WWDC 2023 Session 10226. Added some notes about the kernel’s system log support.
2023-03-22 Made some minor editorial changes.
2023-03-13 Reworked the Xcode discussion to mention OS_ACTIVITY_DT_MODE.
2022-10-26 Called out the Showing popup in Console and the --last argument to log collect.
2022-10-06 Added a link WWDC 2016 Session 721 Unified Logging and Activity Tracing.
2022-08-19 Add a link to Recording Private Data in the System Log.
2022-08-11 Added a bunch of hints and tips.
2022-06-23 Added the Foster Your Friendship section. Made other editorial changes.
2022-05-12 First posted.
I built an app which hosts a CMIOExtension. The app works, and it can activate the extension. The extension loads in e.g. Photo Booth and shows the expected video (a white horizontal line which moves down the picture).
I have a couple of questions about this though.
The sample Camera Extension is built with a CMIOExtension dictionary with just one entry, CMIOExtensionMachServiceName which is $(TeamIdentifierPrefix)$(PRODUCT_BUNDLE_IDENTIFIER)
This Mach service name won't work though. When attempting to activate the extension, sysextd says that the extensions has an invalid mach service name or is not signed, the value must be prefixed with one of the App Groups in the entitlement.
So in order to get the sample extension to activate from my app, I have to change its CMIOExtensionMachServiceName to
<my team ID>.com.mycompany.my-app-group.<myextensionname>
Is this to be expected?
The template CMIOExtension generates its own video using a timer. My app is intended to capture video from a source, filter that video, then feed it to the CMIOExtension, somehow. The template creates an app group called "$(TeamIdentifierPrefix)com.example.app-group", which suggests that it might be possible to use XPC to send frames from the app to the extension.
However, I've been unable to do so. I've used
NSXPCConnection * connection = [[NSXPCConnection alloc] initWithMachServiceName:, using the CMIOExtensionMachServiceName with no options and with the NSXPCConnectionPrivileged option. I've tried NSXPCConnection * connection = [[NSXPCConnection alloc] initWithServiceName: using the extension's bundle identifier. In all cases when I send the first message I get an error in the remote object proxy's handler:
Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named <whatever name I try> was invalidated: failed at lookup with error 3 - No such process."
According to the "Daemons and Services Programming Guide" an XPC service should have a CFBundlePackageType of XPC!, but a CMIOExtension is of type SYSX. It can't be both.
Does the CMIOExtension loading apparatus cook up a synthetic name for the XPC service, and if so, what is it? If none, how is one expected to get pixel buffers into the camera extension?
Hi,
can i create custom tool for PKToolPicker?
On documentation page on PKTool says "Don’t adopt this protocol in your own objects. Instead, create a tool object to provide users with the desired the tool behavior."
Best regards,
Matej Klemen
Attached is an entire project (4 files) that mirrors my actual project including the failure to save to file.
Am I:
missing some syntax in this code?
failing to config a defaults file?
not set the necessary parameters in " "Build Settings" or "Build Rules etc.?
I was writing to JSON files, but now that I must append to files directly, and JSON doesn't do that easily, I am trying to write using native macOS tools.
WELL, IT SEEMS I CAN'T SEND YOU THE CODE, TOO MANY CHARS. I CAN'T ATTACH ANY FILE EITHER. WHY OFFER IT IF IT IS NOT ALLOWED?
ANYWAY, CAN YOU GLEAN ANYTHING FROM THIS... Thanks.
My debugger area:
2022-05-28 12:03:11.827372-0500 exampleClassInClassSecureCoding[1508:29981] Metal API Validation Enabled
2022-05-28 12:03:11.940123-0500 exampleClassInClassSecureCoding[1508:29981] *** NSForwarding: warning: object 0x600003cf7090 of class 'exampleClassInClassSecureCoding.classOne' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[exampleClassInClassSecureCoding.classOne replacementObjectForKeyedArchiver:]
2022-05-28 12:03:11.940416-0500 exampleClassInClassSecureCoding[1508:29981] Unrecognized selector -[exampleClassInClassSecureCoding.classOne replacementObjectForKeyedArchiver:]
Unrecognized selector -[exampleClassInClassSecureCoding.classOne replacementObjectForKeyedArchiver:]
Performing @selector(didPressButton:) from sender _TtC7SwiftUIP33_9FEBA96B0BC70E1682E82D239F242E7319SwiftUIAppKitButton 0x7ff08ab06480
I've got an app that is sandboxed, and it requires a privileged helper. I've worked through the EBAS sample app with various updates to conform with current systems. After a lot of work, I've got to a point where I'm stumped.
The Python script SMJobBlessUtil.py returns this error, and I don't know what to do to correct it:
<path to helper tool>: tool __TEXT / __info_plist section dump malformed (2)
I've gone over the various settings numerous times. It doesn't fail for the EBAS sample, but does for my app. Looking at the binary, the __info_plist sections look identical apart from identifiers. This is what mine looks like (identifiers deleted):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>***</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>***</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>SMAuthorizedClients</key>
<array>
<string>anchor apple generic and identifier "***" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "***")</string>
</array>
</dict>
</plist>
I must be missing something, but I've run out of ideas on where to find it. Anybody got a pointer?
Hello
When I open CarPlay Simulator and connect the phone, it gives the following error:
Accessory is not Supported
Mac Mini MacOS 12.4 with iPhone 13 Pro iOS 15.5
Does anyone have a solution?
General:
TN3151 Choosing the right networking API
Networking Overview document — Despite the fact that this is in the archive, this is still really useful.
TLS for App Developers DevForums post
Choosing a Network Debugging Tool documentation
WWDC 2019 Session 712 Advances in Networking, Part 1 — This explains the concept of constrained networking, which is Apple’s preferred solution to questions like How do I check whether I’m on Wi-Fi?
TN3135 Low-level networking on watchOS
Adapt to changing network conditions tech talk
Foundation networking:
DevForums tags: Foundation, CFNetwork
URL Loading System documentation — NSURLSession, or URLSession in Swift, is the recommended API for HTTP[S] on Apple platforms.
Network framework:
DevForums tag: Network
Network framework documentation — Network framework is the recommended API for TCP, UDP, and QUIC on Apple platforms.
Network Extension (including Wi-Fi on iOS):
See Network Extension Resources
Wi-Fi Fundamentals
Wi-Fi on macOS:
DevForums tag: Core WLAN
Core WLAN framework documentation
Wi-Fi Fundamentals
Secure networking:
DevForums tags: Security
Apple Platform Security support document
Preventing Insecure Network Connections documentation — This is all about App Transport Security (ATS).
Available trusted root certificates for Apple operating systems support article
Requirements for trusted certificates in iOS 13 and macOS 10.15 support article
About upcoming limits on trusted certificates support article
Apple’s Certificate Transparency policy support article
Technote 2232 HTTPS Server Trust Evaluation
Technote 2326 Creating Certificates for TLS Testing
QA1948 HTTPS and Test Servers
Miscellaneous:
More network-related DevForums tags: 5G, QUIC, Bonjour
On FTP DevForums post
Using the Multicast Networking Additional Capability DevForums post
Investigating Network Latency Problems DevForums post
Local Network Privacy FAQ DevForums post
Extra-ordinary Networking DevForums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"