Swift 3 Compiler Error : 'bytes' is unavailable: use withUnsafeBytes instead

2.2k views Asked by At

I have an encrypting method in Swift 2.2. How can I get bytes from data in Swift 3?

Here is my code:

func myEncrypt(encryptData:String) -> String? {

    //security key must be 24charachters 
    let myKeyData : Data = "*******".data(using: String.Encoding.utf8)!
    let myRawData : Data = encryptData.data(using: String.Encoding.utf8)!
    let mykeydatamd5 = Data(bytes: myKeyData.bytes, count: 24)
    let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, mykeydatamd5.bytes   , keyLength, nil, myRawData.bytes, myRawData.count, buffer, buffer_size, &num_bytes_encrypted)

    if UInt32(Crypto_status) == UInt32(kCCSuccess){

        let myResult: Data = Data(bytes: buffer, count: num_bytes_encrypted)        
        free(buffer)

        return myResult.base64EncodedString()

    }else{

        free(buffer)        
        return nil

    }       
}

The error occurs in myKeyData.bytes and myRawData.bytes.

2

There are 2 answers

0
OOPer On

As shown in the error message, you need to use withUnsafeBytes instead.

Generally, if you have some expression like this:

let result = someFunc(..., data.bytes, ...)

You need to rewrite it as:

let result = data.withUnsafeBytes {dataBytes in
    someFunc(..., dataBytes, ...)
}

If you use multiple .bytes in a single expression, you may need to use nested withUnsafeBytes. In your case the related part of your code should be something like this:

let mykeydatamd5 = myKeyData.subdata(in: 0..<24)    //Assuming myKeyData.count >= 24

let crypto_status: CCCryptorStatus = mykeydatamd5.withUnsafeBytes {mykeydataBytes in
    myRawData.withUnsafeBytes {myRawDataBytes in
         CCCrypt(operation, algoritm, options, mykeydataBytes, keyLength, nil, myRawDataBytes, myRawData.count, buffer, buffer_size, &num_bytes_encrypted)
    }
}
0
jignesh Vadadoriya On

Try this

func myEncrypt(encryptData:String) -> String? {

        //security key must be 24charachters

        var myKeyData = [UInt8]()
        var myRawData = [UInt8]()
        for char in "*******".utf8{
            myKeyData += [char]
        }
        for char in encryptData.utf8{
            myRawData += [char]
        }

        let mykeydatamd5 = Data(bytes: myKeyData, count: 24)

        let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, mykeydatamd5.bytes   , keyLength, nil, myRawData, myRawData.count, buffer, buffer_size, &num_bytes_encrypted)

        if UInt32(Crypto_status) == UInt32(kCCSuccess){

            let myResult: Data = Data(bytes: buffer, count: num_bytes_encrypted)

            free(buffer)

            return myResult.base64EncodedString()

        }else{

            free(buffer)

            return nil

        }
    }

Hope it will help you