I was just comparing the build settings of two of my apps to try to understand why they behave differently (one of them uses the full screen on iPad, and the other one has small top and bottom black borders, although that's not the issue I want to discuss now). I saw that the option CLANG_CXX_LANGUAGE_STANDARD is set to gnu++0x for the older project, while it's set to gnu++17 for the newer one. The documentation lists different possible values and also a default one:
Compiler Default: Tells the compiler to use its default C++ language dialect. This is normally the best choice unless you have specific needs. (Currently equivalent to GNU++98.)
If it really is the best choice (normally), why is it not used when creating a new default Xcode project? Or is it better to select a newer compiler version (GNU++98 sounds quite old compared to GNU++17)? Also, does this affect Swift code?
Post
Replies
Boosts
Views
Activity
This crash report for one of my apps was downloaded by Xcode. Apparently the app crashed while releasing an object of type Scan.File, which is a Swift class held in an array in the Scan.Directory class. I'm not doing any manual reference counting or low-level stuff with that object.
What could cause such a crash?
crash.crash
On macOS, the Finder allows to connect to a server and store the login credentials. When creating a bookmark to a file on a server and resolving it again, the server is mounted automatically (unless I provide the option URL.BookmarkResolutionOptions.withoutMounting).
I just tried connecting to my Mac from my iPad via SMB in the Files app and storing a bookmark to a file on the server, but disconnecting the server and trying to resolve the bookmark throws the error (I translated the English text from Italian):
Error Domain=NSFileProviderErrorDomain Code=-2001 "No file provider was found with the identifier "com.apple.SMBClientProvider.FileProvider"'" UserInfo={NSLocalizedDescription=No file provider was found with the identifier "com.apple.SMBClientProvider.FileProvider"., NSUnderlyingError=0x302a1a340 {Error Domain=NSFileProviderErrorDomain Code=-2013 "(null) "}}
Every time I disconnect and reconnect to the server, selecting the same file returns a different path. The first time I got
/private/var/mobile/Library/LiveFiles/com.apple.filesystems.smbclientd/WtFD3Ausername/path/to/file.txt
The next time WtFD3A changed to EqHc2g and so on.
Is it not possible to automatically mount a server when resolving a bookmark on iOS?
The following code allows to reproduce the issue:
struct ContentView: View {
@State private var isPresentingFilePicker = false
@AppStorage("bookmarkData") private var bookmarkData: Data?
@State private var url: URL?
@State private var stale = false
@State private var error: Error?
var body: some View {
VStack {
Button("Open") {
isPresentingFilePicker = true
}
if let url = url {
Text(url.path)
} else if bookmarkData != nil {
Text("couldn't resolve bookmark data")
} else {
Text("no bookmark data")
}
if stale {
Text("bookmark is stale")
}
if let error = error {
Text("\(error)")
.foregroundStyle(.red)
}
}
.padding()
.fileImporter(isPresented: $isPresentingFilePicker, allowedContentTypes: [.data]) { result in
do {
let url = try result.get()
if url.startAccessingSecurityScopedResource() {
bookmarkData = try url.bookmarkData()
}
} catch {
self.error = error
}
}
.onChange(of: bookmarkData, initial: true) { _, bookmarkData in
if let bookmarkData = bookmarkData {
do {
url = try URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &stale)
} catch {
self.error = error
}
}
}
}
}
On macOS, we have didMountNotification but there doesn't seem to be an equivalent for iOS. Is there a way to be notified when a volume is mounted on iOS? I would like to use it in my iOS app I'm currently porting from macOS, which starts a synchronization from the volume (which has been previously selected in a NSOpenPanel) as soon as it's mounted.
Some time ago I read somewhere that one can get a file icon on iOS like this:
UIDocumentInteractionController(url: url).icons.last!)
but this always returns the following image for every file:
Today I tried the following, which always returns nil:
(try? url.resourceValues(forKeys: [.effectiveIconKey]))?.allValues[.effectiveIconKey] as? UIImage
Is there any way to get a file icon on iOS?
You can try the above methods in this sample app:
struct ContentView: View {
@State private var isPresentingFilePicker = false
@State private var url: URL?
var body: some View {
VStack {
Button("Open") {
isPresentingFilePicker = true
}
if let url = url {
Image(uiImage: UIDocumentInteractionController(url: url).icons.last!)
if let image = (try? url.resourceValues(forKeys: [.effectiveIconKey]))?.allValues[.effectiveIconKey] as? UIImage {
Image(uiImage: image)
} else {
Text("none")
}
}
}
.padding()
.fileImporter(isPresented: $isPresentingFilePicker, allowedContentTypes: [.data]) { result in
do {
let url = try result.get()
if url.startAccessingSecurityScopedResource() {
self.url = url
}
} catch {
preconditionFailure(error.localizedDescription)
}
}
}
}
The following code works when compiling for macOS:
print(NSMutableDictionary().isEqual(to: NSMutableDictionary()))
but produces a compiler error when compiling for iOS:
'NSMutableDictionary' is not convertible to '[AnyHashable : Any]'
NSDictionary.isEqual(to:) has the same signature on macOS and iOS. Why does this happen? Can I use NSDictionary.isEqual(_:) instead?
All the threads only contain system calls. The crashed thread only contains a single call to my app's code which is main.swift:12.
What could cause such a crash?
crash.txt
I used to be able to see how many TSIs are still available for the membership year on the developer website, but now I cannot find it anymore.
Is it still 2 per year, or has it been recently changed to unlimited per year?
Every now and then I get this very frustrating message on Feedback Assistant.
For instance, in FB14696726 I reported an issue with the App Store Connect API. 4 weeks later, I got a reply, asking among other things for a „correlation key and Charles log“. I immediately replied saying that I didn‘t know what those are, and they replied
After reviewing your feedback, it is unclear what the exact issue is.
I pointed out that I had asked a question which was left unanswered, and they replied explaining what the correlation key is. Then I asked again what the Charles log is. They replied
The Apple Developer website provides access to a range of videos covering various topics on using and developing with Apple technologies. You can find these videos on our Development Videos page: http://developer.apple.com/videos.
I opened the link and searched for „Charles“ but there were no results, so I asked to kindly point me to the video answering my question. They replied 3 months later (today):
Following up on our last message, we believe this issue is either resolved or not reproducible with the information provided and will now consider this report closed internally. This Feedback will no longer be monitored, and incoming messages will not be reviewed.
This is not the first time I ask for clarification and get back a message basically telling me that „we won‘t answer any questions you may have and won‘t hear anything you still may have to say about this issue“. They didn‘t even ask me to verify if the issue is resolved or not, like they sometimes do. No, they just shut the door in my face.
I just wanted to share this frustrating experience. Perhaps an Apple engineer wants to say something about it or a developer has had a similar experience?
I would like to implement zoom functionality in my SceneKit game: when the user performs the pinch gesture on a point on the screen, the scene zooms in to make that point larger.
Until now I simply changed SCNCamera.focalLength, but this simply zooms in to the center of what is currently visible on screen. Is it somehow possible to implement the zoom functionality described above by perhaps interactively rotating the camera at the same time towards the pinched point? Is there a formula for this? I would like to avoid suddenly rotating the camera to face the pinched point when the pinch gesture begins and then zoom in while the pinch is in progress.
I have a very basic App Intent extension in my macOS app that does nothing than accepting two parameters, but running it in Shortcuts always produces the error "The action “Compare” could not run because an internal error occurred.".
What am I doing wrong?
struct CompareIntent: AppIntent {
static let title = LocalizedStringResource("intent.compare.title")
static let description = IntentDescription("intent.compare.description")
static let openAppWhenRun = true
@Parameter(title: "intent.compare.parameter.original")
var original: String
@Parameter(title: "intent.compare.parameter.modified")
var modified: String
func perform() async throws -> some IntentResult {
return .result()
}
}
The Verify the behavior of your intent in Simulator or on-device documentation says that it's sufficient to build and run the app and open the Shortcuts app to test an app intent, but that doesn't seem to be the case. I always needed to at least move the debugged app to the Applications folder before the app intents showed up in Shortcuts, and even then, most of the times I also need to wait a lot or restart the Mac. When updating an existing app intent (for instance by changing its title), building the app, overwriting the existing one in the Applications folder and restarting Shortcuts is not sufficient to make the new title appear in Shortcuts.
Is there an efficient way to test app intents in the Shortcuts app? I already created FB15638502 one month ago but got no response.
I rarely use the Shortcuts app, so it took me a while to notice that my app's app intents all show incorrectly on macOS 15. On macOS 14 and 13, they used to show correctly, but now it seems that all localized strings show the key rather than the localized value.
@available(iOS 16.0, macOS 13.0, *)
struct MyAppIntent: AppIntent {
static let title = LocalizedStringResource("key1", comment: "")
static let description = IntentDescription(LocalizedStringResource("key2", comment: ""))
...
}
In Localizable.xcstrings file I have defined all the strings, for instance I have associated key1 with the value Title, but while the Shortcuts app used to display Title, it now displays key1.
Is this a known issue or did something change in macOS 15 that would require me to update something?
When running the sample code below, every 3 seconds the middle sprite is replaced by a new one. When this happens, most of the time a flicker is noticeable. When recording the screen and stepping through the recording frame by frame, I noticed that the flicker is caused by a temporary reordering of the nodes’. Below you find two screenshots of two consecutive frames where the reordering is clearly visible.
This only happens for a SpriteKit scene used as an overlay for a SceneKit scene. Commenting out
buttons.zPosition = 1
or avoiding the fade in/out animations solves the issue.
I have created FB15945016.
import SceneKit
import SpriteKit
class GameViewController: NSViewController {
let overlay = SKScene()
var buttons: SKNode!
var previousButton: SKSpriteNode!
var nextButton: SKSpriteNode!
var pageContainer: SKNode!
var pageViews = [SKNode]()
var page = 0
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene(named: "art.scnassets/ship.scn")!
let scnView = self.view as! SCNView
scnView.scene = scene
overlay.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scnView.overlaySKScene = overlay
buttons = SKNode()
buttons.zPosition = 1
overlay.addChild(buttons)
previousButton = SKSpriteNode(systemImage: "arrow.uturn.backward.circle")
previousButton.position = CGPoint(x: -100, y: 0)
buttons.addChild(previousButton)
nextButton = SKSpriteNode(systemImage: "arrow.uturn.forward.circle")
nextButton.position = CGPoint(x: 100, y: 0)
buttons.addChild(nextButton)
pageContainer = SKNode()
pageViews = [SKSpriteNode(systemImage: "square.and.arrow.up"), SKSpriteNode(systemImage: "eraser")]
overlay.addChild(pageContainer)
setPage(0)
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { [self] _ in
setPage((page + 1) % 2)
}
}
func setPage(_ page: Int) {
pageViews[self.page].run(.sequence([
.fadeOut(withDuration: 0.2),
.removeFromParent()
]), withKey: "fade")
self.page = page
let pageView = pageViews[page]
pageView.alpha = 0
pageView.run(.fadeIn(withDuration: 0.2), withKey: "fade")
pageContainer.addChild(pageView)
}
override func viewDidLayout() {
overlay.size = view.frame.size
}
}
extension SKSpriteNode {
public convenience init(systemImage: String) {
self.init()
let width = 100.0
let image = NSImage(systemSymbolName: systemImage, accessibilityDescription: nil)!.withSymbolConfiguration(.init(hierarchicalColor: NSColor.black))!
let scale = NSScreen.main!.backingScaleFactor
image.size = CGSize(width: width * scale, height: width / image.size.width * image.size.height * scale)
texture = SKTexture(image: image)
size = CGSize(width: width, height: width / image.size.width * image.size.height)
}
}
I was able to confirm with a customer of mine that calling copyfile with a source file that is a symbolic link on a NTFS partition always causes the error
NSPOSIXErrorDomain 12 Cannot allocate memory
They use NTFS drivers from Paragon.
They tried copying a symbolic link from NTFS to both APFS and NTFS with the same result. Is this an issue with macOS, or with the NTFS driver?
Copying regular files on the other hand always works. Copying manually from the Finder also seems to always work, both with regular files and symbolic links, so I'm wondering how the Finder does it.
Here is the sample app that they used to reproduce the issue. The first open panel allows to select the source directory and the second one the destination directory. The variable filename holds the name of the symbolic link to be copied from the source to the destination. Apparently it's not possible to select a symbolic link directly in NSOpenPanel, as it always resolves to the linked file.
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.runModal()
let filename = "Modules"
let source = openPanel.urls[0].appendingPathComponent(filename)
openPanel.runModal()
let destination = openPanel.urls[0].appendingPathComponent(filename)
do {
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))
}
if copyfile_state_set(state, UInt32(COPYFILE_STATE_STATUS_CB), unsafeBitCast(copyfileCallback, to: UnsafeRawPointer.self)) != 0 || copyfile_state_set(state, UInt32(COPYFILE_STATE_STATUS_CTX), unsafeBitCast(self, to: UnsafeRawPointer.self)) != 0 || copyfile(source.path, destination.path, state, copyfile_flags_t(COPYFILE_NOFOLLOW)) != 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
} catch {
let error = error as NSError
let alert = NSAlert()
alert.messageText = "\(error.localizedDescription)\n\(error.domain) \(error.code)"
alert.runModal()
}
}
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
}
var size: off_t = 0
copyfile_state_get(state, UInt32(COPYFILE_STATE_COPIED), &size)
}
return COPYFILE_CONTINUE
}
}