Swift Code problem

Hank Moody
Hank Moody used Ask the Experts™
on
I'm following this tutorial: https://medium.com/swift2go/building-grpc-client-ios-swift-note-taking-app-6133c7d74644
The problem is I can't understand what exactly is happening in the following code:

func listNotes(completion: @escaping([Note]?, CallResult?) -> Void) {
        _ = try? client.list(Empty(), completion: { (notes, result) in
            DispatchQueue.main.async {
                completion(notes?.notes, result)
            }
        })
   }

Open in new window


I need someone to explain me the above piece of code in detail.
Can anyone please help?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Robb HillSenior .Net Full Stack Developer

Commented:
Maybe you shoulf not use swift:)

If I am reading this properly this is an async call that upon completion will always return a value or result.  I do not see the full context just by reading this function but it seems to be handling nulls , etc for the return value as well.  The queue should remain open until a response is handled.
Robb HillSenior .Net Full Stack Developer

Commented:
better yet..their explanation is better.

Our main screen is List Notes Screen that display list of notes in UITableView. We will use the DataRepository to get the Notes from the gRPC Server, so let’s add the listNotes function to the DataRepository that accepts a completion handler for notes and CallResult. Inside the function is invokes the client list function passing Empty Request as the parameter, in the completion handler, it provides 2 optional arguments, notes and result. The result is a CallResult object indicating whether theres is an error. For simplicity we just invoke our completion handler passing the notes array.

Author

Commented:
What is "notes?.notes" in the code exactly? It is mentioned that it is an optional arguments so what does "notes?.notes" means? Why not use just "notes" ?
Shahan AyyubSenior Software Engineer

Commented:
You can find details in comment over each line of code. I tried to be as detailed as possible, if you need anything else please let me know.

// We are defining a function named ‘listNotes’ that will take an escaping block and will not return any value.
// In block the values return would be of type ’Note’ object which can be optional (?) that means it may hold a value 
// or can be nil, and another parameter of type ‘CallResult’ which is also an optional.
// For @escaping: https://medium.com/@bestiosdevelope/what-do-mean-escaping-and-nonescaping-closures-in-swift-d404d721f39d
func listNotes(completion: @escaping([Note]?, CallResult?) -> Void) { 

            // Here ‘_’ means that ‘client.list’ function will return a value but we are ignoring it intentionally.
            // for 'try?’ : https://stackoverflow.com/questions/32390611/try-try-try-what-s-the-difference-and-when-to-use-each
            // ‘client.list’ function supports two parameters, first `Empty()` seems to be a custom function that 
            // will probably return an initialised list which will be filled by ‘client.list’, second is the completion handler block
            // that gives two values notes object and result object.
            _ = try? client.list(Empty(), completion: { (notes, result) in     

                    // Here we are trying to return the result to the point from where function ‘listNotes' was called.
                    // We want to return that value in a main thread so if the caller function want to populate it in UI
                    // UI thread issue do not appear. Something like this: Terminating app due to uncaught exception 'GMSThreadException', reason: 'The API method must be called from the main thread'
                    // Here ’notes?’ shows ’notes’ is an optional value so it may either a value or ‘nil'
                    // So 'optional chaining’ were used to access a property ’notes’ under object ’notes’. If first
                    // ‘notes’ is nil the second ’notes’ will not be determined and will be taken as ‘nil’.
                    DispatchQueue.main.async { completion(notes?.notes, result) 
                    
                    }     
    })
 }

Open in new window


Hope it helps!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial