-2

I'm trying to grab a string from a textfile and test the contents of it and return a Bool if it is equal to something. I can't figure out how to return the Bool and keep getting an error message.

Cannot convert return expression of type 'Task<Bool, any Error>' to return type 'Bool'

func checkStatus() {
    if test() {
        //// do this
    }
}

func test()  -> Bool {
    Task.init  {
        myResult = try await grabString()
        if myResult == "ConnectionOK" {
            return true
        }
        return false
    }
}

func grabString() async throws -> String {
    var myString: String = ""
    let url = URL(string: "https://www.blah blah blah.txt")
    if let url = url {
        let req = URLRequest(url: url)
        let (data, _) = try await URLSession.shared.data(for: req)
        myString =  String(data: data, encoding: .utf8)!
    }
    return myString
}

}

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
slicerdicer
  • 155
  • 1
  • 10
  • 3
    You have not understood what asynchronous means. You cannot return anything from inside a Task to outside the Task unless the outside is also async. When your `test` returns its Bool, your Task hasn't even started. – matt Sep 27 '22 at 11:22
  • Yep, I get that, but how do I send a bool message to somewhere else in my code as to the result of the test? – slicerdicer Sep 27 '22 at 11:40
  • It seems your example code is not your real code, is it? So please provide the code for the real issue you try to solve here. Please read [ask] and try to provide a [mre] – burnsi Sep 27 '22 at 11:48
  • I don't understand "is not your real code". It's exactly the code I'm trying to use, but I get a compiler error..Cannot convert return expression of type 'Task' to return type 'Bool' Why is this downvoted? – slicerdicer Sep 27 '22 at 12:00
  • `I don't understand`. I have answered regarding to the code you provided. But then you commented you need to return a boolean for `checkStatus` and want to "send" it to somewhere. Nothing of this is reflected in your question. And for the downvotes: I didn´t downvote, but I would think asking a question about a pretty common programming pattern and also not providing the whole context could lead to downvotes. – burnsi Sep 27 '22 at 12:07
  • Okay, I'll try to ask this a different way: I have an app that needs to periodically check for connectivity to a server. The way I want to do this is to check for a the specific contentns of a textfile that exists on the server. Throughout the app I want to do: If checkStatus() { /// app is online and connected to server //// do something } else { print("check internect connectivity and try again" } I was hoping I could have a "generic" async / await type func. Sorry for being a bit obtuse but I don't post here often. – slicerdicer Sep 27 '22 at 13:14
  • Why didn't you ask that? – matt Sep 27 '22 at 13:44
  • why should he have to? the question as stated is enough to describe what he wants to do. the *reasoning* as to *why* he wants to do that is not for any of us to judge or comment on. the comment he left is more info, but not more info to solve the question. SMH at SO again. – Zonker.in.Geneva Mar 12 '23 at 21:58

1 Answers1

2

If you have a function with a single line, then that is taken as the implicit return of the function. So e.g.

func foo() -> String {
    "foo"
}

returns "foo" without having to say "return"

In your function you are returning a Task in the same way:

func test()  -> Bool {
    Task.init  {
        myResult = try await grabString()
        if myResult == "ConnectionOK" {
            return true
        }
        return false
    }
}

But you need to return a Bool. A task is not a bool, obviously. You can't return a bool because you need to call grabString and grabString is async.

That means you have to make your function async too:

func test() async -> Bool {
    do {
        let myResult = try await grabString()
        return myResult == "ConnectionOK"
    }
    catch {
        // TODO handle error
        return false
    }
}

Then you can call it from an async context, like from within a Task:

func checkStatus() {
    Task {
        let value = await test()
        print(value)
    }
}
Shadowrun
  • 3,572
  • 1
  • 15
  • 13
  • That's perfect. Thank you. But another issue... is the result cached somewhere because when the device is in AIrplane Mode, the call still returns connected and returns True. – slicerdicer Sep 27 '22 at 16:43
  • You're using URLSession.shared, see for example https://stackoverflow.com/questions/24328461/how-to-disable-caching-from-nsurlsessiontask – Shadowrun Sep 28 '22 at 08:04