I have enabled runtime concurrency warnings to check for future problems concerning concurrency: Build Setting / Other Swift Flags:
-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks
When trying to call the async form of PHPhotoLibrary.shared().performChanges{} I get the following runtime warning: warning: data race detected: @MainActor function at ... was not called on the main thread in the line containing performChanges.
My sample code inside a default Xcode multi platform app template is as follows:
import SwiftUI
import Photos
@MainActor
class FotoChanger{
func addFotos() async throws{
await PHPhotoLibrary.requestAuthorization(for: .addOnly)
try! await PHPhotoLibrary.shared().performChanges{
let data = NSDataAsset(name: "Swift")!.data
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, data: data, options: PHAssetResourceCreationOptions())
}
}
}
struct ContentView: View {
var body: some View {
ProgressView()
.task{
try! await FotoChanger().addFotos()
}
}
}
You would have to have a Swift data asset inside the asset catalog to run the above code, but the error can even be recreated if the data is invalid.
But what am I doing wrong? I have not found a way to run perform changes, the block or whatever causes the error on the main thread.
PS: This is only test code to show the problem, don't mind the forced unwraps.
Post
Replies
Boosts
Views
Activity
In my app I try to use SwiftUI's ShareLink to offer sharing of the app's documents.
I followed this video for defining the exported type and the document type.
Unfortunately if I use any ShareLink initializer for sharing Transferable items, the option "save to files" is not offered on the displayed share sheet. (Only "copy" is offered, which works if pasted into the destination directory using the Files app, but that is not an acceptable workaround).
PS: com.example.transferabletestis defined as conforming to com.apple.package
import SwiftUI
import UniformTypeIdentifiers
extension UTType{
static let transferableTest = UTType(exportedAs: "com.example.transferabletest")
}
struct Document:Transferable{
static let filePackageURL = URL.documentsDirectory.appending(components: "0815.transferabletest")
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: .transferableTest) { document in
_ = try? FileManager.default.createDirectory(at: Self.filePackageURL, withIntermediateDirectories: false)
FileManager.default.createFile(atPath: Self.filePackageURL.appending(components: "data").path(), contents: "Transferable Test\n".data(using: .utf8))
return SentTransferredFile(Document.filePackageURL)
}
}
}
struct ContentView: View {
var body: some View {
ShareLink("Share as tranferable item", item: Document(), preview: SharePreview("Test"))
}
}
Is this a bug?
What am I doing wrong?
Sharing the document using the ShareLink for URLs does offer "save to files" but I can't use that in my app for various reasons.
Consider the following sample code:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack{ TabView{ }
.navigationTitle("Titel")
.navigationBarTitleDisplayMode(.inline)
.toolbar{
ToolbarItemGroup(placement: .topBarTrailing){
TextField("Test2", text: .constant("Test2")).textFieldStyle(.roundedBorder)
Image(systemName: "1.circle")
Image(systemName: "2.circle")
Image(systemName: "3.circle")
}
}
}
}
}
This yields a different (wrong) result since iPadOS 17.4. See attached Images. Even Apps compiled with Xcode 15.2 and run on a device using iPadOS 17.4 beta are suddenly affected!
All my experiments to get the old behaviour back were unsuccessful. Does anyone know a way?
Since Swift Playgrounds was able to submit Apps to the AppStore ,Apple stated that it can be used to develop apps without having to use Xcode.
But if you do so you are lost:
The Testflight beta versions of Swift Playgrounds with API support for iOS 17 and macOS 14 have expired one week before the new systems become/became available and there is still no final version!
If you used Playgrounds to develop an iOS 17 ready version of your app you can't do anything now and that at a time where the users get their hands on the new OS.
That is really bad.
The following code is shown on apples documentation page for SwiftUI MagnificationGesture:
struct MagnificationGestureView: View {
@GestureState var magnifyBy = CGFloat(1.0)
var magnification: some Gesture {
MagnificationGesture()
.updating($magnifyBy) { currentState, gestureState, transaction in
gestureState = currentState
}
}
var body: some View {
Circle()
.frame(width: 100 * magnifyBy,
height: 100 * magnifyBy,
alignment: .center)
.gesture(magnification)
}
}
Try it (on device) in the Swift Playgrounds App by prepending
import SwiftUI
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.setLiveView(MagnificationGestureView())
or as a compiled app using the app template in Xcode and try to scale the circle to different sizes in succession.
On iPadOS 14 everything works as expected, but since iPadOS 15 Beta 2 it hangs after a few movements of the fingers.
Does it work for you?
What am I doing wrong? I already filed feedback, but the problem remains till the current beta version and I don't know how to get the gestures working again?
The following code inside an newly created iOS App project results in the following warning:
Non-sendable type 'Notification?' returned by call from main actor-isolated context to non-isolated instance method 'next()' cannot cross actor boundary
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
.task{
for await _ in NotificationCenter.default.notifications(named: UIDevice.orientationDidChangeNotification){
print("orientation changed")
}
}
}
}
What is the correct way to handle this or is it an API error?
Isn't NotificationCenter.default.notifications(named: ...) exactly meant to be used with for ... await aka. next()?
For evaluation of physical phenomena recorded on video we need to know the exact timestamps of the recorded frames and stepping frame by frame.Converting from frame number to timestamp using the framerate did not work because in many videos recorded with iOS cameras the frame rate slightly jitters. Using seekToTime and equivalent methods therefore caused skipping oder doubling of frames.How is it possible to get the exact time(stamps) of every frame in a video using AVFoundation and stepping/seeking through a video on per-frame basis?AVPlayerItem seems to be the only way I found so far to step on per-frame basis, but is it the right choice?Is there any other method?
Create a new App project in Playgrounds 4 and paste the following code into a new swift file or inside the MyApp file:
import CoreBluetooth
class BTDelegate:NSObject, CBPeripheralDelegate{
public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?){
}
public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
}
}
This causes the following error to appear:
Method 'preview__peripheral(:didUpdateValueFor:error:)' withObjective-C selector '_preview__peripheral:didUpdateValueFor:error:' conflicts with previous declaration with the same Objective-C selector
Obviously some Playgrounds preview magic can't handle methods with the same name, but different type signature.
Unfortunately I can't rename the methods because they are part of the CBPeripheralDelegate protocol.
Does anyone know a way to solve this problem?
Hi,
I tried to create a swift package using xCode's „Swift Package“ template and tried to write some tests.
Unfortunately because my package is all about Bluetooth, the test binary fails with the following message;
xctest[9145:288236] [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothAlwaysUsageDescription key with a string value explaining to the user how the app uses this data.
But how to add this key in a Swift Package?
Is it really impossible to write and run test cases for a Swift Package containing Bluetooth? I must miss something...
I'm using Swift Playgrounds 4 to develop a test app containing some network code. Unfortunately Playgrounds runs the whole app code multiple times, at least two times: Once for the preview and once when you press "play".
This causes multiple instances of the network code to be running and makes testing very hard.
Is there a way to check if the code is running in preview?
Unfortunately the usual suggested solution using ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] does not work, because this results in "1" in both cases.
The Archive Framework implements compression algorithms and supports for example the LZMA compression format.
Unfortunately I was not able to find a way to generate a ZIP-kompatible archive using the Archive Framework though iOS / iPadOS seems to be able to do that, because the Files app and the Shortcuts app support this kind of compression.
Is there a way on iOS/iPadOS to generate an LZMA compressed archive with ZIP container using only apple provided APIs or other system services?
PS: I don't need full support for all possible ZIP features. I only need to create a simple archive containing some files which can be opened using any zip decompression program.
https://developer.apple.com/documentation/accelerate/compressing_file_system_directories