CKDatabase save(_:completionHandler:) has a box that says the following below. Yet when I run the method, the completionHandler runs after the print statement after the call to the save method. I noticed the declaration of the method to be run synchronously has an escaping completionHandler. If the method is run synchronously, doesn't using an escaping completionHandler defeat the purpose of executing the method synchronously, or is the documentation wrong and the method is actually run asynchronously both ways?
Concurrency Note
You can call this method from synchronous code using a completion handler, as shown on this page, or you can call it as an asynchronous method that has the following declaration:
func save(_ record: CKRecord) async throws -> CKRecord
For information about concurrency and asynchronous code in Swift, see Calling Objective-C APIs Asynchronously.
Here is my essential code with the nonessentials taken out:
print("*** 1 before self.privateCloudKitDatabase.save(record)")
self.privateCloudKitDatabase.save(record) {
recordReturned, errorReturned in
print("*** 2 closure self.privateCloudKitDatabase.save(record)")
}
print("*** 3 after self.privateCloudKitDatabase.save(record)")
Here's the debug window:
*** 1 before self.privateCloudKitDatabase.save(record)
*** 3 after self.privateCloudKitDatabase.save(record)
. . . (other print statements)
*** 2 closure self.privateCloudKitDatabase.save(record)
Post
Replies
Boosts
Views
Activity
Is there a way to go to a specific line number in a swift file or any file in Xcode or Playground? I don't know if the search feature will do that and I haven't been able to find any help in the Help menu.
I'm getting a runtime error in Playground that tells me to run an lldb command. I am not able to type anything in the debug area of Playground as I can in Xcode. How do I use lldb with Playground.
Specifically, the error I'm getting is:
error: Execution was interrupted, reason: shared-library-event. The process has been left at the point where it was interrupted, use "thread return "-x"" to return to the state before expression evaluation.
I'm able to see some of the "stack trace", I think is what it is, when I click on the icon of an eye on the right side of the code editor in Playground, but it only shows a small portion it.
I am using Playground, and I am able to set breakpoints in a file in the Source folder, but code execution doesn't stop at the breakpoints. I know the code runs to those points, because there are print statements that print into the debug area that are placed between those breakpoints.
What should I do? Is there a setting that would fix this?
0
How would I update a table view row as as a text field text changes? It is difficult to create a string from the arguments in textField(:shouldChangeCharactersIn:replacementString:) so that the string I create would be equal to the string value of the text property of the text field after the textField(:shouldChangeCharactersIn:replacementString:) occurs. Is there a way to use the UITextInput protocol of UITextField? I haven't found anything on stackoverflow about using the UITextInput protocol of UITextField except a question in 2012 using Objective-C that asks why he's getting a crash.
What is the most effective approach to to creating a type of "wizard" interface that takes the user through a process step-by-step, and allows the user to take the steps in any order as he goes along? For instance, the user could start out by selecting from three options: select contacts, select addresses, or selecting a message to send. When he selects one of those options, say select contacts, he sees the interface to allow him to perform that selection, and he sees the other two options to select at any time, which would be select addresses and select message. Say he then selects the option to select a message, he then sees an interface to selecta message and he also sees the other two options. And this continues indefinitely until he selects to send the message.
I think the usual view controllers and segues would work for this. Would I need only one subclass of UINavigationController and three subclasses of UIViewControllers? Could this lead to any problems? Is it possible to do this with view controllers and segues? Is there a better way?
I do use Swift, but this question doesn't require that I use only Swift, as you can see.
Why am I not seeing the message instance property of MFMessageComposeViewController? When I type the following, I get a code-time error message in Xcode that says "Value of type 'MFMessageComposeViewController' has no member 'message'"
messageComposeViewController.message // error message: "Value of type 'MFMessageComposeViewController' has no member 'message'"
There is nothing that explains this in the official Apple documentation: Documentation/Message UI/MFMessageComposeViewController/message
The documentation for DispatchQueue.AutoreleaseFrequency.workItem says , "The queue configures an autorelease pool before the execution of a block, and releases the objects in that pool after the block finishes executing."
Does this mean that the dispatch queue releases each work item or each code in ()->Void after each one finishes executing? When it says, "releases the objects in that pool er the block finishes executing", it makes it sound like there is only one block executing and then the entire pool is released. I'm making sure I verify that I understand this correctly.
Is there always only one local CNContainer on any iOS device whether the user is logged in to iCloud or not, and whether the device is an iPhone or an iPad?
I'm curious why I don't see posts about Xcode crashing. Since I updated both macOS Monterey 12.6 and Xcode 14, Xcode repeatedly crashes, becoming more frequently, even within 20 seconds between the last two crashes.
Am I the only one getting these crashes?
I've been using the CloudKitShare sample code found here as a sample to help me write code for my app. I want to use performWriterBlock and performReaderBlockAndWait as found in BaseLocalCache using a completionHandler without violating the purposes of the design of the code, which focuses on being thread-safe. I include code from CloudKitShare below that are pertinent to my question. I include the comments that explain the code. I wrote comments to identify which code is mine.
I would like to be able to use an escaping completionHandler if possible. Does using an escaping completionHandler still comply with principles of thread-safe code, or does it in any way violate the purpose of the design of this sample code to be thread-safe? If I use an escaping completionHandler, I would need to consider when the completionHandler actually runs relative to other code outside of the scope of the actual perform function that uses the BaseLocalCache perform block. I would for one thing need to be aware of what other code runs in my project between the time the method executes and the time operationQueue in BaseLocalCache actually executes the block of code and thus the completionHandler.
class BaseLocalCache {
// A CloudKit task can be a single operation (CKDatabaseOperation)
// or multiple operations that you chain together.
// Provide an operation queue to get more flexibility on CloudKit operation management.
//
lazy var operationQueue: OperationQueue = OperationQueue()
// This sample ...
//
// This sample uses this dispatch queue to implement the following logics:
// - It serializes Writer blocks.
// - The reader block can be concurrent, but it needs to wait for the enqueued writer blocks to complete.
//
// To achieve that, this sample uses the following pattern:
// - Use a concurrent queue, cacheQueue.
// - Use cacheQueue.async(flags: .barrier) {} to execute writer blocks.
// - Use cacheQueue.sync(){} to execute reader blocks. The queue is concurrent,
// so reader blocks can be concurrent, unless any writer blocks are in the way.
// Note that Writer blocks block the reader, so they need to be as small as possible.
//
private lazy var cacheQueue: DispatchQueue = {
return DispatchQueue(label: "LocalCache", attributes: .concurrent)
}()
func performWriterBlock(_ writerBlock: @escaping () -> Void) {
cacheQueue.async(flags: .barrier) {
writerBlock()
}
}
func performReaderBlockAndWait<T>(_ readerBlock: () -> T) -> T {
return cacheQueue.sync {
return readerBlock()
}
}
}
final class TopicLocalCache: BaseLocalCache {
private var serverChangeToken: CKServerChangeToken?
func setServerChangeToken(newToken: CKServerChangeToken?) {
performWriterBlock { self.serverChangeToken = newToken }
}
func getServerChangeToken() -> CKServerChangeToken? {
return performReaderBlockAndWait { return self.serverChangeToken }
}
// Trial: How to use escaping completionHandler? with a performWriterBlock
func setServerChangeToken(newToken: CKServerChangeToken?, completionHandler: @escaping (Result<Void, Error>)->Void) {
performWriterBlock {
self.serverChangeToken = newToken
completionHandler(.success(Void()))
}
}
// Trial: How to use escaping completionHandler? with a performReaderBlockAndWait
func getServerChangeToken(completionHandler: (Result<CKServerChangeToken, Error>)->Void) {
performReaderBlockAndWait {
if let serverChangeToken = self.serverChangeToken {
completionHandler(.success(serverChangeToken))
} else {
completionHandler(.failure(NSError(domain: "nil CKServerChangeToken", code: 0)))
}
}
}
}
How do I get my iOS app to run code when something specific in a message in Messages happens, like a specific phone number sends a specific phrase?
When I go to the Shortcuts app and add an action, there is a tab that lets me see Apps that has actions I can use. How do I make my iOS app be able to contribute actions for users to use in a shortcut, so that a user creating a shortcut can add an action that does something in my app?
An example of this is the Walmart app. A user can create use an action that allows him to check in.
Is there a way to use code pin iOS to pin a message to the top in the Messages app?
Is there a way for me to put my iOS app in side of the shared with you?