General:
Forums subtopic: App & System Services > Networking
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 forums 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
TN3179 Understanding local network privacy
Adapt to changing network conditions tech talk
Understanding Also-Ran Connections forums post
Extra-ordinary Networking forums post
Foundation networking:
Forums tags: Foundation, CFNetwork
URL Loading System documentation — NSURLSession, or URLSession in Swift, is the recommended API for HTTP[S] on Apple platforms.
Moving to Fewer, Larger Transfers forums post
Testing Background Session Code forums post
Network framework:
Forums tag: Network
Network framework documentation — Network framework is the recommended API for TCP, UDP, and QUIC on Apple platforms.
Building a custom peer-to-peer protocol sample code (aka TicTacToe)
Implementing netcat with Network Framework sample code (aka nwcat)
Configuring a Wi-Fi accessory to join a network sample code
Moving from Multipeer Connectivity to Network Framework forums post
NWEndpoint History and Advice forums post
Network Extension (including Wi-Fi on iOS):
See Network Extension Resources
Wi-Fi Fundamentals
TN3111 iOS Wi-Fi API overview
Wi-Fi Aware framework documentation
Wi-Fi on macOS:
Forums tag: Core WLAN
Core WLAN framework documentation
Wi-Fi Fundamentals
Secure networking:
Forums tags: Security
Apple Platform Security support document
Preventing Insecure Network Connections documentation — This is all about App Transport Security (ATS).
WWDC 2017 Session 701 Your Apps and Evolving Network Security Standards [1] — This is generally interesting, but the section starting at 17:40 is, AFAIK, the best information from Apple about how certificate revocation works on modern systems.
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
What’s new for enterprise in iOS 18 support article — This discusses new key usage requirements.
Technote 2232 HTTPS Server Trust Evaluation
Technote 2326 Creating Certificates for TLS Testing
QA1948 HTTPS and Test Servers
Miscellaneous:
More network-related forums tags: 5G, QUIC, Bonjour
On FTP forums post
Using the Multicast Networking Additional Capability forums post
Investigating Network Latency Problems forums post
WirelessInsights framework documentation
iOS Network Signal Strength forums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] This video is no longer available from Apple, but the URL should help you locate other sources of this info.
Foundation
RSS for tagAccess essential data types, collections, and operating-system services to define the base layer of functionality for your app using Foundation.
Posts under Foundation tag
185 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Two errors in debug: com.apple.modelcatalog.catalog sync and nw_protocol_instance_set_output_handler
We get two error message in Xcode debug. apple.model.catalog we get 1 time at startup, and the nw_protocol_instance_set_output_handler Not calling remove_input_handler on 0x152ac3c00:udp we get on sartup and some time during running of the app. I have tested cutoff repos WS eg. But nothing helpss, thats for the nw_protocol. We have a fondationmodel in a repo but we check if it is available if not we do not touch it.
Please help me?
nw_protocol_instance_set_output_handler Not calling remove_input_handler on 0x152ac3c00:udp
com.apple.modelcatalog.catalog sync: connection error during call: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.modelcatalog.catalog was invalidated: Connection init failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.modelcatalog.catalog was invalidated: Connection init failed at lookup with error 159 - Sandbox restriction.} reached max num connection attempts: 1
The function we have in the repo is this:
public actor FoundationRepo: JobDescriptionChecker, SubskillSuggester {
private var session: LanguageModelSession?
private let isEnabled: Bool
private let shouldUseLocalFoundation: Bool
private let baseURLString = "https://xx.xx.xxx/xx"
private let http: HTTPPac
public init(http: HTTPPac, isEnabled: Bool = true) {
self.http = http
self.isEnabled = isEnabled
self.session = nil
guard isEnabled else {
self.shouldUseLocalFoundation = false
return
}
let model = SystemLanguageModel.default
guard model.supportsLocale() else {
self.shouldUseLocalFoundation = false
return
}
switch model.availability {
case .available:
self.shouldUseLocalFoundation = true
case .unavailable(.deviceNotEligible),
.unavailable(.appleIntelligenceNotEnabled),
.unavailable(.modelNotReady):
self.shouldUseLocalFoundation = false
@unknown default:
self.shouldUseLocalFoundation = false
}
}
So here we decide if we are going to use iPhone ML or my backend-remote?
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags:
Foundation
Swift
SwiftUI
Xcode Sanitizers and Runtime Issues
So if I create an Alias of a folder in Finder and hand the alias to my app (I also moved the alias file to a new folder, but I did not move the original folder)...so then my app resolves the alias using:
NSURL +URLByResolvingAliasFileAtURL:
What happens?
The resolved URL points to a completely different folder. Well not completely different. It resolves to a folder that happens to share same last path component as the original folder...but this folder is inside the same parent folder the alias file is in. It does not resolve to the original folder I created the alias of.
So then once my app touches the alias with +URLByResolvingAliasFileAtURL: the alias now resolves to this new (wrong) location (even in Finder).
Couple details:
My app is not sandboxed.
I have permission to access the original folder in my app (but even if I didn't the alias shouldn't be mutated just by merely resolving it).
Only seems to happen if the folder I move the alias to happens to contain a sibling folder that has the same title as the original folder. Like it's just deleting the last path component of the alias and then appending the last path component of the original filename and just going with that. I hope that makes sense.
I tried creating the alias myself using -bookmarkDataWithOptions: and going the other way (to Finder) but Finder must be resolving the alias using a different API because it resolves to the original location as expected.
I'll try to ask a question that makes sense this time :) . I'm using the following method on NSFileManager:
(BOOL) getRelationship:(NSURLRelationship *) outRelationship
ofDirectoryAtURL:(NSURL *) directoryURL
toItemAtURL:(NSURL *) otherURL
error:(NSError * *) error;
Sets 'outRelationship' to NSURLRelationshipContains if the directory at 'directoryURL' directly or indirectly contains the item at 'otherURL', meaning 'directoryURL' is found while enumerating parent URLs starting from 'otherURL'. Sets 'outRelationship' to NSURLRelationshipSame if 'directoryURL' and 'otherURL' locate the same item, meaning they have the same NSURLFileResourceIdentifierKey value. If 'directoryURL' is not a directory, or does not contain 'otherURL' and they do not locate the same file, then sets 'outRelationship' to NSURLRelationshipOther. If an error occurs, returns NO and sets 'error'.
So this method falsely returns NSURLRelationshipSame for different directories. One is empty, one is not. Really weird behavior. Two file path urls pointing to two different file paths have the same NSURLFileResourceIdentifierKey? Could it be related to https://developer.apple.com/forums/thread/813641 ?
One url in the check lived at the same file path as the other url at one time (but no longer does). No symlinks or anything going on. Just plain directory urls.
And YES calling -removeCachedResourceValueForKey: with NSURLFileResourceIdentifierKey causes proper result of NSURLRelationshipOther to be returned. And I'm doing the check on a background queue.
Environment:
Hardware: Mac M4
OS: macOS Sequoia 15.7.4
TensorFlow-macOS Version: 2.16.2
TensorFlow-metal Version: 1.2.0
Description:
When using the tensorflow-metal plug-in for GPU acceleration on M4, the ReLU activation function (both as a layer and as an activation argument) fails to correctly clip negative values to zero. The same code works correctly when forced to run on the CPU.
Reproduction Script:
import os
import numpy as np
import tensorflow as tf
# weights and biases = -1
weights = [np.ones((10, 5)) * -1, np.ones(5) * -1]
# input = 1
data = np.ones((1, 10))
# comment this line => GPU => get negative values
# uncomment this line => CPU => no negative values
# tf.config.set_visible_devices([], 'GPU')
# create model
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(10,)),
tf.keras.layers.Dense(5, activation='relu')
])
# set weights
model.layers[0].set_weights(weights)
# get output
output = model.predict(data)
# check if negative is present
print(f"min value: {output.min()}")
print(f"is negative present? {np.any(output < 0)}")
I'm trying to use the new Speech framework for streaming transcription on macOS 26.3, and I can reproduce a failure with SpeechAnalyzer.start(inputSequence:).
What is working:
SpeechAnalyzer + SpeechTranscriber
offline path using start(inputAudioFile:finishAfterFile:)
same Spanish WAV file transcribes successfully and returns a coherent final result
What is not working:
SpeechAnalyzer + SpeechTranscriber
stream path using start(inputSequence:)
same WAV, replayed as AnalyzerInput(buffer:bufferStartTime:)
fails once replay starts with:
_GenericObjCError domain=Foundation._GenericObjCError code=0 detail=nilError
I also tried:
DictationTranscriber instead of SpeechTranscriber
no realtime pacing during replay
Both still fail in stream mode with the same error.
So this does not currently look like a ScreenCaptureKit issue or a Python integration issue. I reduced it to a pure Swift CLI repro.
Environment:
macOS 26.3 (25D122)
Xcode 26.3
Swift 6.2.4
Apple Silicon Mac
Has anyone here gotten SpeechAnalyzer.start(inputSequence:) working reliably on macOS 26.x?
If so, I'd be interested in any workaround or any detail that differs from the obvious setup:
prepareToAnalyze(in:)
bestAvailableAudioFormat(...)
AnalyzerInput(buffer:bufferStartTime:)
replaying a known-good WAV in chunks
I already filed Feedback Assistant:
FB22149971
In Swift, iOS, I have a pdf file.
I want to take the pages 2 by 2 and put them side by side, on the new page.
For this, I have to scale initial pages half size and rotate .pi/2.
I managed to achieve this by converting pdf pages to UIImages and using a UIGraphicsImageRenderer. But with a critical loss of resolution.
I've tried improving the resolution by creating images as jpegData(withCompressionQuality: 1.0), to no avail.
So I would need to work directly on the pdf pages using CGPDFDocument format.
The code structure is as follows, to insert a single scaled page:
for iPage in … {
if let _page = theCGPdfDocument.page(at: 1) {
var _pageRect: CGRect = _page.getBoxRect(CGPDFBox.mediaBox)
writeContextInDestination!.beginPage(mediaBox: &_pageRect)
// translate to compensate for the flip caused displacement
writeContextInDestination!.translateBy(x: _pageRect.size.width, y: _pageRect.size.height)
Scale (-1, -1) // rotate 180°
// add rotate as needed
writeContextInDestination!.scaleBy(x: -1, y: -1)
writeContextInDestination!.clip(to: _pageRect)
writeContextInDestination!.drawPDFPage(_page)
writeContextInDestination!.endPage() // end the current page
}
}
writeContextInDestination!.closePDF()
But I do not succeed in inserting the drawing of the second page.
I've tried repeating lines 7 to 11 for a second page at line 13. No success.
What is the direction to look for ?
I have an iOS app that runs on Mac, in iPad mode.
In the menubar, some subitems are improperly labelled, featuring NSMENUITEMTITLEABOUT or NSMENUITEMHIDE or NSMENUITEMTITLE instead. Looks like it cannot find the name of the app.
I have tried to set display name to no avail.
Or is it a localisation issue ?
How to correct this ?
Hi,
I’m looking for clarification on what concurrency and consistency guarantees Apple provides when multiple targets (main app + Widget extensions) access shared storage.
Specifically:
1. UserDefaults (App Group / suiteName:)
• If multiple processes (app + multiple widget instances) read and write the same shared UserDefaults, what guarantees are provided?
• Is access serialized internally to prevent corruption?
• Are read–modify–write operations safe across processes, or can lost updates occur?
2. Core Data (shared SQLite store in App Group container)
• Is it officially supported for multiple processes to open and write to the same Core Data SQLite store?
• Are there recommended configurations (e.g. WAL mode) for safe multi-process access?
• Is Apple’s recommendation to have a single writer process?
3. FileManager (shared container files)
• If two processes write to the same file in an App Group container, what guarantees are provided by the system?
• Is atomic replaceItemAt the recommended pattern for safe cross-process updates?
Additionally:
• Do multiple widget instances count as separate processes with respect to these guarantees?
• Is there official guidance on best practices for shared persistence between app and widget extensions?
I want to ensure I’m following the correct architecture and not relying on undefined behavior.
Thanks.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Foundation
WidgetKit
Core Data
Concurrency
I set the value of NSURLHasHiddenExtensionKey. I provide a textfield to rename a file and I set this flag based on whether the user has deleted or left on the path extension.
So -setResourceValue:forKey:error: returns YES, does not populate the error, but does not honor the value I just set it to.
I'm always setting it off the main thread on the same serial queue. Works the first time I rename the file then it just starts failing (silently).
For example:
NSError *setError = nil;
if ([theURL setResourceValue:@(NO) forKey:NSURLHasHiddenExtensionKey error:&setError])
{
[theURL removeAllCachedResourceValues];
NSNumber *freshRead = nil;
NSError *getError = nil;
if ([theURL getResourceValue:&freshRead forKey:NSURLHasHiddenExtensionKey error:&getError])
{
if (freshRead.boolValue)
{
NSLog(@"it is yes when it should be NO.");
}
}
if (getError != nil)
{
NSLog(@"Get error: %@",getError);
}
}
if (setError != nil)
{
NSLog(@"Set error: %@",setError);
}
While I get that it is possible for there to be other apps setting this value at the same time as my app, doesn't really seem possible in my local environment right now.
No errors log out but "it is yes when it should be NO." does log out.
In this code, I use in some places
required init?(coder: (NSCoder?)) {
// Init some properties
super.init(coder: coder!)
}
And in other places
required init?(coder: NSCoder) {
super.init(coder: coder)
// Init some properties
}
Both seem to work. Is there a preferred one ? In which cases ? Or should I always use the second one ?
And can super be called at anytime ?
In this Mac App, I have an IBOutlet (which is defined as instance of a subclass of NSView).
When I connect the IBOutlet to the code, referencing as file's owner, it works OK.
But if I reference to the class, it crashes, when I access a specific IBOutlet (but other IBOutlets are accessed just before it without crashing)..
The IBOutlet turnPageControl is defined as instance of subclass of NSView.
Note: I have implemented several init methods:
override init(window: NSWindow!) { }
required init?(coder: (NSCoder?)) { } // Yes, (NSCoder?)
convenience init(parameters) {
// loading from nib
}
override func windowDidLoad() {
super.windowDidLoad()
// Access turnpageControl
I get those calls before crash:
init(window:)
init(parameters:)
init(window:)
windowDidLoad() -> crash inside on accessing the IBOutlet
for turnPageControl.isHidden = true
Is there any reason to this ?
So I'm reworking couple things in my app. And I noticed I had this old code that does the following:
Creates a temporary directory.
Writes a file in the temporary directory.
After the file is written moves the file out of the temporary location and places it in its final destination.
Okay so I was not creating the temporary directory using the recommended API. I was simply doing something like this:
NSURL *tempDirectory = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSProcessInfo processInfo].globallyUniqueString]];
// Create tempDirectory and write files inside it.
Now I just changed the code to use the recommended API which takes the the volume of the target destination into account: -URLForDirectory:inDomain:appropriateForURL:create:error:) and I pass in NSItemReplacementDirectory and a url to appropriateForURL so the destination volume is taken into account.
Now I have external storage mounted and I use the recommended approach. I discovered NSFileManager simply writes a directory right in a user facing location titled: **(A Document Being Saved By App Name) ** and the folder is not hidden.
Is this intended behavior for this API? Are temporary files supposed to be user facing? I know it is good practice to clean up temporary stuff when you are done but in crashes or just forgetting to clean up will leave these behind which isn't the behavior I expect for "temporary files." Also if the user is viewing the folder in Finder they'll see these A Document Being Saved By App Name folders appear and disappear in the window as my app does this work.
MacOS system settings allow the user to select one of a number of number formats. My app behaves differently depending on the format (taken from the system Locale), so I need to test every combination.
Thus far I have been successful at creating Locale objects with various identifiers that map to the different formats, like:
let westEuropeanLocale = Locale(identifier: "en_DE")
However, I can't find a locale that maps to using . as a decimal point, and space as a thousands separator, even though it's a standard option (3rd in this list):
Any suggestions on how to create a test for this number format?
macOS 26 "Tahoe" is allocating much more memory for apps than former macOS versions: A customer contacted me with my app's Thumbnail extension allocating so much memory that her 48 GB RAM Mac Mini ran into "out of application memory" state. I couldn't identify any memory leak in my extension's code nor reproduce the issue, but found the main app allocating as much as 5 times the memory compared to running on macOS 15 or lower.
This productive app is explicitly using "Liquid Glass" views as well as implicitly e.g. for an inspector pane. So I created a sample app, just based on Xcode's template of a document-based app, and the issue is still showing (although less dramatically): This sample app allocates 22 MB according to Tahoe's Activity Monitor, while Sequoia only requires 16 MB:
macOS 15.6.1
macOS 26.2
Is anyone experiencing similar issues? I suspect some massive leak in Tahoe's memory management, and just filed a corresponding feedback (FB21967167).
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Foundation
QuickLook Thumbnailing
AppKit
Hey,
I am just about to prepare my app for Swift 6, and facing the issue that UserDefaults is not Sendable. The documentation states that its thread safe, so I am wondering, why is it not marked as Sendable? Was it just forgotten? Is it safe to mark it as nonisolated(unsafe) or @unchecked Sendable?
Hello. We are facing very silent and hardly replicable issue. All UserDefaults.standard data the application saved and was using to determine the state of app is lost and app behaves as if it was freshly installed.
The issue always occurs only if we leave app on background for long time or if we manually swipe the app from the background apps. In case we swipe, this issue can occur in minutes, hours or up to 2 days by our latest testing.
One important factor is that the app was developed using iOS18 in which issue never occured. Next it was being tested on iOS26 and it did everytime. Any currently available version of iOS26 reported this issue, all the way up to 26.2.1 (23C71). Our application is going through major upgrade of its whole lifecycle and services so it is possible this issue is caused by a bug in development as the production version does not report this issue neither on iOS26 of any version.
The following list contains how we tried to fix this issue but none of which helped.
App prewarming in the background (postpone all initialization including searching UserDefaults.standard for when isProtectedDataAvailable)
Calling UserDefaults.standard.synchronize() everytime after saving data despite it is not recomended
Built app using different SDK's (tested on iOS18 and iOS26 SDK)
Distributed the app from local machine aswell as on TestFlight itself
We searched through currently opened and closed issues for third-party libraries app uses regarding 'iOS26' and 'UserDefaults', especially those who were added recently with no success.
The structure using which we save data into UserDefaults.standard did not change, we have only added few more settings to save through the lifecycle of the app after update. We estimate the overall increase is merely 30% more of what it used to be in previous version.
Any ideas are much appreciated. We are considering to use different or fully custom ways to store app's settings.
I'm importing SwiftUI, Foundation and Charts into an iOS app I'm writing in Swift in Xcode Playgrounds and am getting this error:
error: Couldn't look up symbols:
protocol witness table for Foundation.Date : Charts.Plottable in Charts
the code looks like this in just two example files:
file 1, the view
import Foundation
import SwiftUI
import Charts
import PlaygroundSupport
struct FirstChart_WithDates: View {
private let data = ChartDateAndDoubleModel.mockData(months: 3)
var body: some View {
Chart(data) { item in
BarMark(
x: .value("Label", item.date, unit: .month),
y: .value("Value", item.value)
)
}
.padding()
.aspectRatio(1, contentMode: .fit)
.dynamicTypeSize(.accessibility1)
ChartDateAndDoubleModelView(data: data)
}
}
struct ChartDateAndDoubleModelView: View {
var data: [ChartDateAndDoubleModel]
var body: some View {
VStack {
HeaderRowView(texts: ["date", "value"])
ForEach(data) { datum in
HStack {
Text(datum.date.formatted(date: .abbreviated, time: .omitted))
.frame(maxWidth: .infinity)
// TODO: Format for 2 decimal places.
Text(datum.value, format: .number.precision(.fractionLength(2)))
.frame(maxWidth: .infinity)
}
}
}
.padding(.bottom, 8)
.overlay(.quaternary, in: .rect(cornerRadius: 8).stroke())
.padding()
}
}
struct HeaderRowView: View {
var texts: [String]
var body: some View {
HStack(spacing: 2.0) {
ForEach(texts, id: \.self) { text in
Text(text)
.padding(4)
.frame(maxWidth: .infinity)
.background(.quaternary)
}
}
.font(.headline)
.mask(UnevenRoundedRectangle(topLeadingRadius: 8, topTrailingRadius: 8))
}
}
and file 2, the model:
import Foundation
import SwiftUI
import Charts
// ChartDateAndDoubleModel.swift
//
//
// Created by Michael Isbell on 2/10/26.
//
public struct ChartDateAndDoubleModel: Identifiable {
public let id = UUID()
public let date: Date
public let value: Double
}
public extension ChartDateAndDoubleModel {
static func mockData(months: Int = 5) -> [ChartDateAndDoubleModel] {
var data: [ChartDateAndDoubleModel] = []
let calendar = Calendar(identifier: .gregorian)
let currentDate = Date()
for month in 0..<months {
//add month to current date and append to data
data.append(
ChartDateAndDoubleModel(
date: calendar.date(byAdding: .month, value: month, to: currentDate)!,
value: Double.random(in: 0...1000)
)
)
}
return data
}
}
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags:
Foundation
Swift Playground
Playground Support
Swift Charts
I am building an app for iOS and MacCatalyst that indexes files by storing their local paths. Because the app relies on the file remaining at its original location, I only want to accept items that can be opened in place.
I am struggling to determine if an item is "Open In Place" compatible early in the drag-and-drop lifecycle. Specifically:
In dropInteraction(_:canHandle:) and dropInteraction(_:sessionDidUpdate:), calling itemProvider.registeredTypeIdentifiers(fileOptions: [.openInPlace]) returns an empty array.
Only once the drop is actually committed in dropInteraction(_:performDrop:) does that same call return the expected type identifiers.
This creates a poor user experience. I want to validate the "In Place" capability at the very start of the session so the drop target only activates for valid files. If an item is ephemeral (like a dragged photo from the Photos app or a temporary export), the drop zone should not react at all.
How can I reliably detect if an NSItemProvider supports .openInPlace before the performDrop delegate method is called?
Topic:
App & System Services
SubTopic:
General
Tags:
Mac Catalyst
UIKit
Files and Storage
Foundation
A user of my app reported that when my app copies files from a QNAP NAS to a folder on their Mac, they get the error "Result too large". When copying the same files from the Desktop, it works.
I asked them to reproduce the issue with the sample code below and they confirmed that it reproduces. They contacted QNAP for support who in turn contacted me saying that they are not sure they can do anything about it, and asking if Apple can help.
Both the app user and QNAP are willing to help, but at this point I'm also unsure how to proceed. Can someone at Apple say anything about this? Is this something QNAP should solve, or is this a bug in macOS?
P.S.: I've had users in the past who reported the same issue with other brands, mostly Synology.
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.runModal()
let source = openPanel.urls[0]
openPanel.canChooseFiles = false
openPanel.runModal()
let destination = openPanel.urls[0]
do {
try copyFile(from: source, to: destination.appendingPathComponent(source.lastPathComponent, isDirectory: false))
} catch {
NSAlert(error: error).runModal()
}
NSApp.terminate(nil)
}
private func copyFile(from source: URL, to destination: URL) throws {
if try source.resourceValues(forKeys: [.isDirectoryKey]).isDirectory == true {
try FileManager.default.createDirectory(at: destination, withIntermediateDirectories: false)
for source in try FileManager.default.contentsOfDirectory(at: source, includingPropertiesForKeys: nil) {
try copyFile(from: source, to: destination.appendingPathComponent(source.lastPathComponent, isDirectory: false))
}
} else {
try copyRegularFile(from: source, to: destination)
}
}
private func copyRegularFile(from source: URL, to destination: URL) throws {
let state = copyfile_state_alloc()
defer {
copyfile_state_free(state)
}
var bsize = UInt32(16_777_216)
if copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize) != 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
} else if copyfile_state_set(state, UInt32(COPYFILE_STATE_STATUS_CB), unsafeBitCast(copyfileCallback, to: UnsafeRawPointer.self)) != 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
} else if copyfile(source.path, destination.path, state, copyfile_flags_t(COPYFILE_DATA | COPYFILE_SECURITY | COPYFILE_NOFOLLOW | COPYFILE_EXCL | COPYFILE_XATTR)) != 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
}
private let copyfileCallback: copyfile_callback_t = { what, stage, state, src, dst, ctx in
if what == COPYFILE_COPY_DATA {
if stage == COPYFILE_ERR {
return COPYFILE_QUIT
}
}
return COPYFILE_CONTINUE
}
}
I am developing an iOS/iPadOS application and have encountered some behavior regarding Files App and security-scoped bookmarks that I would like to clarify.
Additionally, I would like to report some behavior which might include a potential issue.
Question1: Accessing deleted files via bookmark (Specification clarification)
Our app saves file URLs as bookmarks, which file that user has selected on Files App or app-created so to open a file which user has modified previously in the next launch.
When a user deletes a file in Files App (moves a file to Recently Deleted), the app can still resolve the bookmark and access the file for read/write operations.
Is this behavior intended?
In other words, is it correct that a bookmark can access a file that has been deleted in Files App but not permanently removed?
Question2: Overwriting a file in Recently Deleted (Potential bug)
We noticed that overwriting a file in Recently Deleted behaves differently depending on the method used.
Current implementation
1.Create a temporary file in the same directory
2.Write content to the temporary file
3.Delete the original file ([NSFileManager removeItemAtURL:error:])
4.Move the temporary file to the original file path ([NSFileManager moveItemAtURL:toURL:error:])
Result: The file disappears from Files App Recently Deleted.
In contrast, using
[NSFileManager replaceItemAtURL:withItemAtURL:]
keeps the file visible in Recently Deleted.
Is this difference designed behavior?
If not, this may be a bug.
Question3: Detecting files in Recently Deleted
We want to detect whether a file resides in Recently Deleted, but we cannot find a reliable and officially supported method.
Recently Deleted files appear under .Trash, but using the path alone is not a reliable method.
We have tried the following APIs without success:
[NSURL getResourceValue:forKey:NSURLIsHiddenKey error:]
[NSURL checkResourceIsReachableAndReturnError:]
[NSFileManager fileExistsAtPath:]
[NSFileManager isReadableFileAtPath:]
[NSFileManager getRelationship:ofDirectory:NSTrashDirectory inDomain:NSUserDomainMask toItemAtURL:error:]
We could not obtain the Recently Deleted folder URL using standard APIs.
[NSFileManager URLsForDirectory:NSTrashDirectory inDomains:NSUserDomainMask]
[NSFileManager URLForDirectory:NSTrashDirectory inDomain:NSUserDomainMask appropriateForURL:url create:error:]
Could you advise a safe and supported way to detect Recently Deleted files properly by the app?