Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static generic extension for Array for help function for iterated async callbacks

Tags:

swift

I have two help methods that I want to move to an extension to increase it's reusability. The two methods manages multiple callbacks when calling parallell http request. However when making the methods static and moving them to an extension I get this error:

Cannot convert value of type '[Action]' to expected argument type '[_]'

The code is

extension Array
{
    private static func iterateObjectList<Type>(objectList:[Type], multiplier:Int=1, foreach:(object:Type, (newObject:Type?, error:NSError?) -> Void) -> (), finally: (objectList:[Type], errorList:[NSError]) -> Void)
    {
        var iterationsLeft = objectList.count * multiplier
        var errorList:[NSError] = []
        var returnObjectList:[Type] = []
        if (iterationsLeft == 0) {
            finally (objectList:objectList, errorList:[])
        }
        for object:Type in objectList {
            foreach (object:object, { (requestObject, requestError) -> Void in

                iterationsLeft -= 1
                if (requestError != nil) {
                    errorList.append(requestError!);
                }
                if (requestObject != nil) {
                    returnObjectList.append(requestObject!)
                }
                if (iterationsLeft <= 0) {
                    finally (objectList:returnObjectList, errorList:errorList)
                }
            })
        }
    }

    private static func simpleIterate<Type>(objectList:[Type], multiplier:Int=1, foreach:(object:Type, Void -> Void) -> (), finally: Void -> Void)
    {
        var iterationsLeft = objectList.count * multiplier

        if (iterationsLeft == 0) {
            finally ()
        }
        for object:Type in objectList {
            foreach (object:object, { Void -> Void in

                iterationsLeft -= 1
                if (iterationsLeft <= 0) {
                    finally ()
                }
            })
        }
    }
}

The error is when using the methods:

Array.iterateObjectList(actions, foreach: { (action, iterationComplete) -> () in
    self.fetchStatusAndUpdateAction(action, callback: { (error) -> Void in
        iterationComplete(newObject: action, error:error)
    })
}, finally: { (objectList, errorList) -> Void in
    callback(error: errorList.first)
})

where actions is of type [Action] where Action is a custom object.

like image 393
Sunkas Avatar asked Apr 27 '26 14:04

Sunkas


1 Answers

The problem is that

public struct Array<Element> 

is a generic type, and in

Array.iterateObjectList(actions, foreach: { (action, iterationComplete) -> () in
    // ...
}, finally: { (objectList, errorList) -> Void in
    // ...
})

the compiler cannot infer what Element should be. You could make it compile as

Array<Action>.iterateObjectList(actions, foreach: { (action, iterationComplete) -> () in
    // ...
    }, finally: { (objectList, errorList) -> Void in
    // ...
})

or even

Array<Int>.iterateObjectList(...)

The array Element is unrelated to your generic placeholder Type, so any type will do.

But the better solution would be to make the static method an instance method:

func iterateObjectList(multiplier:Int=1, foreach:(object:Element, (newObject:Element?, error:NSError?) -> Void) -> (), finally: (objectList:[Element], errorList:[NSError]) -> Void)
{
    // Your code with `Type` replaced by `Element`,
    // and `objectList` replaced by `self`.
    // ...
}

and call it on the actions array:

actions.iterateObjectList(foreach: { (action, iterationComplete) -> () in
    // ...
    }, finally: { (objectList, errorList) -> Void in
    // ...
})
like image 138
Martin R Avatar answered Apr 29 '26 04:04

Martin R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!