pixelglow / ZipZap

zip file I/O library for iOS, macOS and tvOS
BSD 2-Clause "Simplified" License
1.22k stars 199 forks source link

replaceWithChannel:channel:error method in ZZDataChannel.m fails in Swift 3 #148

Open ilyakaz opened 8 years ago

ilyakaz commented 8 years ago

ivar _allData is declared as NSData and is being cast to NSMutableData in this method in order to call setData on it. This operation fails at runtime in Swift 3 with the error: [Foundation._SwiftNSData setData:]: unrecognized selector sent to instance.

The solution appears to be to declare _allData as NSMutableData instead, which is what it should have probably been declared to begin with.

pixelglow commented 8 years ago

I admit the internal ZZDataChannel API isn't ideal. It does double duty initialised with NSData or NSMutableData and so sometimes gets into an inconsistent state as you've noticed.

We should have a ZZDataChannel and a ZZMutableDataChannel instead -- the ZZDataChannel can then throw errors for inappropriate write operations. Then ZZArchive could be initialised with NSMutableData as an alternative, which leads to the creation of a ZZMutableDataChannel.

The write operations that should result in errors in the fixed ZZDataChannel are temporaryChannel:, replaceWithChannel:error:, removeAsTemporary and newOutput:.

Anyone interested in working on a fix? I'll leave this open for discussion for a week or two.