Hi,
I'm working on integrating iCloud Drive functionality into my app. I noticed that the folder for my app appears under /Users/USERNAME/Library/Mobile Documents/MY_CONTAINER, but it doesn't show up in iCloud Drive.
Am I missing a step in the setup or configuration? Any guidance would be appreciated!
Thanks!
Dive into the world of programming languages used for app development.
Post
Replies
Boosts
Views
Activity
Recent Incident with SDKAnalytics Version 11.11.4
We recently released version 11.11.4 of SDKAnalytics for use in the SuperApp. This update introduced several significant changes since the last generated version, 11.11.0. The previous version's primary change was the migration of the integration pipeline and its identifier from OQ6 to FW6. Additionally, we performed refactoring and adjustments to the project's configurations.
In SDKAnalytics, we use XcodeGen to simplify project setup and minimize conflicts. We also rely on CocoaPods to create and manage our Pods/Frameworks.
The SuperApp, where SDKAnalytics is implemented, operates as a centralized ecosystem. Its products and user journeys are segregated into Pods/Frameworks, distributed across multiple repositories, following a multi-repo structure. Currently, the app includes over 300 Pods.
Starting from version 11.11.1 of our SDK, we implemented some important project changes. However, when we released version 11.11.4, which included a new feature for the SuperApp, we encountered a critical issue.
Incident Overview
All SDKs implemented in the SuperApp have their loading times monitored. After updating SDKAnalytics from version 11.11.0 to 11.11.4, the loading time spiked from 200 ms to 3000 ms. Faced with this significant impact, we launched a task force to investigate and resolve the issue.
Investigation and Diagnosis
After several days of investigation, we carefully reviewed the numerous pull requests merged between versions 11.11.0 and 11.11.4. As a strategy, we reverted the project.yml configurations from version 11.11.4 to match those of version 11.11.0. This rollback resolved the loading time issue, indicating that the problem stemmed from the project's configuration.
Upon deeper analysis, we identified the culprit: a single line of configuration. The Bundle ID for the SuperApp follows the pattern com.companyname.enterprise. However, in version 11.11.4, SDKAnalytics adopted a new Bundle ID format: com.companyname.SDKAnalytics. This change directly impacted the SDKAnalytics loading time when implemented in the SuperApp.
Solution
To resolve the issue, we reverted this configuration. We modified the Bundle ID for SDKAnalytics to br.com.SDKAnalytics, removing the com.companyname prefix. After this change, the loading time returned to normal.
Reflection
The lingering question remains: What is the logical explanation for this discrepancy in loading time caused by the Bundle ID configuration? This behavior is unexpected, and we plan to investigate further to understand the underlying technical reasons.
Hi, I'm wondering about one of the properties in the MPNowPlayingInfoCenter: MPNowPlayingInfoPropertyElapsedPlaybackTime. The docs say that updating this property frequently is not required, because the system can automatically calculate elapsed playback time based on the infrequent values we provide.
Is performance harmed by updating this property every second? Should I add some filtering/throttling to update this property infrequently? Am I overthinking this, and it doesn't matter either way?
Kind regards.
I am having trouble accessing and controlling @IBOutlet variables from other ViewControllers.
More specifically, I want to control that @IBOutlet variable based on real-time changes in the variable value of another ViewController.
Control is possible in the viewcontainer that contains the @IBOutlet variable, but when trying to control it from another viewcontainer, the message "Thead1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" appears.
Is there any possible way to do it?
I think this will be difficult since thread1 in the error message means the main thread, so I tried to create a thread in the viewcontainer that has the @IBOutlet variable and access the variable of another viewcontainer to control the @IBOutlet variable inside the thread, but in this case, the variable value of the other viewcontainer that changes in real time is fixed to the value at the moment the thread is created, and the value that changes in real time after that cannot be retrieved.
And I don't think using threads for this purpose is a good way.
I sincerely ask for help from all the experts.
If I can solve this, it will be easy to create the rest of the app structure.
Sincerely !
I'm attempting to use NWConnection as a websocket given a NWEndpoint returned by NWBrowser, setup like:
let tcpOptions = NWProtocolTCP.Options()
tcpOptions.enableKeepalive = true
tcpOptions.keepaliveIdle = 2
let parameters = NWParameters(tls: nil, tcp: tcpOptions)
parameters.allowLocalEndpointReuse = true
parameters.includePeerToPeer = true
let options = NWProtocolWebSocket.Options()
options.autoReplyPing = true
options.skipHandshake = true
parameters.defaultProtocolStack.applicationProtocols.insert(options, at: 0)
self.connection = NWConnection(to: endpoint, using: parameters)
The initial connection does make it to the ready state but when I first try to send a text message over the websocket, i get
nw_read_request_report [C1] Receive failed with error "Input/output error"
nw_flow_prepare_output_frames Failing the write requests [5: Input/output error]
nw_write_request_report [C1] Send failed with error "Input/output error"
immediately, and the websocket is closed.
Send code here:
let encoder = JSONEncoder()
let dataMessage = try encoder.encode(myMessage)
let messageMetadata = NWProtocolWebSocket.Metadata(opcode: .text)
let context = NWConnection.ContentContext(identifier: "send", metadata: [messageMetadata])
connection.send(content: dataMessage, contentContext: context, completion: .contentProcessed({ error in
if let error = error {
print (error)
}
}))
What would typically cause the Input/output error when writing? Am I doing something obviously wrong or is there something else I can do to get additional debug information?
Thanks in advance for any help.
I am working on the device activity report. and fetched data is loading on the chart. I am developing app using TabbarController. when I go to another tab and come back to the chart screen, it disappears.
Here, I am working on a storyboard using Swift language, and device activity reports can be fetched only with SwiftUI. So, the problem is with it? Following the current code.
@State private var context: DeviceActivityReport.Context = .init(rawValue: "Daily Activity")
@State private var report: DeviceActivityReport?
@State private var filter = DeviceActivityFilter(
segment: .daily(
during: Calendar.current.dateInterval(
of: .day, for: .now
)!
)
// users: .all
// devices: .init([.iPhone, .iPad])
)
@State var isReload: Bool = false
var body: some View {
ZStack {
if isReload {
LoadingView(title: "Data is loading...")
} else if let report = report {
report
} else {
DeviceActivityReport(context, filter: filter)
}
}
.onAppear {
DispatchQueue.main.async {
report = DeviceActivityReport(context, filter: filter)
}
}
}
struct LoadingView: View {
var title: String = "Please wait..."
var body: some View {
HStack {
ProgressView(title)
.font(.system(size: 14, weight: .medium))
.progressViewStyle(.horizontal)
.tint(Color(.darkGray))
.padding(8)
}
.background(Color(.white))
.cornerRadius(8)
.clipped()
}
}
When I try to load the device activity report, it takes too long to load data. Is this because of development time? Will the problem be solved when the app is live on the App Store?
If it does not depend on the development profile, then please give me a solution for the fast data loading in the device activity report extension.
Thank you
I have a relatively unique project layered with file types (top to bottom) SwiftUI, Swift, Objective C, and C. The purpose of this layering is that I have a C language firmware application framework for development of firmware on custom electronic boards.
Specifically, I use the standard C preprocessor in specific ways to make data driven structures, not code. There are header files shared between the firmware project and the Xcode iPhone app to set things like the BLE protocol and communication command/reply protocols, etc. The app is forced to adhere to that defined by the firmware, rather than rely a design to get it right.
The Objective C code is mainly to utilize the Bluetooth stack provided by iOS. I specifically use this approach to allow C files to be compiled. Normally, everything has worked perfectly, but a serious and obtuse problem just surfaced a couple days ago.
My important project was created long ago. More recently, I started a new project using most of the same technology, but its project is newer. Ironically, it continues to work perfectly, but ironically the older project stopped working. (Talking about the Xcode iOS side.)
Essentially, the Objective C handling of the C preprocessor is not fully adhering to the standard C preprocessing in one project. It's very confusing because there is no code change. It seems Xcode was updated, but looks like the project was not updated, accordingly? I'm guessing there is some setting that forces Objective C to adhere to the standard C preprocessor rules.
I did see a gnu compiler version that did not get updated compared to the newer project, but updating that in the Build Settings did not fix the problem.
The error is in the title:
Token is not a valid binary operator in a preprocessor subexpression.
The offending macro appears in a header file, included in several implementation files. Compiling a single implementation files isolates the issue somewhat. An implementation with no Objective C objects compiles just fine. If there are Objective C objects then I get the errors. Both cases include the same header.
It seems like the Objective C compiler, being invoked, uses a different C preprocessor parser, rather than the standard. I guess I should mention the bridging header file where these headers exist, as well. The offending header with the problem macro appears as an error in the bridging header if a full build is initiated.
Is there an option somewhere, that forces the Objective C compiler to honor the standard C processor? Note, one project seems to.
#define BLE_SERVICE_BLANK( enumTag, uuid, serviceType )
#define BLE_CHARACTERISTIC_BLANK( enumTag, uuid, properties, readPerm, writePerm, value)
#define BLE_SERVICE_ENUM_COUNTER( enumTag, uuid, serviceType) +1
#define BLE_CHARACTERISTIC_ENUM_COUNTER( enumTag, uuid, properties, readPerm, writePerm, value) +1
#if 0 BLE_SERVICE_LIST(BLE_SERVICE_ENUM_COUNTER, BLE_CHARACTERISTIC_BLANK) > 0
#define USING_BLE_SERVICE
...
#if 0 BLE_SERVICE_LIST(BLE_SERVICE_BLANK, BLE_CHARACTERISTIC_ENUM_COUNTER) > 0
#define USING_BLE_CHARACTERISTIC
...
token is not a valid binary operator in a preprocessor subexpression
refers to the comparison. BLE_SERVICE_LIST() does a +1 for each item in the list. There is no further expansion. One counts services. The other counts characteristics. The errors are associated with the comparisons.
Hi!
I'm trying to create a target application that depends on multiple targets that all use the same Swift package that has xcframework binaryTarget. Each component can be successfully assembled individually, but when I try to create a core application that depends on these components, I get an error message on Prepare build stage:
Multiple commands produce '/Users/<USER>/Library/Developer/Xcode/DerivedData/<PROJECT_ID>/Build/Products/Debug/Frameworks/<FW_NAME>.framework/Versions/A'
Target '<COMPONENT1>' has copy command from '/Users/<USER>/Library/Developer/Xcode/DerivedData/<PROJECT_ID>/SourcePackages/artifacts/.../<FW_NAME>/<FW_NAME>.xcframework/macos-arm64_x86_64/<FW_NAME>.framework' to '/Users/<USER>/Library/Developer/Xcode/DerivedData/<PROJECT_ID>/Build/Products/Debug/Frameworks/<FW_NAME>.framework'
Target '<COMPONENT2>' has copy command from '/Users/<USER>/Library/Developer/Xcode/DerivedData/<PROJECT_ID>/SourcePackages/artifacts/.../<FW_NAME>/<FW_NAME>.xcframework/macos-arm64_x86_64/<FW_NAME>.framework' to '/Users/<USER>/Library/Developer/Xcode/DerivedData/<PROJECT_ID>/Build/Products/Debug/Frameworks/<FW_NAME>.framework'
– where <FW_NAME> is a name of the xcframework which is the binaryTarget in the Swift package.
Could someone please explain to me if it is even possible to use xcframeworks packaged in Swift packages in such cases, and if so, how to do it correctly?
Hi, I'm trying to modify the ScreenCaptureKit Sample code by implementing an actor for Metal rendering, but I'm experiencing issues with frame rendering sequence.
My app workflow is:
ScreenCapture -> createFrame -> setRenderData
Metal draw callback -> renderAsync (getData from renderData)
I've added timestamps to verify frame ordering, I also using binarySearch to insert the frame with timestamp, and while the timestamps appear to be in sequence, the actual rendering output seems out of order.
// ScreenCaptureKit sample
func createFrame(for sampleBuffer: CMSampleBuffer) async {
if let surface: IOSurface = getIOSurface(for: sampleBuffer) {
await renderer.setRenderData(surface, timeStamp: sampleBuffer.presentationTimeStamp.seconds)
}
}
class Renderer {
...
func setRenderData(surface: IOSurface, timeStamp: Double) async {
_ = await renderSemaphore.getSetBuffers(
isGet: false,
surface: surface,
timeStamp: timeStamp
)
}
func draw(in view: MTKView) {
Task {
await renderAsync(view)
}
}
func renderAsync(_ view: MTKView) async {
guard await renderSemaphore.beginRender() else { return }
guard let frame = await renderSemaphore.getSetBuffers(
isGet: true, surface: nil, timeStamp: nil
) else {
await renderSemaphore.endRender()
return }
guard let texture = await renderSemaphore.getRenderData(
device: self.device,
surface: frame.surface) else {
await renderSemaphore.endRender()
return
}
guard let commandBuffer = _commandQueue.makeCommandBuffer(),
let renderPassDescriptor = await view.currentRenderPassDescriptor,
let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
await renderSemaphore.endRender()
return
}
// Shaders ..
renderEncoder.endEncoding()
commandBuffer.addCompletedHandler() { @Sendable (_ commandBuffer)-> Swift.Void in
updateFPS()
}
// commit frame in actor
let success = await renderSemaphore.commitFrame(
timeStamp: frame.timeStamp,
commandBuffer: commandBuffer,
drawable: view.currentDrawable!
)
if !success {
print("Frame dropped due to out-of-order timestamp")
}
await renderSemaphore.endRender()
}
}
actor RenderSemaphore {
private var frameBuffers: [FrameData] = []
private var lastReadTimeStamp: Double = 0.0
private var lastCommittedTimeStamp: Double = 0
private var activeTaskCount = 0
private var activeRenderCount = 0
private let maxTasks = 3
private var textureCache: CVMetalTextureCache?
init() {
}
func initTextureCache(device: MTLDevice) {
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, device, nil, &self.textureCache)
}
func beginRender() -> Bool {
guard activeRenderCount < maxTasks else { return false }
activeRenderCount += 1
return true
}
func endRender() {
if activeRenderCount > 0 {
activeRenderCount -= 1
}
}
func setTextureLoaded(_ loaded: Bool) {
isTextureLoaded = loaded
}
func getSetBuffers(isGet: Bool, surface: IOSurface?, timeStamp: Double?) -> FrameData? {
if isGet {
if !frameBuffers.isEmpty {
let frame = frameBuffers.removeFirst()
if frame.timeStamp > lastReadTimeStamp {
lastReadTimeStamp = frame.timeStamp
print(frame.timeStamp)
return frame
}
}
return nil
} else {
// Set
let frameData = FrameData(
surface: surface!,
timeStamp: timeStamp!
)
// insert to the right position
let insertIndex = binarySearch(for: timeStamp!)
frameBuffers.insert(frameData, at: insertIndex)
return frameData
}
}
private func binarySearch(for timeStamp: Double) -> Int {
var left = 0
var right = frameBuffers.count
while left < right {
let mid = (left + right) / 2
if frameBuffers[mid].timeStamp > timeStamp {
right = mid
} else {
left = mid + 1
}
}
return left
}
// for setRenderDataNormalized
func tryEnterTask() -> Bool {
guard activeTaskCount < maxTasks else { return false }
activeTaskCount += 1
return true
}
func exitTask() {
activeTaskCount -= 1
}
func commitFrame(timeStamp: Double,
commandBuffer: MTLCommandBuffer,
drawable: MTLDrawable) async -> Bool {
guard timeStamp > lastCommittedTimeStamp else {
print("Drop frame at commit: \(timeStamp) <= \(lastCommittedTimeStamp)")
return false
}
commandBuffer.present(drawable)
commandBuffer.commit()
lastCommittedTimeStamp = timeStamp
return true
}
func getRenderData(
device: MTLDevice,
surface: IOSurface,
depthData: [Float]
) -> (MTLTexture, MTLBuffer)? {
let _textureName = "RenderData"
var px: Unmanaged<CVPixelBuffer>?
let status = CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface, nil, &px)
guard status == kCVReturnSuccess, let screenImage = px?.takeRetainedValue() else {
return nil
}
CVMetalTextureCacheFlush(textureCache!, 0)
var texture: CVMetalTexture? = nil
let width = CVPixelBufferGetWidthOfPlane(screenImage, 0)
let height = CVPixelBufferGetHeightOfPlane(screenImage, 0)
let result2 = CVMetalTextureCacheCreateTextureFromImage(
kCFAllocatorDefault,
self.textureCache!,
screenImage,
nil,
MTLPixelFormat.bgra8Unorm,
width,
height,
0, &texture)
guard result2 == kCVReturnSuccess,
let cvTexture = texture,
let mtlTexture = CVMetalTextureGetTexture(cvTexture) else {
return nil
}
mtlTexture.label = _textureName
let depthBuffer = device.makeBuffer(bytes: depthData, length: depthData.count * MemoryLayout<Float>.stride)!
return (mtlTexture, depthBuffer)
}
}
Above's my code - could someone point out what might be wrong?
When swizzling NSURLRequest initialiser and returning a mutable copy, the original instance does not get deallocated and eventually gets leaked and a crash follows after that.
Here's the swizzling setup:
static func swizzleInit() {
let initSel = NSSelectorFromString("initWithURL:cachePolicy:timeoutInterval:")
guard let initMethod = class_getInstanceMethod(NSClassFromString("NSURLRequest"), initSel) else {
return
}
let origInitImp = method_getImplementation(initMethod)
let block: @convention(block) (AnyObject, Any, NSURLRequest.CachePolicy, TimeInterval) -> NSURLRequest = { _self, url, policy, interval in
typealias OrigInit = @convention(c) (AnyObject, Selector, Any, NSURLRequest.CachePolicy, TimeInterval) -> NSURLRequest
let origFunc = unsafeBitCast(origInitImp, to: OrigInit.self)
let request = origFunc(_self, initSel, url, policy, interval)
return request.tagged()
}
let newImplementation = imp_implementationWithBlock(block as Any)
method_setImplementation(initMethod, newImplementation)
}
// create a mutable copy if needed and add a header
private func tagged() -> NSURLRequest {
guard let mutableRequest = self as? NSMutableURLRequest ?? self.mutableCopy() as? NSMutableURLRequest else {
return self
}
mutableRequest.setValue("test", forHTTPHeaderField: "test")
return mutableRequest
}
Then, we have a few test cases:
// memory leak and crash
func testSwizzleNSURLRequestInit() {
let request = NSURLRequest(url: URL(string: "https://example.com")!)
XCTAssertEqual(request.value(forHTTPHeaderField: "test"), "test")
}
// no crash, as the request is mutable, so no copy is created
func testSwizzleNSURLRequestInit2() {
let request = URLRequest(url: URL(string: "https://example.com")!)
XCTAssertEqual(request.value(forHTTPHeaderField: "test"), "test")
}
// no crash, as the request is mutable, so no copy is created
func testSwizzleNSURLRequestInit3() {
let request = NSMutableURLRequest(url: URL(string: "https://example.com")!)
XCTAssertEqual(request.value(forHTTPHeaderField: "test"), "test")
}
// no crash, as the new instance does not get deallocated
// when the test method completes (?)
var request: NSURLRequest?
func testSwizzleNSURLRequestInit4() {
request = NSURLRequest(url: URL(string: "https://example.com")!)
XCTAssertEqual(request?.value(forHTTPHeaderField: "test"), "test")
}
It appears a memory leak occurs only when any other instance except for the original one is being returned from the initialiser.
Is there a workaround to prevent the leak, while allowing for modifications of all requests?
Is there any way to use metal-cpp in a Swift project? I have a platform layer I've written in Swift that handles Window/View creation, as well as event handling, etc. I've been trying to bridge this layer with my C++ layer as you normally would using a pure C interface, but using Metal instances that cross this boundary just doesn't seem to work.
e.g. Currently I initialize a CAMetalLayer for my NSView, setting that as the layer for the view. I've tried passing this Metal layer into my C++ code via a void* pointer through a C interface, and then casting it to a CA::MetalView to be used. When this didn't work, I tried creating the CA::MetalLayer in C++ and passing that back to the Swift layer as a void* pointer, then binding it to a CAMetalLayer type. And of course, this didn't work either.
So are the options for metal-cpp to use either Objective-C or just pure C++ (using AppKit.hpp)? Or am I missing something for how to integrate with Swift?
When i create a intance of swift String :
Let str = String ("Hello")
As swift String are immutable, and when we mutate the value of these like:
str = "Hello world ......." // 200 characters
Swift should internally allocate new memory and copy the content to that buffer for update .
But when i checked the addresses of original and modified str, both are same?
Can you help me understand how this allocation and mutation working internally in swift String?
similiar to
Error when debugging: Cannot creat… | Apple Developer Forums - https://developer.apple.com/forums/thread/651375
Xcode 12 beta 1 po command in de… | Apple Developer Forums - https://developer.apple.com/forums/thread/651157
which do not resolve this issue that I am encountering
Description of problem
I am seeing an error which prevents using lldb debugger on Swift code/projects. It is seen on any Swift or SwiftUI project that I've tried. This is the error displayed in lldb console when first breakpoint is encountered:
Cannot create Swift scratch context (couldn't create a ClangImporter)(lldb)
Xcode Version 12.3 (12C33)
macOS Big Sur Intel M1
Troubleshooting
I originally thought this was also working on an Intel Mac running Big Sur/Xcode 12.3, but was mistaken. Using my customized shell environment on the following setups, I encounter the same couldn't create a ClangImporter.
M1 Mac mini, main account (an "Admin" account)
same M1 Mac mini, new "dev" account (an "Admin" account)
Intel MBP, main account
They are all using an Intel Homebrew install, and my customized shell environment if that provides a clue?
I captured some lldb debugging info by putting expr types in ~/.lldbinit but the outputs were basically identical (when discounting scratch file paaths and memory addresses) compared to the "working clean" account log (described below)
log enable -f /tmp/lldb-log.txt lldb expr types
works in a "clean" user account
I created a new, uncustomized "Standard" testuser account on the M1 Mac mini, and launched the same system Xcode.app. There was no longer this error message, and was able to inspect variables at a swift program breakpoint in Swift context, including po symbol.
Impact
Effectively this makes the debugger in Swift on Xcode projects on my systems essentially unable to inspect Swift contexts' state.
Hello,
Im developing an app entirely with C++, and I need to call various swift functions because it requires the Swift library.
Ive seen several posts on forums about C++ callbacks and honestly I dont understand how its done exactly. I get the general idea but I am not able to understand it and make it work. I feel like people throw vague ideas and weird function names and everything gets confusing.
Could anyone give me the smallest example that works please ?
Just to make sure you know what I mean, here is an example of what I want to do, but you dont have to generate the code exactly for this, I want an example that I can understand please, but the swift code has to depend on a swift library. I dont want to simply call a swift function that returns x*2 ...
{1} notif.swift file : coded in swift language
include <UserNotifications/UserNotifications.h>
function A that show notification in swift code.
{2} mainwindow.cpp file : coded in C++ language
import notif.swift ??
button connected to slot/function mybuttonclicked.
MainWindow::mybuttonclicked(){
std::string my_result = call function A_from_swift_file(argument_1);
}
--The end ---
I wrote the notif.swift with '?' because I dont know how you include the swift file from your cpp code and I could not find that anywhere. Maybe it is obvious, but I would really appreciate getting some help on this, Thank you everyone
`
init() {
nextOrder = self.AllItems.map{$0.order}.max()
if nextOrder == nil {
nextOrder = 0
}
nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
}
`
I have to say, Swift is great - when it works!
I ran into a memory issue that I don't understand why this could happen. For me, It seems like ARC doesn't guarantee thread-safety.
Let see the code below
@propertyWrapper
public struct AtomicCollection<T> {
private var value: [T]
private var lock = NSLock()
public var wrappedValue: [T] {
set {
lock.lock()
defer { lock.unlock() }
value = newValue
}
get {
lock.lock()
defer { lock.unlock() }
return value
}
}
public init(wrappedValue: [T]) {
self.value = wrappedValue
}
}
final class CollectionTest: XCTestCase {
func testExample() throws {
let rounds = 10000
let exp = expectation(description: "test")
exp.expectedFulfillmentCount = rounds
@AtomicCollection var array: [Int] = []
for i in 0..<rounds {
DispatchQueue.global().async {
array.append(i)
exp.fulfill()
}
}
wait(for: [exp])
}
}
It will crash for various reasons (see screenshots below)
I know that the test doesn't reflect typical application usage. My app is quite different from traditional app so the code above is just the simplest form for proof of the issue.
One more thing to mention here is that array.count won't be equal to 10,000 as expected (probably because of copy-on-write snapshot)
So my questions are
Is this a bug/undefined behavior/expected behavior of Swift/Obj-c ARC?
Why this could happen?
Any solutions suggest?
How do you usually deal with thread-safe collection (array, dict, set)?
I make some small program to make dots. Many of them.
I have a Generator which generates dots in a loop:
//reprat until all dots in frame
while !newDots.isEmpty {
virginDots = []
for newDot in newDots {
autoreleasepool{
virginDots.append(
contentsOf: newDot.addDots(in: size, allDots: &result, inSomeWay))
}
newDots = virginDots
}
counter += 1
print ("\(result.count) dots in \(counter) grnerations")
}
Sometimes this loop needs hours/days to finish (depend of inSomeWay settings), so it would be very nice to send partial result to a View, and/or if result is not satisfying — break this loop and start over.
My understanding of Tasks and Concurrency became worse each time I try to understand it, maybe it's my age, maybe language barier. For now, Button with {Task {...}} action doesn't removed Rainbow Wheel from my screen. Killing an app is wrong because killing is wrong.
How to deal with it?
Hello all.
This is my code snippet.
RecordListView()
.tabItem {
Label("Record List", systemImage: "list.clipboard")
}
.tag(Tab.RecordList)
When I export localizations, there is no Record List in the .xcloc file.
Then I use LocalizedStringKey for Label and export localizations file, the code is as follows:
let RecordsString:LocalizedStringKey = "Tab.Records"
RecordListView()
.tabItem {
Label(RecordsString, systemImage: "list.clipboard")
}
.tag(Tab.RecordList)
There is still no Tab.Records.
Hi,
I have a complex structure of classes, and I'm trying to migrate to swift6
For this classes I've a facade that creates the classes for me without disclosing their internals, only conforming to a known protocol
I think I've hit a hard wall in my knowledge of how the actors can exchange data between themselves. I've created a small piece of code that can trigger the error I've hit
import SwiftUI
import Observation
@globalActor
actor MyActor {
static let shared: some Actor = MyActor()
init() {
}
}
@MyActor
protocol ProtocolMyActor {
var value: String { get }
func set(value: String)
}
@MyActor
func make(value: String) -> ProtocolMyActor {
return ImplementationMyActor(value: value)
}
class ImplementationMyActor: ProtocolMyActor {
private(set) var value: String
init(value: String) {
self.value = value
}
func set(value: String) {
self.value = value
}
}
@MainActor
@Observable
class ViewObserver {
let implementation: ProtocolMyActor
var value: String
init() async {
let implementation = await make(value: "Ciao")
self.implementation = implementation
self.value = await implementation.value
}
func set(value: String) {
Task {
await implementation.set(value: value)
self.value = value
}
}
}
struct MyObservedView: View {
@State var model: ViewObserver?
var body: some View {
if let model {
Button("Loaded \(model.value)") {
model.set(value: ["A", "B", "C"].randomElement()!)
}
} else {
Text("Loading")
.task {
self.model = await ViewObserver()
}
}
}
}
The error
Non-sendable type 'any ProtocolMyActor' passed in implicitly asynchronous call to global actor 'MyActor'-isolated property 'value' cannot cross actor boundary
Occurs in the init on the line "self.value = await implementation.value"
I don't know which concurrency error happens... Yes the init is in the MainActor , but the ProtocolMyActor data can only be accessed in a MyActor queue, so no data races can happen... and each access in my ImplementationMyActor uses await, so I'm not reading or writing the object from a different actor, I just pass sendable values as parameter to a function of the object..
can anybody help me understand better this piece of concurrency problem?
Thanks