I have been trying to integrate a UIKit view into SwiftUI, specifically a WKWebView. However, I keep encountering a does not conform to protocol error.
Here's my code:
import SwiftUI
import WebKit
struct SimpleWebView: View {
var body: some View {
WebViewContainerRepresentable()
.edgesIgnoringSafeArea(.all)
}
}
struct WebViewContainerRepresentable: UIViewRepresentable {
typealias UIViewType = WKWebView
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
// Updates not required for this use case
}
}
I tried this with other views as well, and it turns out this is not WKWebView-specific.
The minimum deployment version is iOS 15.
Any help would be much appreciated. Let me know if I need to add any more information.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm using xcode 16.1 withSwift. I want to know how to call a function passing in an array. Also I need to know how to declare the function receiving the array. I currently have:
func myfunc(costa: [Double]) {
}
I call it like this:
myfunc(costa:[ ])
It's an array of Doubles. I don't get any errors but the array is always empty. Please help. Thank you.
Topic:
Programming Languages
SubTopic:
Swift
Decrypting Data to String Conversion failure
Development environment: Xcode 15.4, macOS 14.7
Run-time configuration: iOS 15.8.1 & 16.0.1
DESCRIPTION OF PROBLEM
We were using objective C implementation of CCCrypt(see below) in our app earlier which we migrated to swift implementation recently. We convert the byte array that CCCrypt returns into Data, and data to string to read the decrypted value. It works perfectly fine in Objective C, whereas with new swift implementation this conversion is failing, it looks like CCCrypt is returning byte array with few non UTF8 characters and that conversion is failing in swift since Objective C is more tolerant with this conversion and converts the byte array to Data and then to string even though there are few imperfect UTF characters in the array.
Objective C
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. /
CCAlgorithm alg, / kCCAlgorithmAES128, etc. /
CCOptions options, / kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void iv, / optional initialization vector */
const void dataIn, / optional per op and alg */
size_t dataInLength,
void dataOut, / data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
API_AVAILABLE(macos(10.4), ios(2.0));
Swift Code
CCCrypt(_ op: CCOperation,
_ alg: CCAlgorithm,
_ options: CCOptions,
_ key: UnsafeRawPointer!,
_ keyLength: Int, _ iv: UnsafeRawPointer!,
_ dataIn: UnsafeRawPointer!,
_ dataInLength: Int,
_ dataOut: UnsafeMutableRawPointer!,
_ dataOutAvailable: Int,
_ dataOutMoved: UnsafeMutablePointer!) -> CCCryptorStatus
Data to String Conversion
String(data: decryptedData, encoding: .utf8)
STEPS TO REPRODUCE
Able to reproduce on below devices
iPhone - 7
OS Version 15.8.1
iPhone 14- Pro
OS Version 16.0.2
iPhone 15
iOS 18.0.1
**Decryption method return "Data" and converting into string using ".utf8" but String conversion is failing on above devices and some other devices as well. Decryption failure not occurring always.
**
Below code used for String conversion
String(data: decryptedData, encoding: .utf8)
My application crash on iOS 16 randomly, stack trace like this:
libswiftCore.dylib __swift_release_dealloc + 32
libswiftNetwork.dylib outlined consume of (@escaping @callee_guaranteed (@in_guaranteed Network.NWConnection.State) -> ())? + 52
libswiftNetwork.dylib outlined consume of (@escaping @callee_guaranteed (@in_guaranteed Network.NWConnection.State) -> ())? + 52
libswiftCore.dylib __swift_release_dealloc + 56
libsystem_blocks.dylib __call_dispose_helpers_excp + 48
libsystem_blocks.dylib __Block_release + 252
libsystem_blocks.dylib bool HelperBase::disposeCapture<(HelperBase::BlockCaptureKind)4>(unsigned int, unsigned char*) + 68
libsystem_blocks.dylib HelperBase::destroyBlock(Block_layout*, bool, unsigned char*) + 180
libsystem_blocks.dylib __call_dispose_helpers_excp + 72
libsystem_blocks.dylib __Block_release + 252
libdispatch.dylib ___destroy_helper_block_8_32c35typeinfo name for dispatch_block_private_data_s + 96
libsystem_blocks.dylib __call_dispose_helpers_excp + 48
libsystem_blocks.dylib __Block_release + 252
libdispatch.dylib __dispatch_client_callout + 20
libdispatch.dylib __dispatch_root_queue_drain + 684
libdispatch.dylib __dispatch_worker_thread2 + 164
libsystem_pthread.dylib __pthread_wqthread + 228
From buly(a tool to report crash) we notice that this crash only happens on iOS 16
Topic:
Programming Languages
SubTopic:
Swift
I want to know how to format doubles. In the program I have 4.3333 I just want to print 4 to the screen. I just want to print whole numbers. I'm using Swiftui with xcode. Please help. Thank you.
Topic:
Programming Languages
SubTopic:
Swift
Hi,
I'm struggling to understand using Swift-C++ in the same project. I have an existing code-base that makes heavy use of Swift-Objective-C interoperability.
We make use of swift classes in our project. When I enable swift-objective c interoperability I am running into numerous build errors in the generated bridging header.
I'm trying to understand why these errors exist and what to do to get around them.
I have a project that I've set up with some test code, and I'm running into an error here:
public class Foo {
let name: String
public init(name: String) {
self.name = name
}
}
public class Bar {
let name: String
public init(name : String) {
self.name = name;
}
public func getFoo() -> Foo {
return Foo(name: self.name);
}
}
In the header file:
Unknown type name 'Foo'
SWIFT_INLINE_THUNK Foo getFoo() SWIFT_SYMBOL("s:13ForestBuilder3BarC6getFooAA0E0CyF");
This error goes away if I use structs, but for the purposes of porting my codebase, I'd prefer to use classes. Do classes not play nice here? Or am I misunderstanding something.
Thanks.
I am porting an old app from ObjC. The app uses many defined constants such as:
#define COM_OFFSET 12.5
and many variables that are read and/or written throughout the App, such as:
PCDate* Dates[367];
@class PCMainView;
PCMainView* MainView;
in one file called "PCCommon.h"
How do I duplicate this function in Swift? I have looked around and have found no help.
Thanks in advance.
We would like to show a user-friendly message but can not.
Description:
When attempting to create a duplicate passkey using the ASAuthrorizationController in iOS, the Face ID authentication times out SDK does not return a timeout specific error. Instead, it directly returns an error stating that duplicate passkey cannot be created.
SDK to first handle the FaceID timeout case and provide a distinct timeout error so we can gracefully manage this scenario before the duplicate passkey validation occurs.
Steps to Reproduce:
Implement passkey creation flow using ASAuthorizationController.
Attempt to register a duplicate passkey (e.g., using the same user ID and challenge).
Let FaceID prompt timeout (do not interact with the authentication prompt).
Topic:
Programming Languages
SubTopic:
Swift
I recently submitted my app, Hogs, to the App Store, but it was rejected due to references to non-public symbols:
_lzma_code
_lzma_end
I am using the LZMA compression library in my app, and these functions are part of that implementation. Here's a breakdown of my usage:
Library Used: liblzma (custom wrapper around LZMA functions)
Error Message: "The app references non-public symbols in Payload/Hogs.app/Hogs: _lzma_code, _lzma_end."
Steps I’ve Taken:
I’ve wrapped the LZMA functions in my own functions (my_lzma_code, my_lzma_end) to prevent direct references.
I have checked the build settings and included -lzma in the linker flags.
I’ve tried using a custom framework to encapsulate LZMA, but the issue persists.
I would greatly appreciate any help or suggestions on how to resolve this issue and get my app approved. Is there any workaround or adjustment I can make to avoid using these non-public symbols?
Thank you in advance for your assistance.
Hello,
I have integrated LZMA2 compression into my iOS app, Hogs, and successfully implemented compression. However, when attempting to upload the app for TestFlight, I encountered an error:
"The app references non-public symbols in Payload/Hogs.app/Hogs: _lzma_code, _lzma_end."
These functions are part of the LZMA compression library (specifically LZMA2). Here's a detailed description of the issue:
What I Have Done:
LZMA2 Integration: I integrated LZMA2 compression into the app and created a wrapper around the LZMA functions (_lzma_code, _lzma_end) to prevent direct references.
App Build Configuration:
I ensured the LZMA2 library is linked correctly with the -lzma flag in the linker settings.
I wrapped the LZMA functions in custom functions (my_lzma_code, my_lzma_end) in an attempt to avoid using the non-public symbols directly.
Error Message:
During the app submission process, I received the following error:
"The app references non-public symbols in Payload/Hogs.app/Hogs: _lzma_code, _lzma_end."
Steps Taken to Resolve:
Checked if any LZMA functions were exposed incorrectly.
Ensured that all non-public symbols were properly encapsulated in a wrapper.
Verified linker settings to ensure the proper inclusion of the LZMA2 library.
Request:
Could anyone provide suggestions or best practices to resolve this issue and avoid references to non-public symbols? Should I use a different method for linking LZMA2 or encapsulating these symbols?
Thank You:
I appreciate your help in resolving this issue so I can move forward with submitting the app for TestFlight.
Topic:
Programming Languages
SubTopic:
Swift
Tags:
Swift Packages
Apple Archive
Compression
TestFlight
I was a long time C# programmer, and recently started learning Rust. Now that I recently purchased my first Mac, I ran into several issues trying to run binaries on the Mac, due to various restrictions. On another forum post here, it was mentioned that I should take a look at Swift, as a development tool.
This comment brings up an entirely new topic for me, as I discovered that the Swift project file structure seems daunting. But first let's backtrack to when I used C#.
C#
The first graphic show the default file structure that I used to start a new C# project. I would copy this entire folder structure to the clipboard and paste it where my new project folder was located, and start coding.
Using this same principle, I wrote my own music player, and again the file structure for the entire project was as below. For those that may not know, the "bin" folder contains both debug and release folders and appropriate contents.
Swift
I created a Windows UI called "Test" using Swift, and then started poking around the file system, trying to determine the file structure that was created. Unbeknownst to me at the time, part of the project files ended up on the Desktop in a folder called Test. I did not expect Swift to place the files there.
When I click on the Test folder and look inside, I see a file with a "xcodeproj" extension, which makes sense to me, as this is similar to C#. What I don't see however, is any file labeled Test.App. I also don't see either debug or release folders for this project.
Obviously there are additional files for this project that are "somewhere", just not in a location I am aware of.
Topic:
Programming Languages
SubTopic:
Swift
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.
Hi, I want to create a dashboard in a app using swift playgrounds with esp 32 and a led. The dashboard should have a toggle switch to toggle the switch state like on/off for the led once i get the basics i want to create a full dashboards with things like gauges, sliders, button and many more. Can someone please help/guide me.
Thanks.
Topic:
Programming Languages
SubTopic:
Swift
A few years ago [1] Xcode added new warnings that help detect a nasty gotcha related to the lifetime of unsafe pointers. For example:
Initialization of 'UnsafeMutablePointer<timeval>' results in a dangling pointer
Inout expression creates a temporary pointer, but argument 'iov_base' should be a pointer that outlives the call to 'init(iov_base:iov_len:)'
I’ve seen a lot of folks confused by these warnings, and by the lifetime of unsafe pointers in general, and this post is my attempt to clarify the topic.
If you have questions about any of this, please put them in a new thread in the Programming Languages > Swift topic.
Finally, I encourage you to watch the following WWDC presentations:
WWDC 2020 Session 10648 Unsafe Swift
WWDC 2020 Session 10167 Safely manage pointers in Swift
These cover some of the same ground I’ve covered here, and a lot of other cool stuff as well.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
[1] Swift 5.2.2, as shipped in Xcode 11.4. See the discussion of SR-2790 in Xcode 11.4 Release Notes.
Basics
In Swift, the ampersand (&) indicates that a parameter is being passed inout. Consider this example:
func addVarnish(_ product: inout String) {
product += " varnish"
}
var waffle = "waffle"
addVarnish(&waffle) // line A
print(waffle)
// printed: waffle varnish
On line A, the ampersand tells you that waffle could be modified by addVarnish(_:).
However, there is another use of ampersand that was designed to help with C interoperability. Consider this code:
var tv = timeval()
gettimeofday(&tv, nil)
print(tv)
// printed: timeval(tv_sec: 1590743104, tv_usec: 77027)
The first parameter to gettimeofday is an UnsafeMutablePointer<timeval>. Here the ampersand denotes a conversion from a timeval to an UnsafeMutablePointer<timeval>. This conversion makes it much easier to call common C APIs from Swift.
This also works for array values. For example:
var hostName = [CChar](repeating: 0, count: 256)
gethostname(&hostName, hostName.count)
print(String(cString: hostName))
// printed: slimey.local.
In this code the ampersand denotes a conversion from [CChar] to an UnsafeMutablePointer<CChar> that points to the base of the array.
While this is convenient, it’s potentially misleading, especially if you come from a C background. In C-based languages, using ampersand in this way yields a pointer to the value that’s valid until the value gets deallocated. That’s not the case in Swift. Rather, the pointer generated by the ampersand syntax is only valid for the duration of that function call.
To understand why that’s the case, consider this code:
struct TimeInTwoParts {
var sec: time_t = 0
var usec: Int32 = 0
var combined: timeval {
get { timeval(tv_sec: sec, tv_usec: usec) }
set {
sec = newValue.tv_sec
usec = newValue.tv_usec
}
}
}
var time = TimeInTwoParts()
gettimeofday(&time.combined, nil) // line A
print(time.combined)
// printed: timeval(tv_sec: 1590743484, tv_usec: 89118)
print(time.sec)
// printed: 1590743484
print(time.usec)
// printed: 89118
Here combined is a computed property that has no independent existence in memory. Thus, it simply makes no sense to take the address of it.
So, how does ampersand deal with this? Under the covers the Swift compiler expands line A to something like this:
var tmp = time.combined
gettimeofday(&tmp, nil)
time.combined = tmp
Once you understand this it’s clear why the resulting pointer is only valid for the duration of the call: As soon as Swift cleans up tmp, the pointer becomes invalid.
A Gotcha
This automatic conversion can be a nasty gotcha. Consider this code:
var tv = timeval()
let tvPtr = UnsafeMutablePointer(&tv) // line A
// ^~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization of 'UnsafeMutablePointer<timeval>' results in a dangling pointer
gettimeofday(tvPtr, nil) // line B
This results in undefined behaviour because the pointer generated by the ampersand on line A is no longer valid when it’s used on line B. In some cases, like this one, the later Swift compiler is able to detect this problem and warn you about it. In other cases you’re not so lucky. Consider this code:
guard let f = fopen("tmp.txt", "w") else { … }
var buf = [CChar](repeating: 0, count: 1024)
setvbuf(f, &buf, _IOFBF, buf.count) // line A
let message = [UInt8]("Hello Crueld World!".utf8)
fwrite(message, message.count, 1, f) // line B
fclose(f) // line C
This uses setvbuf to apply a custom buffer to the file handle. The file handle uses this buffer until after the close on line C. However, the pointer created by the ampersand on line A only exists for the duration of the setvbuf call. When the code calls fwrite on line B the buffer pointer is no longer valid and things end badly.
Unfortunately the compiler isn’t able to detect this problem. Worse yet, the code might actually work initially, and then stop working as you change optimisation settings, update the compiler, change unrelated code, and so on.
Another Gotcha
There is another gotcha associated with the ampersand syntax. Consider this code:
class AtomicCounter {
var count: Int32 = 0
func increment() {
OSAtomicAdd32(1, &count)
}
}
This looks like it’ll implement an atomic counter but there’s no guarantee that the counter will be atomic. To understand why, apply the tmp transform from earlier:
class AtomicCounter {
var count: Int32 = 0
func increment() {
var tmp = count
OSAtomicAdd32(1, &tmp)
count = tmp
}
}
So each call to OSAtomicAdd32 could potentially be operating on a separate copy of the counter that’s then assigned back to count. This undermines the whole notion of atomicity.
Again, this might work in some builds of your product and then fail in other builds.
Note The above discussion is now theoretical because Swift 6 added a Synchronization module that includes comprehensive support for atomics. That module also has a Mutex type (if you need a mutex on older platforms, check out OSAllocatedUnfairLock). These constructs use various different mechanisms to ensure that the underlying value has a stable address.
Summary
So, to summarise:
Swift’s ampersand syntax has very different semantics from the equivalent syntax in C.
When you use an ampersand to convert from a value to a pointer as part of a function call, make sure that the called function doesn’t use the pointer after it’s returned.
It is not safe to use the ampersand syntax for functions where the exact pointer matters.
It’s Not Just Ampersands
There’s one further gotcha related to arrays. The gethostname example above shows that you can use an ampersand to pass the base address of an array to a function that takes a mutable pointer. Swift supports two other implicit conversions like this:
From String to UnsafePointer<CChar> — This allows you to pass a Swift string to an API that takes a C string. For example:
let greeting = "Hello Cruel World!"
let greetingLength = strlen(greeting)
print(greetingLength)
// printed: 18
From Array<Element> to UnsafePointer<Element> — This allows you to pass a Swift array to a C API that takes an array (in C, arrays are typically represented as a base pointer and a length). For example:
let charsUTF16: [UniChar] = [72, 101, 108, 108, 111, 32, 67, 114, 117, 101, 108, 32, 87, 111, 114, 108, 100, 33]
print(charsUTF16)
let str = CFStringCreateWithCharacters(nil, charsUTF16, charsUTF16.count)!
print(str)
// prints: Hello Cruel World!
Note that there’s no ampersand in either of these examples. This technique only works for UnsafePointer parameters (as opposed to UnsafeMutablePointer parameters), so the called function can’t modify its buffer. As the ampersand is there to indicate that the value might be modified, it’s not used in this immutable case.
However, the same pointer lifetime restriction applies: The pointer passed to the function is only valid for the duration of that function call. If the function keeps a copy of that pointer and then uses it later on, Bad Things™ will happen.
Consider this code:
func printAfterDelay(_ str: UnsafePointer<CChar>) {
print(strlen(str))
// printed: 18
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
print(strlen(str))
// printed: 0
}
}
let greeting = ["Hello", "Cruel", "World!"].joined(separator: " ")
printAfterDelay(greeting)
dispatchMain()
The second call to strlen yields undefined behaviour because the pointer passed to printAfterDelay(_:) becomes invalid once printAfterDelay(_:) returns. In this specific example the memory pointed to by str happened to contain a zero, and hence strlen returned 0 but that’s not guaranteed. The str pointer is dangling, so you might get any result from strlen, including a crash.
Advice
So, what can you do about this? There’s two basic strategies here:
Extend the lifetime of the pointer
Manual memory management
Extending the Pointer’s Lifetime
The first strategy makes sense when you have a limited number of pointers and their lifespan is limited. For example, you can fix the setvbuf code from above by changing it to:
let message = [UInt8]("Hello Crueld World!".utf8)
guard let f = fopen("tmp.txt", "w") else { … }
var buf = [CChar](repeating: 0, count: 1024)
buf.withUnsafeMutableBufferPointer { buf in
setvbuf(f, buf.baseAddress!, _IOFBF, buf.count)
fwrite(message, message.count, 1, f)
fclose(f)
}
This version of the code uses withUnsafeMutableBufferPointer(_:). That calls the supplied closure and passes it a pointer (actually an UnsafeMutableBufferPointer) that’s valid for the duration of that closure. As long as you only use that pointer inside the closure, you’re safe!
There are a variety of other routines like withUnsafeMutableBufferPointer(_:), including:
The withUnsafeMutablePointer(to:_:) function
The withUnsafeBufferPointer(_:), withUnsafeMutableBufferPointer(_:), withUnsafeBytes(_:), and withUnsafeMutableBytes(_:) methods on Array
The withUnsafeBytes(_:) and withUnsafeMutableBytes(_:) methods on Data
The withCString(_:) and withUTF8(_:) methods on String.
Manual Memory Management
If you have to wrangle an unbounded number of pointers — or the lifetime of your pointer isn’t simple, for example when calling an asynchronous call — you must revert to manual memory management. Consider the following code, which is a Swift-friendly wrapper around posix_spawn:
func spawn(arguments: [String]) throws -> pid_t {
var argv = arguments.map { arg -> UnsafeMutablePointer<CChar>? in
strdup(arg)
}
argv.append(nil)
defer {
argv.forEach { free($0) }
}
var pid: pid_t = 0
let success = posix_spawn(&pid, argv[0], nil, nil, argv, environ) == 0
guard success else { throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil) }
return pid
}
This code can’t use the withCString(_:) method on String because it has to deal with an arbitrary number of strings. Instead, it uses strdup to copy each string to its own manually managed buffer. And, as these buffers are manually managed, is has to remember to free them.
Change History
2024-12-11 Added a note about the Synchronization module. Made various editorial changes.
2021-02-24 Fixed the formatting. Added links to the WWDC 2021 sessions. Fixed the feedback advice. Minor editorial changes.
2020-06-01 Initial version.
Everyone knows that dictionaries in swift are unordered collections, there is no problem with that.
I've noticed some behavior that I can't explain and hope someone can help me.
The first variant
We have a very simple code:
struct Test {
let dict = [1: “1”, 2: “2”, 3: “3”, 4: “4”, 5: “5”]
func test() {
for i in dict {
print(i)
}
}
}
If you call test() several times in a row, the output to the console on my computer looks something like this:
(key: 5, value: “5”)
(key: 1, value: “1”)
(key: 2, value: “2”)
(key: 3, value: “3”)
(key: 4, value: “4”)
(key: 2, value: “2”)
(key: 3, value: “3”)
(key: 1, value: “1”)
(key: 4, value: “4”)
(key: 5, value: “5”)
(key: 1, value: “1”)
(key: 3, value: “3”)
(key: 2, value: “2”)
(key: 5, value: “5”)
(key: 4, value: “4”)
At each new for loop we get a random order of elements
It seemed logical to me, because a dictionary is an unordered collection and this is correct behavior.
However
The second variant
the same code on my colleague's computer, but in the console we see something like this:
(key: 2, value: “2”)
(key: 3, value: “3”)
(key: 1, value: “1”)
(key: 4, value: “4”)
(key: 5, value: “5”)
(key: 2, value: “2”)
(key: 3, value: “3”)
(key: 1, value: “1”)
(key: 4, value: “4”)
(key: 5, value: “5”)
(key: 2, value: “2”)
(key: 3, value: “3”)
(key: 1, value: “1”)
(key: 4, value: “4”)
(key: 5, value: “5”)
always, within the same session, we get the same order in print(i)
We didn't use Playground, within which there may be differences, but a real project.
swift version 5+
we tested on Xcode 14+, 15+ (at first I thought it was because the first version had 14 and the second version had 15, but then a third colleague with Xcode 15 had the behavior from the first scenario)
we did a lot of checks, several dozens of times and always got that on one computer random output of items to the console, and in another case disordered only in the first output to the console
Thanks
I have an old app that I just got a notice will be pulled form the App Store if I don't upgrade. I tried to open in Xcode but it says I need to use Xcode 10.1 to convert to Swift 4.
Exact message - "Use Xcode 10.1 to migrate the code to Swift 4."
I downloaded Xcode 10.1 , now the OS (Sequoia ) says can't do it, have to use the latest version of Xcode.
Exact message - "The version of Xcode installed on this Mac is not compatible with macOS Sequoia. Download the latest version for free from the App Store."
Any experience with this and suggestions would be greatly appreciated.
Sometimes when my app crashes I get an exception like this: EXC_BREAKPOINT (SIGTRAP).
But I don't know how to catch it. Is there a way in Swift to catch such exceptions?
Hi, I have issue on build my react native project and got this error "Undefined symbol: _swift_willThrowTypedImpl" how can I fix it?
I don't understand what's happening when I save values via a loop.
I initialize an array with default values, then run a loop to assign calculated values to it. In the middle of the loop, I print values, then print values again after the loop is over. The array values sometimes change, even though nothing has been written between print calls (when they change, the values are equal the last value in the array, index 49).
I made a test file which writes four types of values to an array: (1) A new class instance, (2) Calculation, (3) Variable, (4) Hard-code. Saving the same value gives different results between the different write methods:
import Foundation
let numElements : Int = 50
class CustomType{
var x : Double
var y : Double
init(x: Double = 1.23, y: Double = 2.34) {
self.x = x
self.y = y
}
}
// Try this four different ways
var array1 = [CustomType](repeating:CustomType(), count:numElements)
var array2 = [CustomType](repeating:CustomType(), count:numElements)
var array3 = [CustomType](repeating:CustomType(), count:numElements)
var array4 = [CustomType](repeating:CustomType(), count:numElements)
// Checking that defaults were written
print("Pre: Point 1: (\(array1[44].x),\(array1[44].y))")
print("Pre: Point 2: (\(array2[44].x),\(array2[44].y))")
print("Pre: Point 3: (\(array3[44].x),\(array3[44].y))")
print("Pre: Point 4: (\(array4[44].x),\(array4[44].y))")
// --- Fix 1: Problem goes away if I uncomment this:
// array1[44]=CustomType()
// array2[44]=CustomType()
// array3[44]=CustomType()
// array4[44]=CustomType()
// --- Fix 2: Or if you swap these two lines for the following line:
// let index = 44
// do {
for index in 0..<numElements{
let rads = Double(index) * 2 * Double.pi/Double(numElements)
let sinrads = sin(rads), cosrads = cos(rads)
// Four different ways to save to arrays
array1[index] = CustomType(x:sin(rads),y:cos(rads))
array2[index].x = sin(rads)
array2[index].y = cos(rads)
array3[index].x = sinrads
array3[index].y = cosrads
array4[index].x = -0.684547105928689
array4[index].y = 0.7289686274214113
if(index==44){
print("\n== Printing results mid-loop at index 44 ==")
print("During: index: \(index), Calculated Rads: \(rads)")
print("During: Calculated Vals: (\(sin(rads)),\(cos(rads)))")
print("During: Stored 'let' Vals: (\(sinrads),\(cosrads))")
print("During: Point 1: (\(array1[44].x),\(array1[44].y))")
print("During: Point 2: (\(array2[44].x),\(array2[44].y))")
print("During: Point 3: (\(array3[44].x),\(array3[44].y))")
print("During: Point 4: (\(array4[44].x),\(array4[44].y))")
}
}
print("\n== Printing the same results after the loop ==")
print("Post: Point 1: (\(array1[44].x),\(array1[44].y))")
print("Post: Point 2: (\(array2[44].x),\(array2[44].y))")
print("Post: Point 3: (\(array3[44].x),\(array3[44].y))")
print("Post: Point 4: (\(array4[44].x),\(array4[44].y))")
print("\n== Reverse-calculating results from a correct array (array 1) to get the for loop index ==")
print("reverse index calculation 01: \( (atan2(array1[ 1].x,array1[ 1].y) + Double.pi * 0) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 44: \( (atan2(array1[44].x,array1[44].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 45: \( (atan2(array1[45].x,array1[45].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("\n== Reverse-calculating results from an incorrect array (array 2) to get the for loop index ==")
print("reverse index calculation 1: \( (atan2(array2[ 1].x,array2[ 1].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 44: \( (atan2(array2[44].x,array2[44].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 45: \( (atan2(array2[45].x,array2[45].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
Which gives the following output:
Pre: Point 1: (1.23,2.34)
Pre: Point 2: (1.23,2.34)
Pre: Point 3: (1.23,2.34)
Pre: Point 4: (1.23,2.34)
== Printing results mid-loop at index 44 ==
During: index: 44, Calculated Rads: 5.529203070318036
During: Calculated Vals: (-0.684547105928689,0.7289686274214113)
During: Stored 'let' Vals: (-0.684547105928689,0.7289686274214113)
During: Point 1: (-0.684547105928689,0.7289686274214113)
During: Point 2: (-0.684547105928689,0.7289686274214113)
During: Point 3: (-0.684547105928689,0.7289686274214113)
During: Point 4: (-0.684547105928689,0.7289686274214113)
== Printing the same results after the loop ==
Post: Point 1: (-0.684547105928689,0.7289686274214113)
Post: Point 2: (-0.12533323356430465,0.9921147013144778)
Post: Point 3: (-0.12533323356430465,0.9921147013144778)
Post: Point 4: (-0.684547105928689,0.7289686274214113)
== Reverse-calculating results from a correct array (array 1) to get the for loop index ==
reverse index calculation 01: 1.0000000000000002
reverse index calculation 44: 43.99999999999999
reverse index calculation 45: 45.0
== Reverse-calculating results from an incorrect array (array 2) to get the for loop index ==
reverse index calculation 1: 49.0
reverse index calculation 44: 49.0
reverse index calculation 45: 49.0
Program ended with exit code: 0
Re-initializing the objects prior to the loop fixes the problem (see "Fix 1" in the comments), but the elements of the array are all initialized during creation and I don't understand why doing it a second time is helpful. The values should all be the same, am I missing something simple?
Topic:
Programming Languages
SubTopic:
Swift
I have the following TaskExecutor code in Swift 6 and is getting the following error:
//Error
Passing closure as a sending parameter risks causing data races between main actor-isolated code and concurrent execution of the closure.
May I know what is the best way to approach this?
This is the default code generated by Xcode when creating a Vision Pro App using Metal as the Immersive Renderer.
Renderer
@MainActor
static func startRenderLoop(_ layerRenderer: LayerRenderer, appModel: AppModel) {
Task(executorPreference: RendererTaskExecutor.shared) { //Error
let renderer = Renderer(layerRenderer, appModel: appModel)
await renderer.startARSession()
await renderer.renderLoop()
}
}
final class RendererTaskExecutor: TaskExecutor {
private let queue = DispatchQueue(label: "RenderThreadQueue", qos: .userInteractive)
func enqueue(_ job: UnownedJob) {
queue.async {
job.runSynchronously(on: self.asUnownedSerialExecutor())
}
}
func asUnownedSerialExecutor() -> UnownedTaskExecutor {
return UnownedTaskExecutor(ordinary: self)
}
static let shared: RendererTaskExecutor = RendererTaskExecutor()
}