1

Being fairly new to Swift I decided I would look at extending Array (or more specifically [SKTexture] Arrays of SKTexture) with a function to add a specified number of frames from the application bundle.

// FRAMES
FuzzyRabbit_0001@2x.png
FuzzyRabbit_0002@2x.png
FuzzyRabbit_0003@2x.png
FuzzyRabbit_0004@2x.png

// CALL
var rabbitTextures = [SKTexture]()
self.rabbitTextures.textureFromFrames("FuzzyRabbit", count: 4)

My first attempt is listed below, I am getting the error Cannot invoke 'append' with an argument list of type '(SKTexture!)' which from looking at the function fuzzyPush is because I am trying to append an SKTexture rather than the generic T.

Is this possible, or am I limited by the fact that I don't want the function to be generic but rather specific to Arrays of SKTexture.

extension Array {

    // ONLY SKTexture
    mutating func textureFromFrames(imageName: String, count: Int) {
        if !(self[0] is SKTexture) { return }
        for index in 1...count {
            let image = String(format: "\(imageName)_%04d", index)
            let texture = SKTexture(imageNamed: image)
            self.append(texture) // ERROR: Cannot invoke append with an argument list of type SKTexture!
        }
    }

    // WORKS FINE
    mutating func fuzzyPush(newItem: T) {
        self.append(newItem)
    }
}

I was just curious if this is something I could do with an extension, its not a problem as I have this as a function that takes 3 parameters (imageName, count, arrayToAppend) so I can quite easily use that.

fuzzygoat
  • 26,573
  • 48
  • 165
  • 294
  • Compare http://stackoverflow.com/questions/29929497/how-can-i-create-an-extension-method-that-only-applies-to-arrays-of-nullable-ite and the references in the comments. You cannot write an extension method only for a specific type of array. – Martin R Apr 29 '15 at 13:23

2 Answers2

2

This extension is not possible to write today. You cannot apply an extension method to only certain types of arrays.

There are two good solutions. You can use a HAS-A pattern by creating a struct (TextureList) that contains a [SKTexture], or you can use a function.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
1

You can replace :

self.append(texture)

with

self.append(texture as T)

I checked this on an array of strings though and it worked. About the first check add another check to see if the array is empty otherwise the self[0] is SKTexture will fail.

This is the code I tested on an online swift compiler (SKTexture was not available obviously) :

extension Array {

    mutating func textureFromFrames(imageName: String, count: Int) {
        for index in 1...count {
            let image = String(format: "\(imageName)_%04d", index)
            self.append(image as T) 
        }
    }
}


var arr = Array<String>()
arr.textureFromFrames("testing", count:4)

for tmp in arr {
    println("\(tmp)")
}
giorashc
  • 13,691
  • 3
  • 35
  • 71