I'm unable to compile my project for UnitTests at present - get a load of Cannot Find XXXXX in Scope errors.
Anybody else getting this, or ideas of how to resolve.
I've tried cleaning the build folder, restarting Xcode, checking my unit test code file is only a member of the test target.
Code compiles for the debug and production builds.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Is there anyway to suppress the very verbose console output I am getting with MacOS Monterey and SwiftUI code? Here's a snippet of the output:
2021-07-20 09:58:18.267602+0100 BBCFTEST[19341:1880374] IMKInputSession (deactivate) CFRunLoopObserver kCFRunLoopExit (State change BEGIN) - innerRunLoopCount=1, otherInnerRunLoopDetected=0
2021-07-20 09:58:18.267637+0100 BBCFTEST[19341:1880374] IMKInputSession (deactivate) CFRunLoopObserver kCFRunLoopExit (State change END) - innerRunLoopCount=0, otherInnerRunLoopDetected=0
2021-07-20 09:58:18.270063+0100 BBCFTEST[19341:1880374] IMKInputSession (deactivate) CFRunLoopRunInMode exited, (kCFRunLoopRunStopped)
2021-07-20 09:58:18.270109+0100 BBCFTEST[19341:1880374] IMKInputSession (deactivate) CFRunLoopRunInMode (kIMKXPCPrivateRunLoopMode) ] RunLoopFinished(1)/Stopped(2) - Run result = 2, (Invocation already done = 1) (Sentinel IsZombie = 0)
2021-07-20 09:58:18.270147+0100 BBCFTEST[19341:1880374] IMKInputSession (deactivate) CFRunLoopRunInMode() LOOP DONE!
When I run my code with TSAN enabled I am getting an EXC_BAD_ACCESS exception thrown.
I am seeing the following error in debug navigator:
#0 0x0000000104becb44 in __tsan::ThreadClock::release(__tsan::DenseSlabAllocCache*, __tsan::SyncClock*) ()
The stack trace is not in my code.
Without TSAN I am seeing the following in the console:
(Fig) signalled err=-16993
Anybody seen this before?
This is under the new Beta 6 Xcode running under Ventura 13.0 Beta (22A5331f), on an M1 Mac.
Topic:
Programming Languages
SubTopic:
Swift
Tags:
Swift
Xcode Sanitizers and Runtime Issues
Concurrency
I'm trying to understand a design pattern for accessing the isolated state held in an actor type from within a SwiftUI view.
Take this naive code:
actor Model: ObservableObject {
@Published var num: Int = 0
func updateNumber(_ newNum: Int) {
self.num = newNum
}
}
struct ContentView: View {
@StateObject var model = Model()
var body: some View {
Text("\(model.num)") // <-- Compiler error: Actor-isolated property 'num' can not be referenced from the main actor
Button("Update number") {
Task.detached() {
await model.updateNumber(1)
}
}
}
}
Understandably I get the compiler error Actor-isolated property 'num' can not be referenced from the main actor when I try and access the isolated value. Yet I can't understand how to display this data in a view. I wonder if I need a ViewModel that observes the actor, and updates itself on the main thread, but get compile time error Actor-isolated property '$num' can not be referenced from a non-isolated context.
class ViewModel: ObservableObject {
let model: Model
@Published var num: Int
let cancellable: AnyCancellable
init() {
let model = Model()
self.model = model
self.num = 0
self.cancellable = model.$num // <-- compile time error `Actor-isolated property '$num' can not be referenced from a non-isolated context`
.receive(on: DispatchQueue.main)
.sink { self.num = $0 }
}
}
Secondly, imagine if this code did compile, then I would get another error when clicking the button that the interface is not being updated on the main thread...again I'm not sure how to effect this from within the actor?
How does one add Codable conformance to a class that needs to be isolated to the MainActor?
For example, the following code gives compiler errors:
@MainActor final class MyClass: Codable {
var value: Int
enum CodingKeys: String, CodingKey {
case value
}
init(from decoder: Decoder) throws { // <-- Compiler error: Initializer 'init(from:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Decodable'
let data = try decoder.container(keyedBy: CodingKeys.self)
self.value = try data.decode(Int.self, forKey: .value)
}
func encode(to encoder: Encoder) throws { // <-- Compiler error: Instance method 'encode(to:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Encodable'
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(value, forKey: .value)
}
}
I'm definitely struggling to get my head around actors and @MainActor at the moment!
I'm getting a lot of output on the console as I run a MacOS based SwiftUI app I'm developing, for example:
2021-12-08 12:40:14.439565+0000 SpDriveApp[6801:159299] [] [0x7fe6e7830820] CVCGDisplayLink::setCurrentDisplay: 1892262333
2021-12-08 12:40:14.439785+0000 SpDriveApp[6801:159299] [] [0x7fe6e7830800] CVDisplayLinkCreateWithCGDisplays count: 1 [displayID[0]: 0x70c9a1bd] [CVCGDisplayLink: 0x7fe6e7830820]
2021-12-08 12:40:14.439827+0000 SpDriveApp[6801:159299] [] [0x7fe6e7830800] CVDisplayLinkStart
2021-12-08 12:40:14.439853+0000 SpDriveApp[6801:159299] [] [0x7fe6e7830820] CVDisplayLink::start
2021-12-08 12:40:14.439993+0000 SpDriveApp[6801:182706] [] [0x60000f698460] CVXTime::reset
Has anyone else seen this? Have I accidentally switched on a diagnostic tool, or is there something else I am doing wrong?
I'm developing across two Macs: one Apple Silicon and an Intel laptop (used for performance and compatibility testing).
I've been testing my StoreKit2 implementation, and have come across a couple of issues.
From time to time something appears to become corrupted, and StoreKit2 says it has a 'connection' issue. Deleting the folder com.apple.storekitagent, which a sub folder Octane, restarting the machine appears to fix this.
The second issue I cannot appear to resolve. I have needed to change the App Bundle ID. I did this whilst developing on the M2 Mac without problem. But now when I try and run back on the Intel Mac I am getting a set of unfinished transactions which I can either process, nor delete (they are not appearing in Xcode's StoreKit debug window. I've tried deleting the folder com.apple.storekitagent, and restarting the machine, but to no avail.
Note if I reset back to my original App Bundle ID then all works as before.
Here is a sample of errors I am receiving:
Error finishing transaction 110: Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x600001863cf0 {Error Domain=AMSErrorDomain Code=301 "Invalid Status Code" UserInfo={NSLocalizedDescription=Invalid Status Code, AMSURL=http://localhost:49242/WebObjects/MZFinance.woa/wa/inAppTransactionDone?REDACTED, AMSStatusCode=404, AMSServerPayload={
error = "Transaction not found";
}, NSLocalizedFailureReason=The response has an invalid status code}}, storefront-country-code=USA, client-environment-type=XcodeTest(file:///Users/peggers/Library/Caches/com.apple.storekitagent/Octane/com.bristolbaycodefactory.photo-organista/), AMSServerErrorCode=0, NSLocalizedFailureReason=An unknown error occurred, NSLocalizedDescription=Unhandled exception}
Any further ideas on how to reset or solve this issue?
I am unable to get VisionOS 2.0 (simulator) to receive the GCControllerDidConnect notification and thus am unable to setup support for a gamepad. However, it works in VisionOS 1.2.
For VisionOS 2.0 I've tried adding:
.handlesGameControllerEvents(matching: .gamepad) attribute to the view
Supports Controller User Interaction to Info.plist
Supported game controller types -> Extended Gamepad to Info.plist
...but the notification still doesn't fire. It does when the code is run from VisionOS 1.2 simulator, both of which have the Send Game Controller To Device option enabled.
Here is the example code. It's based on the Xcode project template. The only files updated were ImmersiveView.swift and Info.plist, as detailed above:
import SwiftUI
import GameController
import RealityKit
import RealityKitContent
struct ImmersiveView: View {
var body: some View {
RealityView { content in
// Add the initial RealityKit content
if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
content.add(immersiveContentEntity)
}
NotificationCenter.default.addObserver(
forName: NSNotification.Name.GCControllerDidConnect,
object: nil, queue: nil) { _ in
print("Handling GCControllerDidConnect notification")
}
}
.modify {
if #available(visionOS 2.0, *) {
$0.handlesGameControllerEvents(matching: .gamepad)
} else {
$0
}
}
}
}
extension View {
func modify<T: View>(@ViewBuilder _ modifier: (Self) -> T) -> some View {
return modifier(self)
}
}
Hello,
I am trying to use the subdivision mesh rendering option.
I can see it working in RealityComposerPro:
But not when loading asset and displaying in Simulator:
Using this code:
import SwiftUI
import RealityKit
import RealityKitContent
struct AirspaceView: View {
// MARK: - VIEW BODY
var body: some View {
RealityView { content in
if let a = try? await Entity(named: "Models/Test/Test.usdc", in: realityKitContentBundle) {
content.add(a)
}
}
}
}
Any ideas why?
When using a TextField with axis to set to .vertical on iOS, it sets a bound selection parameter to an erroneous value. Whilst on MacOS it performs as expected.
Take the following code:
import SwiftUI
@main
struct SelectionTestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@FocusState private var isFocused: Bool
@State private var text = ""
@State private var textSelection: TextSelection? = nil
var body: some View {
TextField("Label", text: $text, selection: $textSelection, axis: .vertical)
.onChange(of: textSelection, initial: true) {
if let textSelection {
print("textSelection = \(textSelection)")
} else {
print("textSelection = nil")
}
}
.focused($isFocused)
.task {
isFocused = true
}
}
}
Running this on MacOS target gives the following on the console:
textSelection = nil
textSelection = TextSelection(indices: SwiftUI.TextSelection.Indices.selection(Range(0[any]..<0[any])), affinity: SwiftUI.TextSelectionAffinity.downstream)
Running the code on iOS gives:
textSelection = TextSelection(indices: SwiftUI.TextSelection.Indices.selection(Range(1[any]..<1[any])), affinity: SwiftUI.TextSelectionAffinity.upstream)
textSelection = TextSelection(indices: SwiftUI.TextSelection.Indices.selection(Range(1[any]..<1[any])), affinity: SwiftUI.TextSelectionAffinity.upstream)
Note here the range is 1..<1 - which is incorrect.
Also of side interest this behaviour changes if you remove the axis parameter:
textSelection = nil
Am I missing something, or is this a bug?
Given that type UUID is a struct I thought it would be Sendable. But the compiler generates a warning:
struct S: Sendable {
var int: Int
var id: UUID // <-- Stored property 'id' of 'Sendable'-conforming struct 'S' has non-sendable type 'UUID'
}
I'm writing a function where a directory and its descendants are scanned to produce a list of files. The function is part of a class, FileScanner. Here's a simplified version of the function:
func scanFolder(_ folderURL: URL) async {
// Set up configuration for directory search, varies based on need to search sub directories
let resourceKeysArray: [URLResourceKey] = [.nameKey, .isDirectoryKey, .fileResourceTypeKey, .creationDateKey, .contentModificationDateKey, .contentTypeKey]
let resourceKeysSet = Set<URLResourceKey>(resourceKeysArray)
let options = FileManager.DirectoryEnumerationOptions(arrayLiteral: [.skipsHiddenFiles, .skipsPackageDescendants])
if let enumerator = FileManager.default.enumerator(at: folderURL, includingPropertiesForKeys: resourceKeysArray, options: options) {
await folderScanStatus.markRunning()
while
await !folderScanStatus.cancelled,
let fileURL = enumerator.nextObject() as? URL
{
print("\(id) found \(fileURL.path)") // Logging for debug purposes
foundFiles.append(fileURL)
}
}
}
The code is async, as it has to call some async functions (I've left a couple in for illustration.)
The user can have multiple scans in process simultaneously. For each one a new FileScanner is created, and de-inited once the scan has completed - the results are copied across elsewhere. scanFolder is called from within a Task:
Task { await scanFolder(someURL) }
I am finding that if two of these processes run at once, they can actually interfere with each other - i.e. one can scan the directory of the other.
I added some logging to highlight the issue. The log line shows the ID of the scanner, and the file it has found. In this run there were two scanners:
EDF43558-608E-47A4-81E5-97B9707B1D0F, scanning /Volumes/Back-up A/
982EC712-D79E-4785-A1BA-3B53F85967F0, scanning /Users/TEST/
And here's some extracts from the log showing them working as expected:
982EC712-D79E-4785-A1BA-3B53F85967F0 found /Users/TEST/Files/R_24_04-04.txt
EDF43558-608E-47A4-81E5-97B9707B1D0F found /Volumes/Back-up A/180704f01.txt
And here's an example showing Scanner 982EC712-D79E-4785-A1BA-3B53F85967F0 finding a file that the other one also picked up:
982EC712-D79E-4785-A1BA-3B53F85967F0 found /Volumes/Back-up A/19839f92.txt
:
EDF43558-608E-47A4-81E5-97B9707B1D0F found /Volumes/Back-up A/19839f92.txt
Any ideas why this is happening? I was under the impression FileManager was thread safe?
I'm trying to detect when two entities collide. The following code shows a very basic set-up. How do I get the upperSphere to move? If I set its physicsBody.mode to .dynamic it moves with gravity (and the collision is reported), but when in kinematic mode it doesn't respond to the impulse:
struct CollisionView: View {
@State var subscriptions: [EventSubscription] = []
var body: some View {
RealityView { content in
let upperSphere = ModelEntity(mesh: .generateSphere(radius: 0.04))
let lowerSphere = ModelEntity(mesh: .generateSphere(radius: 0.04))
upperSphere.position = [0, 2, -2]
upperSphere.physicsBody = .init()
upperSphere.physicsBody?.mode = .kinematic
upperSphere.physicsMotion = PhysicsMotionComponent()
upperSphere.generateCollisionShapes(recursive: false)
lowerSphere.position = [0, 1, -2]
lowerSphere.physicsBody = .init()
lowerSphere.physicsBody?.mode = .static
lowerSphere.generateCollisionShapes(recursive: false)
let sub = content.subscribe(to: CollisionEvents.Began.self, on: nil) { _ in print("Collision!") }
subscriptions.append(sub)
content.add(upperSphere)
content.add(lowerSphere)
Task {
try? await Task.sleep(for: .seconds(2))
print("Impulse applied")
upperSphere.applyLinearImpulse([0, -1, 0], relativeTo: nil)
}
}
}
}
Topic:
Graphics & Games
SubTopic:
RealityKit
Hello,
In the documentation for an ARView we see a diagram that shows that all Entity's are connected via AnchorEntity's to the Scene:
https://developer.apple.com/documentation/realitykit/arview
What happens when we are using a RealityView? Here the documentation suggests we direclty add Entity's:
https://developer.apple.com/documentation/realitykit/realityview/
Three questions:
Do we need to add Entitys to an AnchorEntity first and add this via content.add(...)?
Is an Entity ignored by physics engine if attached via an Anchor?
If both the AnchorEntity and an attached Entity is added via content.add(...), does is its anchor's position ignored?
Does anyone have experience of creating their own EntityActions?
Say for example I wanted one that faded up the opacity of an entity, then once it had completed set another property on one of the entity's components.
I understand that I could use the FromToByAction to control the opacity (and have this working), but I am interested to learn how to create my own dedicated EntityAction, and finding the documentation hard to fathom.
I got as far as creating a struct conforming to EntityAction protocol:
var animatedValueType: (any AnimatableData.Type)?
}
Subscribing to update events on this:
FadeUpAction.subscribe(to: .updated) { event in
guard let animationState = event.animationState else {
return
}
// My animation state is always nil, so I never get here!
let newValue = \\\Some Calc...
animationState.storeAnimatedValue(newValue)
}
And setting it up as an animation on an entity:
let action = FadeUpAction()
if let animation = try? AnimationResource.makeActionAnimation(
for:action,
duration: 2.0,
bindTarget: .opacity
) {
entity.playAnimation(animation)
}
...but haven't been able to understand how to extract the current timeDelta or set the value in the event handler.
Any pointers?