In java I am using the following code
string value = "b:0001"
byte[] bytes = value.getBytes("US-ASCII");
Does anyone know the equivalent in Swift 3 but instead of passing to bytes [] pass to Data?
This gives you Data back:
let str = "b:0001"
let bytes = str.data(using: .ascii)!
Related
I have a string received from the server and I was trying to decode the string with padding but it is throwing nil as result. I tried codes that are available in stack overflow but of no use. Help will be highly appreciated.
I tried with base64 encoded with ignore unknown characters option and padding, still it throws nil.
let pem = "MIICyjCCAjOgAwIBAgIDBJPhMA0GCSqGSIb3DQEBBQUAMHsxEjAQBgNVBAMTCVJvb3RjZXJ0MTESMBAGA1UECRMJYmVsbGFuZHVyMQswCQYDVQQIEwJrYTEPMA0GA1UEERMGODg4ODg4MQwwCgYDVQQLEwNlc3MxGDAWBgNVBAoTD2VtdWRocmEgbGltaXRlZDELMAkGA1UEBhMCaW4wHhcNMTkwNzExMTAzNzM4WhcNMjgxMjI2MTAzNzM4WjB0MREwDwYDVQQDEwhBdmFkaGVzaDEMMAoGA1UECRMDYnRtMQswCQYDVQQIEwJrYTEPMA0GA1UEERMGODc4Nzg3MQwwCgYDVQQLEwNlc3MxGDAWBgNVBAoTD2VtdWRocmEgbGltaXRlZDELMAkGA1UEBhMCaW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMDAm7W3nc3hyyAhG8RBCSmlSDzcU/C39dPEFPq3N0JpSghMojnZg0jnfwXCvWqtPhlTYEdVLSXRehmQpS2v/FN8wkqZoVaKHNQE1UJnzPbyjfTlQA20nlCNVTNBQ70rWYzfuuFhliUBycGbYaIE/VGk354AEdXipLklCPf7PsgZAgMBAAGjYzBhMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUkdq9ZIGVtD0x6k6hO7PdFMidh/QwHQYDVR0OBBYEFDwUkx0+5e1xTcavaVBpvREel/hZMAsGA1UdDwQEAwIBzjANBgkqhkiG9w0BAQUFAAOBgQBIDy2MjWWsZC9G1k3DFYyP2/jsj/xzKyQh2e5YrnxIGtK5jBRKZe3JOuq1wxMzRfzd22lnSyKzf4dKMp2ADXJnNQrB/aafGs9nf+FXuIomquZHoNGrThfSyB/tre8T3dMWRiUdYy74XL2wvQb6tVHPQ/UEPSYOyf3XDSnzpgtjmw=="
let decodedData = NSData(base64Encoded: dataStr, options: .ignoreUnknownCharacters)
let length = dataStr.count
dataStr = dataStr.padding(toLength: length + (4 - length % 4) % 4, withPad: "=", startingAt: 0)`
It has to give some decoded data with which I can create a certificate because the response is in the format of .cert.
A certificate is not a string. You cannot create a string from the raw Data.
You can decode the base64 encoded string simply with
let decodedData = Data(base64Encoded: dataStr)
Notes:
Don't use NSData in Swift.
The ignoreUnknownCharacters is not needed.
The padding is wrong. It's only required when encoding the data and the base64 related API of String and Data adds the = characters automatically.
May be It will Help
For Image I am doing like this
I am converting UIImage To data and Converting That data to base64EncodedString
let imageData = UIimage.pngData()
//encode string
let imgBase64Str = imageData?.base64EncodedString(options: .lineLength64Characters) ?? ""
//decoding string to data
let decodedData = Data(base64Encoded: imgBase64Str, options: .ignoreUnknownCharacters)
Here was my workable code in the previous version of Swift:
let imageOptionsDictKeys = [ kCVPixelBufferPixelFormatTypeKey, kCVPixelBufferWidthKey, kCVPixelBufferHeightKey, kCVPixelBufferOpenGLESCompatibilityKey, kCVPixelBufferIOSurfacePropertiesKey]
let imageOptionsDictValues = [ cvPixelFormatType, frameW, frameH, boolYES]
var keyCallbacks = kCFTypeDictionaryKeyCallBacks
var valueCallbacks = kCFTypeDictionaryValueCallBacks
let imageOptions = CFDictionaryCreate(kCFAllocatorDefault, UnsafeMutablePointer(imageOptionsDictKeys), UnsafeMutablePointer(imageOptionsDictValues), 4, &keyCallbacks, &valueCallbacks)
After changes in the Swift 3.0 I have to convert my keys and values arrays into UnsafeMutablePointer<UnsafeRawPointer?> for creating CFDictionary.
This way:
let imageOptionsDictKeysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
imageOptionsDictKeysPointer.initialize(to: imageOptionsDictKeys)
gives an Bad Access error.
And after reading documentation I am trying to compile this code:
let imageOptionsDictKeys = [kCVPixelBufferPixelFormatTypeKey, kCVPixelBufferWidthKey, kCVPixelBufferHeightKey, kCVPixelBufferOpenGLESCompatibilityKey]
let imageOptionsDictKeysRawPointer = Unmanaged.passUnretained(imageOptionsDictKeys).toOpaque()
let imageOptionsDictKeysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
imageOptionsDictKeysPointer.initialize(to: imageOptionsDictKeysRawPointer)
let imageOptionsDictValues = [ cvPixelFormatType, frameW, frameH, boolYES]
let imageOptionsDictValuesRawPointer = Unmanaged.passUnretained(imageOptionsDictValues).toOpaque()
let imageOptionsDictValuesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
imageOptionsDictValuesPointer.initialize(to: imageOptionsDictValuesRawPointer)
let imageOptions = CFDictionaryCreate(kCFAllocatorDefault, imageOptionsDictKeysPointer, imageOptionsDictValuesPointer, 4, &keyCallbacks, &valueCallbacks)
but error Generic parameter 'Instance' could not be inferred appears in the lines Unmanaged.passUnretained(array).toOpaque()
I have no idea how to create CFDictionary programmatically now.
I just solved a similar issue converting arrays to UnsafeMutablePointer< UnsafeMutablePointer<T>> which you can find here:
Swift 3 UnsafeMutablePointer initialization for C type float**
To convert swift arrays using the same scheme, use UnsafeMuTablePointer as suggested here: http://technology.meronapps.com/2016/09/27/swift-3-0-unsafe-world-2/
var dataFile: NSData = NSMutableData.init(data: wav.subdataWithRange(NSRange.init(location: currentByte, length: wavDataSize)))
How to me convert this code to using Data with Swift 3? Or how to parseNSRange to Range
Separating Data into smaller Data instances
Assumptions
This answer is the Swift 3 & 4 equivalent of the code in the question. It will produce the same result, dataFile, given the same input values: wav, currentByte and wavDataSize assuming none of the surrounding code changes.
I did not make assumptions about what the variables: wav, dataFile, currentByte or wavDataSize mean. To avoid the variable names implying things not stated in the question, I will use the following names instead: sourceData, subdata, rangeStartByte and subdataLength. I assume the code (not shown in the question) surrounding this would assure that rangeStartByte and subdataLength were in a valid range to avoid an error.
Converting NSRange to Range<Int>
The Swift 2 implementation from the question uses an NSRange defined by a start point and a length like this:
NSRange.init(location: rangeStartByte, length: subdataLength)
The Swift 3 & 4 implementation I propose creates an equivalent Range<Int> defined by a start point and end point like this:
rangeStartByte ..< (rangeStartByte + subdataLength)
I converted an app from Swift 2.2 to 3 which used similar code to upload a photo in smaller chunks. During conversion we missed this nuance and used the Swift 2 implementation's length in place of the Swift 3 & 4 implementation's end point. This caused a defect that was tricky to resolve. The first iteration succeeded but subsequent iterations failed.
Another answer implements the issue I just described as the solution. It uses subdataLength from the length of the Swift 2 range as the end point of the Swift 3 & 4 range. This will produce the same result in the special case where currentByte is 0 and subdataLength is <= the length of the NSData instance (which is why the first iteration succeeded in the issue I described). That assumption was not explicitly stated in the question and yields a less flexible solution for others.
Swift 3 & 4 equivalent
var subdata = sourceData.subdata(in: rangeStartByte ..< (rangeStartByte + subdataLength))
Swift 2.2
(code from question with updated variable names)
var subdata: NSData = NSMutableData.init(data: sourceData.subdataWithRange(NSRange.init(location: rangeStartByte, length: subdataLength)))
Runnable sample code
I've included sample code you can run in a playground demonstrating how this line of code could be used to separate a Data instance into smaller Data instances. The source Data instance is created from a string "ABCDEFGHIJKL". This instance is separated into smaller Data instances of length 5.
Swift 3 & 4 with context
import UIKit
var sourceString = "ABCDEFGHIJKL"
let sourceData = sourceString.data(using: String.Encoding.utf8)! // sourceData is equivalent to "wav" from question
var rangeStartByte = 0 // rangeStartByte is equivalent to "currentByte" from question
let maxSubdataLength = 5
let dataLength = sourceString.lengthOfBytes(using: String.Encoding.utf8)
precondition(maxSubdataLength <= dataLength, "maxSubdataLength must be <= to dataLength")
while rangeStartByte < dataLength {
// subdataLength is equivalent to "wavDataSize" from question
let subdataLength = min(maxSubdataLength, dataLength - rangeStartByte)
// subdata is equivalent to "dataFile" from question
let subdata = Data(sourceData.subdata(in: rangeStartByte ..< (rangeStartByte + subdataLength)))
let subdataString = String(data: subdata, encoding: String.Encoding.utf8) ?? ""
print("'\(subdataString)'")
rangeStartByte += subdataLength
}
The result is:
'ABCDE'
'FGHIJ'
'KL'
Swift 2.2 with context
import UIKit
var sourceString = "ABCDEFGHIJKL"
let sourceData = sourceString.dataUsingEncoding(NSUTF8StringEncoding)! // sourceData is equivalent to "wav" from question
var rangeStartByte = 0 // rangeStartByte is equivalent to "currentByte" from question
let maxSubdataLength = 5
let dataLength = sourceString.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
precondition(maxSubdataLength <= dataLength, "maxSubdataLength must be <= to dataLength")
while rangeStartByte < dataLength {
// subdataLength is equivalent to "wavDataSize" from question
let subdataLength = min(maxSubdataLength, dataLength - rangeStartByte)
// subdata is equivalent to "dataFile" from question
let subdata: NSData = NSMutableData.init(data: sourceData.subdataWithRange(NSRange.init(location: rangeStartByte, length: subdataLength)))
let subdataString = String(data: subdata, encoding: NSUTF8StringEncoding) ?? ""
print("'\(subdataString)'")
rangeStartByte += subdataLength
}
The result is:
'ABCDE'
'FGHIJ'
'KL'
Swift 3 & 4 using NSRange
pedrouan's answer uses NSRange like this:
var subdata: Data = Data(sourceData.subdata(with: NSRange(location: rangeStartByte, length: subdataLength)))
I could not get this to compile initially so I disregarded it. Now I realize that it works if sourceData is declared or cast at NSData and not Data
If you want to run this approach within the "Swift 3 & 4 with context" sample code above, replace the corresponding code in that sample with this:
// subdata is equivalent to "dataFile" from question
let sourceNSData = sourceData as NSData
let subdata = sourceNSData.subdata(with: NSRange(location: rangeStartByte, length: subdataLength))
I'm trying not to use "NS" classes like NSRange where possible so I favored the solution using a Swift Range.
Some 'little' changes in Swift 3.0
var dataFile: Data = Data(wav.subdata(with: NSRange(location: currentByte, length: wavDataSize)))
In Swift 3 your code will be like this one:
var dataFile = sourceData.subdata(in: currentByte..<currentByte+wavDataSize)
How do we find out the length (byte-wise) of a string [declared String type, not NSString] in Swift 2.2?
I know one way out is to use _bridgeToObejectiveC().length
Is there any other way out?
let str: String = "Hello, World"
print(str.characters.count) // 12
let str1: String = "Hello, World"
print(str1.endIndex) // 12
let str2 = "Hello, World"
NSString(string: str2).length //12
Refer String length in Swift 1.2 and Swift 2.0 and Get the length of a String
let str: String = "Hello, World"
print(str.characters.count) // 12
let byteLength = str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
print("byte lenght: \(byteLength)")//12
let str2: String = "你好"
print(str2.characters.count) // 2
let byteLength2 = str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
print("byte lenght: \(byteLength2)")//12
Try this code:
Swift
let test : String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let bytes : NSInteger = test.lengthOfBytesUsingEncoding(NSUTF8StringEncoding);
NSLog("%i bytes", bytes);
Objective C
refer this link:
What is the length in bytes of a NSString?
I think type casting is another easier way to use the methods, properties of NSString class.
print((str as NSString).length)
I'm trying to concatenate two NSData objects into one NSMutableData, and than get them back. For now i'm trying to do it in such way:
Get length of first object.
Write into NSMutableData in such order: first object length, first object, second object.
Code looks like:
let firstString = "first_string";
let secondString = "secondSting";
let firstData = firstString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let secondData = secondString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let mutableData = NSMutableData()
var length = firstData.length
mutableData.appendBytes(&length, length: sizeof(Int))
mutableData.appendData(firstData)
mutableData.appendData(secondData)
Then I want to get datas back. So I suppose to read first data length and then get two datas.
var length = 0
mutableData.getBytes(&length, length: sizeof(Int))
But when I'm trying to get data I'm getting crash instead:
var data = NSData()
mutableData.getBytes(&data, range: NSMakeRange(sizeof(Int), length))
Maybe somebody know where is my problem or how to get datas?
You can extract the data using subdataWithRange():
let firstData1 = mutableData.subdataWithRange(NSMakeRange(sizeof(Int), length))
if let firstString1 = NSString(data: firstData1, encoding: NSUTF8StringEncoding) as? String {
println(firstString1)
} else {
// bad encoding
}
Your solution
var data = NSData()
mutableData.getBytes(&data, range: NSMakeRange(sizeof(Int), length))
does not work and crashes because NSData is a reference type and
data a pointer to the object. You are overwriting this pointer
and the following bytes in memory.
This works perfectly without a crash in my storyboard. I just omitted the second var before length in order to avoid redefining it.
Here is the output for each line:
"first_string"
"secondSting"
<66697273 745f7374 72696e67> // let firstData = ...
<7365636f 6e645374 696e67> // let secondData = ...
<> // let mutableData = ...
12 // var length = ...
// appending data
<0c000000 00000000>
<0c000000 00000000 66697273 745f7374 72696e67>
<0c000000 00000000 66697273 745f7374 72696e67 7365636f 6e645374 696e67>
0 // length = 0
<0c000000 00000000 66697273 745f7374 72696e67 7365636f 6e645374 696e67>
12 // length
This means you probably have an error somewhere else. You did not redefine length, right?