struct ContentView: View {
@State var isPresented = false
var body: some View {
Button {
isPresented.toggle()
} label: {
Text("Button")
}
.sheet(isPresented: $isPresented) {
SubView()
}
}
}
struct SubView: View {
@State var text = ""
var body: some View {
NavigationStack {
TextEditor(text: $text)
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button("Click") {
}
}
ToolbarItemGroup(placement: .keyboard) {
Button("Click") {
}
}
}
}
}
}
Swift
RSS for tagSwift is a powerful and intuitive programming language for Apple platforms and beyond.
Posts under Swift tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
In some particular situation, Xcode debugger or lldb cli cannot correctly extract some value that returned by a async throw function and handled by guard let try?.
Here is the minimum example:
import Dispatch
func test() async throws -> [Int] {
return [369]
}
let group = DispatchGroup()
group.enter()
let task = Task {
guard let res = try? await test() else { return }
print(res)
group.leave()
}
group.wait()
If added a break point at print(res), the debugger cannot show the value of res.
Due to forum limitation, I cannot paste a screenshot here...
if use p res or po res at lldb cli, it shows:
(lldb) p res
error: expression failed to parse:
error: <EXPR>:3:1: error: cannot find 'res' in scope
res
^~~
(lldb) po res
error: expression failed to parse:
error: <EXPR>:3:1: error: cannot find 'res' in scope
res
^~~
If test() returns a dict, or a costom struct, the issue retains. But if returned a trivial value like Int, it acts normally.
Also, if remove the guard statement, make res a optional value(use let res = try? await test()), debugger can extract the value.
Above results are compiled and run in this environment:
Swift 5.6.1
Xcode 13.4.1 (13F100)
lldb-1316.0.9.46
macOS 12.4
x86_64 arch
Hi,
I was testing the lockdown mode in iOS 16 and would like to know whether we can detect the lockdown mode status using any public API that Apple provides.
I really appreciate any help you can provide.
Hey, so I am creating an app that will get the core motion data (accelerometer and gyroscope) from my apple watch and stream it onto a console. I am able to get accelerometer data but not a gyroscope from my apple watch. When I try it with my phone I get both. So is gyroscope data not available for the apple watch?
I spend way too much time interacting with the Security framework. Most Security framework APIs are kinda clunky to call from Swift, largely because they use Core Foundation conventions. However, I see a lot of folks working much harder than they should to call these APIs. This post contains two tips to make your life easier.
Many Security framework APIs work in terms of CFDictionary. I regularly see folks create these dictionaries like so:
let query: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecMatchLimit as String: kSecMatchLimitAll,
kSecReturnRef as String: true,
]
var copyResult: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, ©Result)
That’s much too hard. Try this instead:
let query = [
kSecClass: kSecClassKey,
kSecMatchLimit: kSecMatchLimitAll,
kSecReturnRef: true,
] as NSDictionary
var copyResult: CFTypeRef?
let status = SecItemCopyMatching(query, ©Result)
Much nicer.
Security framework APIs have a wide variety of ways to indicate an error:
Some routines return an OSStatus and that’s it.
Some routines return an OSStatus and an ‘out’ value.
Some routines return a pointer, where nil indicates an error.
Some routines return a pointer, where nil indicates an error, with a CFError ‘out’ value.
Some routines return a Boolean, where false indicates an error, with a CFError ‘out’ value.
In Swift you really just want to call the API and have it throw. The code pasted in at the end of this post helps with that. It declares a bunch of overloaded secCall(…) functions, one for each of the cases outlined above. It takes code like this:
let query = [
kSecClass: kSecClassKey,
kSecMatchLimit: kSecMatchLimitAll,
kSecReturnRef: true,
] as NSDictionary
var copyResult: CFTypeRef? = nil
let err = SecItemCopyMatching(query, ©Result)
guard err == errSecSuccess else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(err))
}
let keys = copyResult! as! [SecKey]
and turns it into this:
let query = [
kSecClass: kSecClassKey,
kSecMatchLimit: kSecMatchLimitAll,
kSecReturnRef: true,
] as NSDictionary
let keys = try secCall { SecItemCopyMatching(query, $0) } as! [SecKey]
Still not exactly pretty, but definitely an improvement.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Revision History
2023-11-27 Fixed a polarity bug with the Bool routine. As the saying goes “Real programmers can get the branch backwards in any language!” |-:
/// Calls a Security framework function, throwing if it returns an error.
///
/// For example, the `SecACLRemove` function has a signature like this:
///
/// ```
/// func SecACLRemove(…) -> OSStatus
/// ```
///
/// and so you call it like this:
///
/// ```
/// try secCall { SecACLRemove(acl) }
/// ```
///
/// - Parameter body: A function that returns an `OSStatus` value.
/// - Throws: If `body` returns anything other than `errSecSuccess`.
func secCall(_ body: () -> OSStatus) throws {
let err = body()
guard err == errSecSuccess else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil)
}
}
/// Calls a Security framework function that returns an error and a value indirectly.
///
/// For example, the `SecItemCopyMatching` function has a signature like this:
///
/// ```
/// func SecItemCopyMatching(…, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus
/// ```
///
/// and so you call it like this:
///
/// ```
/// let keys = try secCall { SecItemCopyMatching([
/// kSecClass: kSecClassKey,
/// kSecMatchLimit: kSecMatchLimitAll,
/// kSecReturnRef: true,
/// ] as NSDictionary, $0) }
/// ```
///
/// - Parameter body: A function that returns an `OSStatus` value and takes a
/// ‘out’ pointer to return the result indirectly.
/// - Throws: If `body` returns anything other than `errSecSuccess`.
/// - Returns: The value returned indirectly by the function.
func secCall<Result>(_ body: (_ resultPtr: UnsafeMutablePointer<Result?>) -> OSStatus) throws -> Result {
var result: Result? = nil
let err = body(&result)
guard err == errSecSuccess else {
throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil)
}
return result!
}
/// Calls a Security framework function that returns `nil` on error.
///
/// For example, the `SecKeyCopyPublicKey` function has a signature like this:
///
/// ```
/// func SecKeyCopyPublicKey(…) -> SecKey?
/// ```
///
/// and so you call it like this:
///
/// ```
/// let publicKey = try secCall { SecKeyCopyPublicKey(privateKey) }
/// ```
///
/// - Parameters:
/// - code: An `OSStatus` value to throw if there’s an error; defaults to `errSecParam`.
/// - body: A function that returns a value, or `nil` if there’s an error.
/// - Throws: If `body` returns `nil`.
/// - Returns: On success, the non-`nil` value returned by `body`.
func secCall<Result>(_ code: Int = Int(errSecParam), _ body: () -> Result?) throws -> Result {
guard let result = body() else {
throw NSError(domain: NSOSStatusErrorDomain, code: code, userInfo: nil)
}
return result
}
/// Calls a Security framework function that returns `nil` on error along with a `CFError` indirectly.
///
/// For example, the `SecKeyCreateDecryptedData` function has a signature like this:
///
/// ```
/// func SecKeyCreateDecryptedData(…, _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> CFData?
/// ```
///
/// and so you call it like this:
///
/// ```
/// let plainText = try secCall { SecKeyCreateDecryptedData(privateKey, .rsaEncryptionPKCS1, cypherText, $0) }
/// ```
///
/// - Parameter body: A function that returns a value, which returns `nil` if
/// there’s an error and, in that case, places a `CFError` value in the ‘out’ parameter.
/// - Throws: If `body` returns `nil`.
/// - Returns: On success, the non-`nil` value returned by `body`.
func secCall<Result>(_ body: (_ resultPtr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> Result?) throws -> Result {
var errorQ: Unmanaged<CFError>? = nil
guard let result = body(&errorQ) else {
throw errorQ!.takeRetainedValue() as Error
}
return result
}
/// Calls a Security framework function that returns false on error along with a `CFError` indirectly.
///
/// For example, the `SecKeyVerifySignature` function has a signature like this:
///
/// ```
/// func SecKeyVerifySignature(…, _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> Bool
/// ```
///
/// and so you call it like this:
///
/// ```
/// try secCall { SecKeyVerifySignature(publicKey, .ecdsaSignatureMessageX962SHA1, signedData, signature, $0) }
/// ```
///
/// - Parameter body: A function that returns a false if there’s an error and,
/// in that case, places a `CFError` value in the ‘out’ parameter.
/// - Throws: If `body` returns false.
func secCall(_ body: (_ resultPtr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> Bool) throws {
var errorQ: Unmanaged<CFError>? = nil
guard body(&errorQ) else {
throw errorQ!.takeRetainedValue() as Error
}
}
Hi Team,
Is there a way to clone the entire mail app like listing the email, details view with attachment and thread emails?
Bellows are the codes in Swift Playground.
import PlaygroundSupport
import SwiftUI
struct VisualEffectView: NSViewRepresentable
{
let material: NSVisualEffectView.Material = .contentBackground
let blendingMode: NSVisualEffectView.BlendingMode = .withinWindow
func makeNSView(context: Context) -> NSVisualEffectView
{
let visualEffectView = NSVisualEffectView()
visualEffectView.material = material
visualEffectView.blendingMode = blendingMode
visualEffectView.state = NSVisualEffectView.State.active
return visualEffectView
}
func updateNSView(_ visualEffectView: NSVisualEffectView, context: Context)
{
visualEffectView.material = material
visualEffectView.blendingMode = blendingMode
}
}
struct ContentView: View {
var body: some View {
ZStack {
Image(nsImage: #imageLiteral(resourceName: "background.jpg"))
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 400, height: nil, alignment: .center)
VisualEffectView()
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
The codes result in white area with the Image invisible.
I'm pretty sure I'm missing something completely obvious, but I can't see what. I watched WWDC session, read the Swift evolution blog, and they all make sense, but still it doesn't click for me. Please help me out here :) .
I'm diving into adopting the 'new' async/await style of coding (I know, it's old news at this point, but I could only get to it now), and so I'm all pumped to get my code to go eleven and therefore I wrote a small data-downloader class. It has one method, well two: one oldskool function with a completionHandler, and one new style async/await one.
When using the oldskool one, it works as everyone would expect:
print(1)
dataFetcher.fetchSomeData
{
print(2)
let data = $0
// process data ...
print(3)
}
print(4)
The output is, unsurprisingly:
1
4
2
3
Now, when I use my new style function:
let data = await dataFetcher.fetchSomeData()
// process data ...
Xcode gives me an error:
'async' call in a function that does not support concurrency
That makes sense, I am calling this in the viewDidLoad() method of a UIViewController subclass. Can't mark viewDidLoad() as await, as super's implementation is not async. No problem, let me wrap it in Task:
print(1)
Task
{
print(2)
let data = await dataFetcher.fetchSomeData()
// process data ...
print(3)
}
print(4)
No errors, and this code works exactly as expected, the output is:
1
4
2
3
So now I am wondering: why take the effort of changing/adding code for async/await style function that ultimately end up requiring exactly the same amount of code, and is exactly as non-linear as completionHandlers?
Note that the dataFetcher only has one property, an instance ofURLSession, so I am also not even managing my own queues or threads in the oldskool method vs the new one. They just wrap URLSession's functions:
func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
and
func download(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil) async throws -> (URL, URLResponse)
Is async/await useful only with SwiftUI maybe? What am I missing here? Please help me see the light.
Hello,
I wrote a simple email validation test:
struct ContentView: View {
@State private var email: String
@State var emailIsValid: Bool = true
public init(email: String = "")
{
self.email = email
}
var body: some View {
Text("Hello, world!")
.padding()
TextField("Email", text: $email)
.onChange(of: email) { newValue in
if(newValue.range(of:"^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", options: .regularExpression) != nil) {
self.emailIsValid = true
print("valid")
} else {
self.emailIsValid = false
print("invalid")
}
}
.foregroundColor(emailIsValid ? Color.green : Color.red)
}
}
And it works for the email like Test@gmail.com. Text is green.
But if I type something like Testerka@gmail.com text stays red. But the print output says 'valid'.
Hi,
Xcode warns me that NSPersistentContainer, NSManagedObjectContext, NSPersistentHistoryTransaction and NSPersistentHistoryToken are non-Sendable types and therefore cannot cross actor boundaries.
These warnings occur even when I use @preconcurrency import CoreData (only works with Xcode 14.0 Beta, in Xcode 13.4.1, it says '@preconcurrency' attribute on module 'CoreData' is unused)
I understand that types in Core Data have yet to be marked as Sendable when it makes sense.
Although NSPersistentHistoryTransaction, and NSPersistentHistoryToken are reference types, they should qualify to be marked as Sendable in the future since these are immutable types, am I right?
NSPersistentContainer provides variables and methods like viewContext and newBackgroundContext(). It would make sense that this type is thread-safe. However, I'm not sure about it, especially regarding its loadPersistentStores(completionHandler:) method. Is NSPersistentContainer (and its subclass NSPersistentCloudKitContainer) thread-safe and should it be marked as Sendable in the future?
The case of and NSManagedObjectContext confuses me the most. Indeed, it has both thread-safe methods like perform(_:) and thread-unsafe methods like save(). Still, it should be possible to cross actor boundaries. Would such a "partially thread-safe" type quality to be marked as Sendable? If not, how can it cross actor boundaries?
The reason I'm asking these questions is that I have a CoreDataStack type.
It has mutable variables, such as var lastHistoryToken: NSPersistentHistoryToken?, needs to perform work without blocking the main thread, such as writing the token to a file, has async methods, uses notification observers, and needs to be marked as Sendable to be used by other controllers running on different actors.
Since this type is related to back-end work, I made it an Actor. This type exposes the persistent container, and a method to create new background threads.
However, I need to explicitly annotate all methods using await context.perform { ... } as nonisolated in this actor. Not doing so causes a data race to be detected at runtime. Is this a bug, and is making a Core Data stack an Actor the proper way to do it or is there a better solution?
Any help would be greatly appreciated.
Thanks.
Xcode Configuration
Xcode 13.4.1, Xcode 14.0 beta 5
The Xcode project is configured with Other Swift Flags set to -Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks.
Hi,
It seems that there's a bug in the iOS and iPadOS 16 betas (i've not test in macOS 13 yet), that when after updating a List data source with a bigger array, scrolling to a row of an offset bigger than the previous data array, with ScrollViewProxy, will crash the app with an EXC_BREAKPOINT (code=1, subcode=0x1099d6004) error.
Below I attached a sample code to reproduce the crash. In it when opening there's an empty list. When pressing the "Randomize & Select Last" button at the top, the list will be filled with 5 random UUIDs, followed by scrolling to the last row. The app will crash on the second try, when it will try to scroll to an offset bigger than the previous data array (the last row).
As a control there's an "Randomize & Select Random" button that will behave more or less like the "Randomize & Select Last" button but will choose a random row to select and scroll. It will only crash if this select row if of an offset bigger that the size of the previous array.
This doesn't happen in iOS 15.
I've already posted the Radar as FB11302966, however if someone has any toughs on how to solve this problem (or what I'm doing wrong) they are welcome.
Sample code:
///A simple data model for the demo. Only stores an UUID.
struct DataModel: Identifiable, Hashable {
let id: UUID = UUID()
var nameUUID: String {
id.uuidString
}
}
struct ContentView: View {
///Array with some data to show
@State private var data: [DataModel] = []
///Selected row
@State private var selection: DataModel?
var body: some View {
VStack(alignment: .leading) {
HStack {
//Create a new array for showing in the list.
//This array will be bigger than the last one.
//The selection will be the last element of the array (triggering the bug)
Button {
//Increment the size of the new List by 5
let numberElements = data.count + 5
//Create a new Array of DataModel with more 5 elements that the previous one
let newData = (0 ..< numberElements).map { _ in DataModel() }
//Select the last element of the array/list.
//This will make sure that the scrollTo will go to the end
let newSelection = newData.last
//Update STate for the new values
data = newData
selection = newSelection
} label: {
Text("Randomize & Select Last")
}
Spacer()
//Create a new array for showing in the list.
//This array will be bigger than the last one.
//The selection will be the a random element of the array (only triggering the bug when the element is )
Button {
//Increment the size of the new List by 5
//If empty will start with 40 (reducing the odds of triggering the bug)
let numberElements = data.count == 0 ? 40 : data.count + 5
//Create a new Array of DataModel with more 5 elements that the previous one
let newData = (0 ..< numberElements).map { _ in DataModel() }
//Select a random element of the array/list.
//This will scroll if the element is 'inside' the previous list
//Otherwise will crash
let newSelection = newData.randomElement()
//Update State for the new values
data = newData
selection = newSelection
} label: {
Text("Randomize & Select Random")
}
}
.padding()
//MARK: ScrollViewReader and List
ScrollViewReader {
proxy in
List(data, selection: $selection) {
dataElement in
//Row (is only the UUID for the rows
Text(dataElement.id.uuidString)
.id(dataElement)
.tag(dataElement)
}
//action that fires when data changes
//it will scroll to the selection
.onChange(of: data, perform: { newValue in
if let selection {
proxy.scrollTo(selection)
}
})
}
}
}
}
Hola, tengo un problema con una app enterprise el cual me arroja un mensaje cuando termina de instalarse (No se pudo instalar "My-App" intente mas tarde), solo es con iOS 16 BETA, si el ipa se instala desde xcode no existe ningun problema, solo es cuando se distribuye mendiante storage de Google, Alguien le sucede algo similar ?
Hi all,
I am trying to use the new CarPlay Simulator (the one provided with the Xcode Additional Tools) to test an application that uses a protocol string. My question is: is there a way to edit this protocol string on this application? Because as of right now, my app is not shown in the CarPlay Simulator, as it does not have the required protocol string.
I've used the Xcode simulator, and protocol strings can be added using:
defaults write com.apple.iphonesimulator CarPlayProtocols -array-add <protocol-string>
But I've not found a way to do this on the standalone application.
Thank you all in advance
I'm testing network loss handling in my app on the simulator.
Turning WiFi OFF triggers pathUpdateHandler with .unsatisfied status.
Turning WiFi back to ON triggers pathUpdateHandler with .unsatisfied status again.
I noticed that pathUpdateHandler is triggered right after I enabled WiFi, but before WiFi actually connects to the network. When the laptop is actually connected to the WiFi network - pathUpdateHandler isn't triggered, so my app stays in "offline" mode permanently.
networkMonitor.pathUpdateHandler = { [weak self] path in
guard let self = self else { return }
DispatchQueue.main.async {
if path.status == .satisfied {
self.status = .connected
} else {
print(path.unsatisfiedReason)
self.status = .disconnected
}
}
}
monitor.start(queue: queue)
networkMonitor is retained by my DIContainer
Xcode13.4.1 is running properly, but after upgrading Xcode14, the debugging device reports an error: Library not loaded: / usr/lib/swift/libswiftCoreGraphics dylib, I according to the online solutions are tried, can't solve my problem, problem is ios10.3.3 equipment, unable to debug, also is unable to start the application success after packaging, Is this a problem with xcode14 itself?
Hi
Can anyone help me out with this extra white space showing in dynamic island iPhones?
Any help is much appreciated.
Thanks.
Recently I updated to Xcode 14.0. I am building an iOS app to convert recorded audio into text. I got an exception while testing the application from the simulator(iOS 16.0).
[SpeechFramework] -[SFSpeechRecognitionTask handleSpeechRecognitionDidFailWithError:]_block_invoke Ignoring subsequent recongition error: Error Domain=kAFAssistantErrorDomain Code=1101 "(null)"
Error Domain=kAFAssistantErrorDomain Code=1107 "(null)"
I have to know what does the error code means and why this error occurred.
Trying to use file importer in a swift app to upload documents into firebase Storage and getting error when running on live device but works perfectly fine on emulator.
error:
BackgroundSession <***...> Failed to issue sandbox extension for file
file:///private/var/mobile/Library/Mobile%20Documents/comappleCloudDocs/Sample.pdf, errno = [1: Operation not permitted]
UNKNOWN ERROR Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response." UserInfo={object=Repository/Sample.pdf, ResponseBody=Can not finalize upload. Current size is 0. Expected final size is 2665098., bucket=bucket, data={length = 77, bytes = 0x43616e20 6e6f7420 66696e61 6c697a65 ... 32363635 3039382e }, data_content_type=text/plain; charset=utf-8, NSLocalizedDescription=An unknown error occurred, please check the server response., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=400}
I tried separating all the logic from selectedFile.startAccessingSecurityScopedResource() all the way through the end into a function of its own using @MainActor based on another post I found around here and issue persisted..
Below is the implementation:
.fileImporter(
isPresented: $fileImporterIsPresented,
allowedContentTypes: [.pdf],
allowsMultipleSelection: false
) {
result in
switch result
{
case .success(let url):
print(url)
guard let selectedFile:URL = url.first else { return }
guard selectedFile.startAccessingSecurityScopedResource() else
{
return
}
let firebaseRepository = Storage.storage().reference().child("Repository/Sample.pdf")
let uploadTask = firebaseRepository.putFile(from: selectedFile)
uploadTask.observe(.progress)
{
snapshot in
// Upload reported progress
percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
}
uploadTask.observe(.success)
{
snapshot in
selectedFile.stopAccessingSecurityScopedResource()
uploadTask.removeAllObservers()
print("SUCCESS")
// Upload completed successfully
}
uploadTask.observe(.failure)
{
snapshot in
if let error = snapshot.error as? NSError
{
switch (StorageErrorCode(rawValue: error.code)!)
{
case .objectNotFound:
print("NOT FOUND")
// File doesn't exist
break
case .unauthorized:
print("UNAUTHORIZED")
// User doesn't have permission to access file
break
case .cancelled:
print("CANCELLED")
// User canceled the upload
break
/* ... */
case .unknown:
print("UNKNOWN ERROR \(error.description)")
print("UNKNOWN ERROR \(error.localizedDescription)")
print("UNKNOWN ERROR \(error.underlyingErrors)")
// Unknown error occurred, inspect the server response
break
default:
print("UNSPECIFIED ERROR")
// A separate error occurred. This is a good place to retry the upload.
break
}
}
}
case .failure(let error):
print(error)
}
}
Hi,
do you know if it's possible to handle the flashlight inside DataScannerViewController?
I tried with AVCaptureDevice.DiscoverySession, but clearly when torchmode is on DataScannerViewController freeze...
Thanks
Luca
Hi,
I am working on an iPad application that has both Portrait and Landscape orientation. The issue that I am facing is regarding the the popup presentation that iPad shows you for saving password while you log-in in the application.
Now, when the pop-up is presented, at that moment if I try to rotate the device, the application crashes with the message
Application tried to present modally a view controller <_SFAppPasswordSavingViewController: 0x107be7230> that is already being presented by <UIKeyboardHiddenViewController_Save: 0x107a49190>.
Now, the problem is that SFAppPasswordSavingViewController presentation is not controlled by me. Also UIKeyboardHiddenViewController_Save,is something I am not controlling.
Please help me out on how to solve this issue or let me know if I am missing anything.