Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casting to Task without specifying generic type #36

Open
adrianhr91 opened this issue Aug 4, 2016 · 3 comments
Open

Casting to Task without specifying generic type #36

adrianhr91 opened this issue Aug 4, 2016 · 3 comments

Comments

@adrianhr91
Copy link

adrianhr91 commented Aug 4, 2016

I'm trying to create a universal error handler for my application and to make matters even more complicated I'm using an event bus to pass a task around. I'm trying to do the following:

let apiTask = data.object as! Task // Option 1
let apiTask = data.object as! Task<AnyObject> // Option 2

apiTask!.continueWith { (task) in
    if(task.cancelled || task.faulted) {
        self.isInError = true
    } else {
        self.isInError = false
    }
}

Option 1 gives a compile time error saying the generic type TResut of Task cannot be inferred.
Option 2 causes a runtime error saying Task<SpecificType> cannot be caster to Task<AnyObject>

I have the same implementation in Java where it seems you don't need to specify the generic type so I appreciate this might be a language limitation rather than a library one. TResult could be potentially any type so I can't specify it in the method above. Is there any way to work around this?

@xxtesaxx
Copy link

xxtesaxx commented Nov 18, 2016

Hello,
I'm completely new to Bolts and also a beginner in swift so maybe this might be completely wrong but wouldn't it be possible to create a struct or class called e. g. "MyTaskResult" to wrap your actual result?

I just gave it a quick try and it seems to work:

func printHelloWorld() {
    doSomething().continueWith() { task in
        print(task.result?.result)
    }
}

func doSomething() -> Task<MyResult> {
    let tcs = TaskCompletionSource<MyResult>()
    ...
    tcs.set(result: MyResult(result: "Hello World" as AnyObject))
    ...
    return tcs.task
}

struct MyResult {
    var result: AnyObject
}


Surely there is a better way of doing this but this, I think, could at least work somehow.

@appacea
Copy link

appacea commented Nov 16, 2018

Hi. Any updates on this? I'm running into the same problem.

I'm porting my code from Objc to Swift and have a function like this:

(void) handleException:(BFTask*)task{}

converted to Swift:

func handleException(_ task: Task)()

In ObjC the input can be any BFTask but in Swift I get the "Task cannot be caster to Task" error mentioned above by @adrianhr91 .

@xxtesaxx solution is a smart approach but requires the use of AnyObject in the input rather than a specific type.

@appacea
Copy link

appacea commented Nov 16, 2018

I ended up going a different route, by using an extension I can create a function in the Task Class that can be called from any generic Task. So instead of a function that takes a generic Task as input, I have a function that is a prototype of a generic Task.

extension Task{
func handleException()()
}

This way handleException() can be called on any Task

Hope that helps someone else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants