Overview

Post

Replies

Boosts

Views

Activity

How to use Map initializers Xcode15
Hello, I'm trying to learn swift and making the Landmarks tutorial I found a problem with the map view. The error read as follow: "'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:)' was deprecated in iOS 17.0: Use Map initializers that take a MapContentBuilder instead." My code is: import MapKit struct MapView: View { @State private var region = MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2) ) // The error happens here! var body: some View { Map(coordinateRegion: $region) } } #Preview { MapView() } Any suggestions about hot to solve this will be appreciate it. Thanks, BR Skalex
3
1
1.8k
Jul ’23
Sonoma slow on USB Mac Port.
Hi everyone, I have a Macbook Air M1 and the Mac runs fine. For work needs, I need to use the new Sonoma operating system on an external drive. Now here are the problems. The operating system is installed correctly so I don't think that could be the problem. It happens that if I attach the external disk to the Belkin HUB, the new operating system starts without problems, if instead I try to attach the SSD to the Macbook Air USB ports, the operating system does not start, so I am forced to use Sonoma only with the hub attached. I thought it could reset the PRAM or the SMC but from the Apple forum, it seems that Macbooks with M1 processors, have neither PRAM nor SMC. Is there anything I can do ? Thank you all, Vincent
2
1
605
Jul ’23
My loop makes a click noise each time it starts
The loop plays smoothly in audacity but when I run it in the device or simulator it clicks each loop at different intensities. I config the session at App level: let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setCategory(.playback, mode: .default, options: [.mixWithOthers]) try audioSession.setActive(true) } catch { print("Setting category session for AVAudioSession Failed") } And then I made my method on my class: func playSound(soundId: Int) { let sound = ModelData.shared.sounds[soundId] if let bundle = Bundle.main.path(forResource: sound.filename, ofType: "flac") { let backgroundMusic = NSURL(fileURLWithPath: bundle) do { audioPlayer = try AVAudioPlayer(contentsOf:backgroundMusic as URL) audioPlayer?.prepareToPlay() audioPlayer?.numberOfLoops = -1 // for infinite times audioPlayer?.play() isPlayingSounds = true } catch { print(error) } } } Does anyone have any clue? Thanks! PS: If I use AVQueuePlayer and repeat the item the click noise disappear (but its no use, because I would need to repeat it indefinitely without wasting memory), if I use AVLooper I get a silence between loops. All with the same sound. Idk :/ PS2: The same happens with ALAC files.
4
2
808
Jul ’23
Xcode 15 doesn't fix Info.plist management bugs introduced in Xcode 14
Xcode 14 introduced some ridiculous Info.plist management bugs which are not yet fixed in Xcode 15: The bugs are manifested in the General and Info tabs of target management: -The Build value in the General tab is not in sync with the CFBundleVersion value in the Info tab (that is, changing the value in the General tab won't affect the Info tab and vice versa). -The App Category value in the General tab isn't in sync with the LSApplicationCategoryType value in the Info tab. -Additional document type properties in the Info tab cannot be added: clicking "Click here to add..." doesn't do anything. -Document types in Info tab cannot be deleted: once you added a document type instance (even as a test) there's no way to remove it.
3
0
1.8k
Jul ’23
Working with a Wi-Fi Accessory
For important background information, read Extra-ordinary Networking before reading this. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Working with a Wi-Fi Accessory Building an app that works with a Wi-Fi accessory presents specific challenges. This post discusses those challenges and some recommendations for how to address them. Note While my focus here is iOS, much of the info in this post applies to all Apple platforms. IMPORTANT iOS 18, currently in beta, includes AccessorySetupKit, a new framework that can radically simplify the process of setting up an accessory. I’m not fully up to speed on that framework myself, but I encourage you to watch WWDC 2024 Session 10203 Meet AccessorySetupKit and read the framework documentation. Accessory Categories I classify Wi-Fi accessories into three different categories. A bound accessory is ultimately intended to join the user’s Wi-Fi network. It may publish its own Wi-Fi network during the setup process, but the goal of that process is to get the accessory on to the existing network. Once that’s done, your app interacts with the accessory using ordinary networking APIs. An example of a bound accessory is a Wi-Fi capable printer. A stand-alone accessory publishes a Wi-Fi network at all times. An iOS device joins that network so that your app can interact with it. The accessory never provides access to the wider Internet. An example of a stand-alone accessory is a video camera that users take with them into the field. You might want to write an app that joins the camera’s network and downloads footage from it. A gateway accessory is one that publishes a Wi-Fi network that provides access to the wider Internet. Your app might need to interact with the accessory during the setup process, but after that it’s useful as is. An example of this is a Wi-Fi to WWAN gateway. Not all accessories fall neatly into these categories. Indeed, some accessories might fit into multiple categories, or transition between categories. Still, I’ve found these categories to be helpful when discussing various accessory integration challenges. Do You Control the Firmware? The key question here is Do you control the accessory’s firmware? If so, you have a bunch of extra options that will make your life easier. If not, you have to adapt to whatever the accessory’s current firmware does. Simple Improvements If you do control the firmware, I strongly encourage you to: Support IPv6 Implement Bonjour [1] These two things are quite easy to do — most embedded platforms support them directly, so it’s just a question of turning them on — and they will make your life significantly easier: Link-local addresses are intrinsic to IPv6, and IPv6 is intrinsic to Apple platforms. If your accessory supports IPv6, you’ll always be able to communicate with it, regardless of how messed up the IPv4 configuration gets. Similarly, if you support Bonjour, you’ll always be able to find your accessory on the network. [1] Bonjour is an Apple term for three Internet standards: RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses RFC 6762 Multicast DNS RFC 6763 DNS-Based Service Discovery WAC For a bound accessory, support Wireless Accessory Configuration (WAC). This is a relatively big ask — supporting WAC requires you to join the MFi Program — but it has some huge benefits: You don’t need to write an app to configure your accessory. The user will be able to do it directly from Settings. If you do write an app, you can use the EAWiFiUnconfiguredAccessoryBrowser class to simplify your configuration process. HomeKit For a bound accessory that works in the user’s home, consider supporting HomeKit. This yields the same onboarding benefits as WAC, and many other benefits as well. Also, you can get started with the HomeKit Open Source Accessory Development Kit (ADK). Bluetooth LE If your accessory supports Bluetooth LE, think about how you can use that to improve your app’s user experience. For an example of that, see SSID Scanning, below. Claiming the Default Route, Or Not? If your accessory publishes a Wi-Fi network, a key design decision is whether to stand up enough infrastructure for an iOS device to make it the default route. IMPORTANT To learn more about how iOS makes the decision to switch the default route, see The iOS Wi-Fi Lifecycle and Network Interface Concepts. This decision has significant implications. If the accessory’s network becomes the default route, most network connections from iOS will be routed to your accessory. If it doesn’t provide a path to the wider Internet, those connections will fail. That includes connections made by your own app. Note It’s possible to get around this by forcing your network connections to run over WWAN. See Binding to an Interface in Network Interface Techniques and Running an HTTP Request over WWAN. Of course, this only works if the user has WWAN. It won’t help most iPad users, for example. OTOH, if your accessory’s network doesn’t become the default route, you’ll see other issues. iOS will not auto-join such a network so, if the user locks their device, they’ll have to manually join the network again. In my experience a lot of accessories choose to become the default route in situations where they shouldn’t. For example, a bound accessory is never going to be able to provide a path to the wider Internet so it probably shouldn’t become the default route. However, there are cases where it absolutely makes sense, the most obvious being that of a gateway accessory. Acting as a Captive Network, or Not? If your accessory becomes the default route you must then decide whether to act like a captive network or not. IMPORTANT To learn more about how iOS determines whether a network is captive, see The iOS Wi-Fi Lifecycle. For bound and stand-alone accessories, becoming a captive network is generally a bad idea. When the user joins your network, the captive network UI comes up and they have to successfully complete it to stay on the network. If they cancel out, iOS will leave the network. That makes it hard for the user to run your app while their iOS device is on your accessory’s network. In contrast, it’s more reasonable for a gateway accessory to act as a captive network. SSID Scanning Many developers think that TN3111 iOS Wi-Fi API overview is lying when it says: iOS does not have a general-purpose API for Wi-Fi scanning It is not. Many developers think that the Hotspot Helper API is a panacea that will fix all their Wi-Fi accessory integration issues, if only they could get the entitlement to use it. It will not. Note this comment in the official docs: NEHotspotHelper is only useful for hotspot integration. There are both technical and business restrictions that prevent it from being used for other tasks, such as accessory integration or Wi-Fi based location. Even if you had the entitlement you would run into these technical restrictions. The API was specifically designed to support hotspot navigation — in this context hotspots are “Wi-Fi networks where the user must interact with the network to gain access to the wider Internet” — and it does not give you access to on-demand real-time Wi-Fi scan results. Many developers look at another developer’s app, see that it’s displaying real-time Wi-Fi scan results, and think there’s some special deal with Apple that’ll make that work. There is not. In reality, Wi-Fi accessory developers have come up with a variety of creative approaches for this, including: If you have a bound accessory, you might add WAC support, which makes this whole issue go away. You might build your accessory with a barcode containing the info required to join its network, and scan that from your app. This is the premise behind the Configuring a Wi-Fi Accessory to Join the User’s Network sample code. You might configure all your accessories to have a common SSID prefix, and then take advantage of the prefix support in NEHotspotConfigurationManager. See Programmatically Joining a Network, below. You might have your app talk to your accessory via some other means, like Bluetooth LE, and have the accessory scan for Wi-Fi networks and return the results. Programmatically Joining a Network Network Extension framework has an API, NEHotspotConfigurationManager, to programmatically join a network, either temporarily or as a known network that supports auto-join. For the details, see Wi-Fi Configuration. One feature that’s particularly useful is it’s prefix support, allowing you to create a configuration that’ll join any network with a specific prefix. See the init(ssidPrefix:) initialiser for the details. For examples of how to use this API, see: Configuring a Wi-Fi Accessory to Join the User’s Network — It shows all the steps for one approach for getting a non-WAC bound accessory on to the user’s network. NEHotspotConfiguration Sample — Use this to explore the API in general. Secure Communication Users expect all network communication to be done securely. For some ideas on how to set up a secure connection to an accessory, see TLS For Accessory Developers. Revision History 2024-07-16 Added a preliminary discussion of AccessorySetupKit. 2023-10-11 Added the HomeKit section. Fixed the link in Secure Communication to point to TLS For Accessory Developers. 2023-07-23 First posted.
0
0
685
Jul ’23
Nested Composite Attribute values are not saved in the database
According the WWDC23 presentation “What’s new in Core Data”, “Composite attributes may be nested within each other”. However, in the current macOS and iOS beta builds, only single level composite attributes (without nested composite attributes) are persisted in the SQLite database. Is this still work in progress? See example project in FB12552092.
1
0
515
Jul ’23
App cannot upgrade to http/3 when running on iOS 16
My team are now testing http/3 support in our app and backend. It looks strange to me how the behaviour is different between iOS 15.7.3 and 16.x (now 16.6). It is a default URLSession config and just a regular URLRequest, with no assumesHTTP3Capable flag set. I observe the protocol in use with both collecting URLSessionTaskMetrics and the Network instrument. On 15.7.3 the 1st request is done using h2, the network subsystem caches the Alt-Svc header (per host I suppose). Several seconds pass and then when I issue the same 2nd request a new connection is established and the protocol is upgraded to h3. This is all fine and as described in the documentation or wwdc videos. However, when I take the same steps with a device running e.g. iOS 16.5.1 I see that the protocol is never upgraded to h3. Neither a longer timeout nor an app relaunch make any difference. Interestingly, on my Ventura desktop the same url is also handled differently: h3 by Chrome but always h2 by Safari. In the mobile Safari on iOS 16, I'm also always shown HTTP/2 on e.g. the cloudflare status page for QUIC. What can be the reason for such behaviour on iOS 16 and Apple platforms in general? PS. I've tried running the app with CFNETWORK_DIAGNOSTICS but found no useful log messages to clarify problems with QUIC. Is there still a way to better diagnose such a problem?
3
0
1k
Jul ’23
Interface is not propagated when using mergeable libraries
Hi! I've been dealing with mergeable libraries quite some time. However I can't achieve the following scenario: I have 2 xcframeworks A and B that are merged as part of a third xcframework called C. And my app needs to import something from A and B. As per the documentation we have to remove the references from A and B from the final app and replace it with C. If I work on the same xcodepoj it works like a charm (maybe because of caches), but if I try to compile C as a separate XCFramework and distribute it as a packed library, the app is not able to resolve the symbols to A and B classes. This C xcframework is compiled with BUILD_LIBRARY_FOR_DISTRIBUTION se to true and if I check its swiftinterface files it is not declaring the symbols from A and B. However the size of the binary seems to have A and B. Is there any way to export A and B symbols as part of C's swiftinterface? If I add @_exported, it is forcing me to declare the import of A and B wherever I use them and therefore I'm going to have duplicated symbols Thanks!
2
0
631
Aug ’23
WidgetKit complications won't update
We are migrating ClockKit complications to WidgetKit in our watch app (watchOS 9+). The migration went smoothly, UI part works just fine. However, we've hit the wall with widgets not updating when requested by the watch app. I believe we are missing something very simple and fundamental, but couldn't find what exactly so far. Advice and tips would be very welcome! 🙇‍♂️ Our implementation details: Whenever data is changed in the main app, the updated data is submitted to the watch app via WatchConnectivity framework using WCSession.default.transferCurrentComplicationUserInfo(_:). According to documentation, this method should be used to transfer complication-related data, since it will wake the watch app even if it is in the background or not opened at all. Watch app receives updated data and stores it in UserDefaults shared with Watch Widget Extension hosting WidgetKit complications via App Group. Watch app then request widget timeline reload via WidgetCenter.shared.reloadAllTimelines(). According to documentation, it reloads the timelines for all configured widgets belonging to the containing app, so it seems the appropriate way to reload WidgetKit complications. Widget Timeline Provider class in Watch Widget Extension reads updated data from shared UserDefaults and uses it to provide the updated snapshot for widget views to render. We believe our implementation logic is correct, but it doesn't work, for some reason. Widgets sometimes update when the watch app is opened, but not always. The most definitive way to force widgets to update is to switch to a different watch face, which confirms that the Widget Timeline Provider has access to properly updated data. P.S. We are aware of the daily reload budget imposed on widgets, so we use widgets reload trigger sparingly. Anyway, according to documentation, reload budget is not effective when in DEBUG mode, but widgets won't reload even in DEBUG mode. Thank you!
17
9
3.9k
Aug ’23
App version is not showing up in crash reports
Facing crashes with a deamon that I'm working with has info.plist embedded within it. It also has CFBundleVersion, CFBundleShortVersionString properties with the appropriate values. But somehow the macOS is not picking up the version while generating crash reports. Crash reports just shows ??? in the version field. Here is info plist within the binary, I'm using macOS Monterey 12.2.1
4
0
367
Aug ’23
TipKit: showing a popover tip on a SwiftUI toolbar button
Hi folks, there's currently a known issue in TipKit due to which it won't show popover tips on buttons that are inside a SwiftUI ToolbarItem. For example, if you try this code, the popover tip will not appear: ToolbarItem { Button(action: {...}) { Label("Tap here", systemImage: "gear") } .popoverTip(sampleTip) } There's an easy workaround for this issue. Just apply a style to the button. It can be any style. Some examples are bordered, borderless, plain and borderedProminent. Here's a fixed version of the above code: ToolbarItem { Button(action: {...}) { Label("Tap here", systemImage: "gear") } .buttonStyle(.plain) // Adding this line fixes the issue. .popoverTip(sampleTip) } Hope this helps anyone running into this issue.
7
7
2.8k
Aug ’23
Xcode 15 beta 7 Previews building issue
Summary When trying to display SwiftUI previews, building the previews may fail with the following error: Linking failed: linker command failed with exit code 1 (use -v to see invocation) ld: warning: search path '/Applications/Xcode.app/Contents/SharedFrameworks-iphonesimulator' not found ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found Note that may app does not use CoreAudioTypes. Observation This issue seems to occur when two conditions are met: The SwiftUI view must be located in a Swift Package Somewhere in either the View or the #Preview a type from another package has to be used. Say I have to packages one named Model-package and one named UI-Package. The UI-Package depends on the Model-Package. If I have a SwiftUI view in the UI-Package that uses a type of the Model-Package either in the View itself or in the #Preview, then the described error occurs. If I have a View in the UI-package that does not use a type of the Model-Package anywhere in its View or #Preview then the SwiftUI Preview builds and renders successful. I created a bug report: FB13033812
35
10
23k
Aug ’23
SwiftData does not work on a background Task even inside a custom ModelActor.
I have created an actor for the ModelContainer, in order to perform a data load when starting the app in the background. For this I have conformed to the ModelActor protocol and created the necessary elements, even preparing for test data. Then I create a function of type async throws to perform the database loading processes and everything works fine, in that the data is loaded and when loaded it is displayed reactively. actor Container: ModelActor { nonisolated let modelContainer: ModelContainer nonisolated let modelExecutor: ModelExecutor static let modelContainer: ModelContainer = { do { return try ModelContainer(for: Empleados.self) } catch { fatalError() } }() let context: ModelContext init(container: ModelContainer = Container.modelContainer) { self.modelContainer = container let context = ModelContext(modelContainer) self.modelExecutor = DefaultSerialModelExecutor(modelContext: context) self.context = context Task { do { try await loadData() } catch { print("Error en la carga \(error)") } } } } The problem is that, in spite of doing the load inside a Task and that there is no problem, when starting the app it stops responding the UI while loading to the user interactions. Which gives me to understand that actually the task that should be in a background thread is running somehow over the MainActor. As I have my own API that will provide the information to my app and refresh it at each startup or even send them in Batch when the internet connection is lost and comes back, I don't want the user to be continuously noticing that the app stops because it is performing a heavy process that is not really running in the background. Tested and compiled on Xcode 15 beta 7. I made a Feedback for this: FB13038621. Thanks Julio César
7
1
3.9k
Aug ’23
Passkey AutoFill - How to get AttestationObject ?
We are trying to support Passkey Management in our app with the latest iOS 17 Passkey Autofill. During this process, we have a few doubts and queries: First, we have configured the AutoFill extension for external passkey management Next we used the 'prepareInterface(forPasskeyRegistration:' delegate for passkey generation We are facing an issue on creating the attestationObject for ‘ASPasskeyRegistrationCredential’. Here, we’re not sure if we need to create the attestationObject [if so any documentation or help regarding this] or is there any API to get the attestationObject which we are missing. override func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) { let request = registrationRequest as! ASPasskeyCredentialRequest let passkeyRegistration = ASPasskeyRegistrationCredential(relyingParty: request.credentialIdentity.serviceIdentifier.identifier, clientDataHash: request.clientDataHash, credentialID: Data(UUID().uuidString.utf8), attestationObject: "????") extensionContext.completeRegistrationRequest(using: passkeyRegistration) } Even we have tried passing the hardcoded attestationObject[we used the existing attestationObject received using icloud keychain] , still we got empty ‘ClientDataJSON’ on ‘authorizationController(controller:’ delegate.
2
0
664
Sep ’23
'ID' is inaccessible due to '@_spi' protection level
When I reference the ID of a SwiftData model entity (aka PersistentIdentifier) anywhere as a type (like @State var selection: Set<SomeEntity.ID> = Set<SomeEntity.ID>()) I now get the following error: 'ID' is inaccessible due to '@_spi' protection level This never was a problem with CoreData and also not with SwiftData until the Xcode 15 RC. Does anybody know, if this is a bug or intended behaviour?
3
2
1.1k
Sep ’23