Post

Replies

Boosts

Views

Activity

Reply to Metrickit does not send reports iOS 15
I reverse-engineered MetricKit to get to the bottom of this. The short version is that in practice there is a "probationary period" before you get your first MXDiagnosticPayload. I suspect this is some confusion on MetricKit's part about what payloads are delivered in realtime vs what are on a 24-hour basis, but it could also be a feature. To reproduce the "not delivered" behavior, install an app with a new bundle ID never seen before, it won't get crash reports. To reproduce the "delivered in real-time behavior", charge the device to 100%, reboot it while plugged in, and leave it locked on your desk for 15 minutes, crash reports occurring after that will be delivered in real time. Behind the scenes, failed crash deliveries will log statements like default 05:37:23.812310-0500 ReportCrash [bundle id] is not a MetricKit client This is true even though, when calling MXMetricManager.shared.add(subscriber), metrickitd logs that you are a client. The discrepancy seems to happen because some step inbetween these processes is disintermediated by duet scheduler (dasd). duet considers factors like "is the device being used?" and "didn't we do this a few minutes ago?" when deciding to give cputime to tasks. So if you are currently testing this behavior, or troubleshooting why it works in one app and not in another, that actually changes the behavior which makes it very hard to understand or troubleshoot.
Oct ’21
Reply to Creating a custom stack type with Child : Protocol
Answering my own question. So it is possible to do this via a custom _functionBuilder type. The type needs to traffic in an internal [Foo] array type and can be passed back to the ZStack via ZStack { &#9;&#9;let built = customBuilder() &#9;&#9;return ForEach(0..<count) { index in &#9;&#9;&#9;&#9;AnyView(built[index]) &#9;&#9;} } However this is messy for a variety of reasons. One is that a custom builder is a lot to maintain. I'm not sure how many of them are optimizations, but ViewBuilder has a ton of functions for building different blocks. Another is that this hides a lot of stuff from the typesystem (particularly, we have to use AnyView here) which is not ideal performance-wise for large hierarchies. The real problem though is this: DStack { &#9;&#9;MyView1() // : Foo MyView2().foregroundColor(.red) //does NOT conform to Foo } In this example, we wrap the conforming view in some other opaque view which does not conform, which is the kind of idiomatic configuration users do. It is possible to implement e.g. .foregroundColor in a conforming type directly and write a .foregroundColor(...) function which returns that (and this is indeed the case for builtin SwiftUI types like Text) but doing this for any useful function added to SwiftUI.View in the indefinite future is probably fighting a losing battle. Instead, the idiomatic solution to configure across view hierarchies at a distance like this is a combination of 2 techniques. For passing configuration data from parent to child, use Environment. For passing configuration data from child to parent, use PreferenceKey Vadim Bulavin's "View Communication Patterns in SwiftUI" covers these patterns in more detail.
Jul ’20
Reply to Swift Packages + Dependencies + SwiftUI = Fail to Preview
I also have this issue. In a similar configuration I've seen the error "MessageSendingError: Connection interrupted" (filed FB7872575 with diagnostics) and "Failed to connect to &lt;pid&gt;" (filed FB7872591 with diagnostics). I've had mixed results creating a random iOS app that depends on the package and doing previews on that. Currently it's the only workaround I'm aware of, and it's not terribly reliable.
Jul ’20
Reply to Add Playground to Swift Package - WWDC20 10096
I’ve had a number of issues with playgrounds and swift packages, possibly related to having a C package somewhere in the dependency chain (apple if you’re reading this there’s a sample project on FB7859836. Although some of my issues are documented more fully there, here are some “tips and tricks” I’ve learned the hard way: Sometimes it helps to clean and build the package (in Xcode, not on CLI) for the same platform as the playground. For iOS playgrounds this is Simulator. Note that Xcode likes to change the active platform on me randomly, complicating maintaining this. Related, I think sometimes an out-of-date binary gets picked up, which may have unexpected runtime or build time results. importing inside the playground module (that is, inside a file in Sources) doesn’t work for me at all, whereas importing on the playground page itself works better. This does complicate authoring playground code for re-use. Sometimes it helps to build the playground multiple times, like at least 5 times. Doing the same thing can produce different results! Sometimes Issues displayed somewhere in the GUI (issue navigator, source editor, or even the bottom drawer) are alternate worlds that disagree with one another. Therefore if your workflow depends on looking in a consistent location (e.g., issue navigator) and expecting issues to disappear once fixed, you might incorrectly conclude that the import error isn’t fixed by your changes, when in fact the situation changed some other place in Xcode
Jul ’20
Reply to `assert` in metal?
One limitation of buffer out-of-bounds, is that a buffer is not always in-scope (such as inside a math function). Adding a buffer argument for the sole purpose of trapping is not ideal. Based on your suggestion, I am now using this pattern     device float *f = 0;     *f = 12; which seems to trap OK without an explicit buffer. I had previously filed FB7731230 for assert.
Jun ’20
Reply to Swift Package with Metal
I also do this. (Apple, see FB7744335). The main option I need is to link them into the same metallib as the client, since my library contains e.g. math functions that a shader author would call from their shader (and not a set of shader functions that are ready to use, which is a different situation than mine). I also need to add my package to the metal header import paths in the user's library. It would be nice to have a way to specify arbitrary compiler/link flags as well. For OP, my best-effort solution to this problem is I configure my metal library as a C package (this makes sense for me because I provide a CPU version, and it's also easier to develop/test on CPU anyway). Then for the metal version, I have this build script in the root of my package. At a high level, this concatenates all the .c files into a single .metal for them to drag in, and checks some details of their project configuration. #!/usr/bin/swift import Foundation let m = FileManager.default let sourcePath = String(#file.dropLast(15)) m.changeCurrentDirectoryPath(sourcePath) //makemetal.swift var metalAccumulate = "" let sourceDir = "Sources/target/" for file in try m.contentsOfDirectory(atPath: sourceDir) {     if file.hasSuffix(".c") {         metalAccumulate += String(data: m.contents(atPath: sourceDir + file)!, encoding: .utf8)!     } } let outPath = (ProcessInfo.processInfo.environment["SRCROOT"] ?? ".") + "/target.metal" try! metalAccumulate.write(to: URL(fileURLWithPath:outPath), atomically: false, encoding:.utf8) func checkPbxProj() {     guard let srcRoot = ProcessInfo.processInfo.environment["SRCROOT"] else { return }     guard let projectName = ProcessInfo.processInfo.environment["PROJECT_NAME"] else { return }     guard let pbxproj = try? String(contentsOfFile: "\(srcRoot)/\(projectName).xcodeproj/project.pbxproj") else { return }     if !pbxproj.contains("target.metal in Sources") {         print("warning: Drag \(srcRoot)/target.metal into your xcodeproj")     } } func checkHeaderPath() {     guard let _ = ProcessInfo.processInfo.environment["XCODE_VERSION_MAJOR"] else { return }     let searchPaths = ProcessInfo.processInfo.environment["MTL_HEADER_SEARCH_PATHS"] ?? ""     if !searchPaths.contains("target/include") {         print("warning: Add ${HEADER_SEARCH_PATHS} to the 'Metal Compiler - Build Options - Header Search Paths' setting")     } } checkPbxProj() checkHeaderPath() Users then have a custom buildphase in their xcode project set -e for v in ${HEADER_SEARCH_PATHS[@]}; do echo $v notfound if [[ $v == *"target"* ]]; then   (    SDKROOT=""    $v/../../../makemetal.swift   ) fi done This is the best solution I have come up with, but there's a number of annoyances with it: Users have to modify their xcode project in numerous ways, such as a custom buildphase, adding a file to their project manually, setting custom metal import paths etc. I can mitigate this somewhat by checking the situation in my buildscript and warning them about what they did wrong, but I rely a lot on undocumented behavior to inspect xcode, so it's not a future-proof solution custom buildphase requires input/output files to be set explicitly by the end user, so that xcode understands the dependencies and doesn't intermittently fail. Specifying the inputs, in particular, is a trick because ... I abuse header search paths to search for the swiftpm packages, because there is no dedicated environment variable to figure out where they are I am hoping the "Build GPU binaries with metal" talk provides some insights into how to solve some of these issues from the metal side at least, but obviously it's not out until tomorrow so I don't know what's in it.
Jun ’20