Can't get AudioStreamBasicDescription from capture output - video-capture

I'm trying to access mSampleRate and mChannelsPerFrame and assign the values to global variables.
Method:
func setAudioFormat(format: CMFormatDescriptionRef) {
let asbd: UnsafePointer<AudioStreamBasicDescription> = CMAudioFormatDescriptionGetStreamBasicDescription(format)
sampleRate = asbd.memory.mSampleRate // breakpoint
channels = asbd.memory.mChannelsPerFrame
}
Method Call:
func captureOutput(captureOutput: AVCaptureOutput!, var didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
...
let format: CMFormatDescriptionRef = CMSampleBufferGetFormatDescription(sampleBuffer)!
self.setAudioFormat(format)
...
}
am I doing something wrong? is there a better way to get AudioStreamBasicDescription from capture output samplebuffer
Edit:
format is holding these values:
<CMAudioFormatDescription 0x14516150 [0x346c08a0]> {
mediaType:'soun'
mediaSubType:'lpcm'
mediaSpecific: {
ASBD: {
mSampleRate: 44100.000000
mFormatID: 'lpcm'
mFormatFlags: 0xc
mBytesPerPacket: 2
mFramesPerPacket: 1
mBytesPerFrame: 2
mChannelsPerFrame: 1
mBitsPerChannel: 16 }
cookie: {(null)}
ACL: {(null)}
}
extensions: {(null)}
}

Once you have a CMFormatDescriptionRef instance, you can use this code (in Objective-C, sorry) to retrieve the ASBD data:
const AudioFormatListItem *audioFormatListItem = CMAudioFormatDescriptionGetFormatList(formatDescription, nil);
AudioStreamBasicDescription asbd = audioFormatListItem->mASBD;
float sampleRate = asbd.mSampleRate;

Related

How to Display Post Method Requests data in Swiftui Ios Simulator Screen?

This is Doc File Generate in Postman by write method and url "link/services.php".
This is Header File.
#Headers({"Content-Type: application/json"})
 #POST("services.php")
Observable<Division> divisionListApi(#Body HashMap<String, String> map);
map.put("method", "My_List");
After Postman Generation I Got This Given Below.
{"err_code":9,
"message":"My List ",
"list":[
{"ForestDivision":"Yam(T)"},
{"ForestDivision":"Rewar(T)"},
{"ForestDivision":"Ro(T)"},
{"ForestDivision":"Bh(T)"},
{"ForestDivision":"Ka(T) "},
{"ForestDivision":"Ambal(T) "},
{"ForestDivision":"Fari(T)"}]
}
I have made request by taking post mehod, is this the right way to create code in
swiftui.
import Foundation
import Combine
struct File: Decodable, Hashable {
var error_code : Int
var message : String
var list : [lisst]
}
struct lisst: Decodable, Hashable {
var ForestDivision: String
}
class fetchResults : ObservableObject{
#Published var fetchedRes : [lisst]?
func getData(completion: #escaping (File) -> ()){
print("Fetch")
let parameters = "{ I dont Know }"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string:
"URl")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { (data, _, _) in
let resultList = try! JSONDecoder().decode(File.self, from: data!)
print(" ")
print("ID: \(resultList.error_code)")
print("VOLUME: \(resultList.message)")
print("READINGS: \(String(describing: resultList.list))")
print(" ")
print("SUCCESS: Got data - \(data! )")
DispatchQueue.main.async {
completion(resultList) // << here !!
}
}
task.resume()
}
}
Also How to Write in Swiftui View.
To Make Properly Works in List View.
import SwiftUI
import UIKit
struct DivisionList: View {
#ObservedObject var res = fetchResults()
var body: some View {
NavigationView {
Text("Nothing Here")
List(res.fetchedRes ?? [], id: \.self) { resp in // Error Here
ForEach(res.list, id: \.self) { course in
VStack {
Text(res.for) // Error Here
}
}
}
.navigationBarTitle("Data")
.onAppear(perform: {
self.getData // Error Here
})
}
}
}
struct DivisionList_Previews: PreviewProvider {
static var previews: some View {
DivisionList()
}
}
Create New Swift File Copy this Post Requests.
import Foundation
import Combine
let postUrl = "Your URl"
struct divisionList: Decodable, Identifiable {
let id: Int
let mesg: String
let list: [FDivision]
private enum CodingKeys: String, CodingKey {
case id = "err_code"
case mesg = "message"
case list = "list"
}
}
struct FDivision: Decodable, Hashable {
let forestDivision: String
private enum CodingKeys: String, CodingKey {
case forestDivision = "ForestDivision"
}
init(data:String) {
forestDivision = data
}
}
class viewModal: ObservableObject {
#Published var items = [FDivision]()
func postData() {
guard let serviceUrl = URL(string: postUrl) else { return }
let parameters: [String: Any] = [
"method": "Your Method Name"
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let dictionary = json as? [String:Any] {
if let arrList = dictionary["list"] as? [[String:Any]]{
for data in arrList{
let model = FDivision(data: data["ForestDivision"] as! String)
self.items.append(model)
}
}
}
print(json)
} catch {
print(error)
}
}
}.resume()
}
}
Create Now New Swiftui File.
import SwiftUI
import UIKit
struct DivisionList: View {
#ObservedObject var vm = viewModal()
var body: some View {
NavigationView {
VStack {
List(vm.items, id: \.self) { item in
Button(action: {}, label: {
Text(item.forestDivision).foregroundColor(.customGreen)
})
}
}.navigationBarTitle("Data")
.onAppear(perform: {
vm.postData()
})
}
}
}
struct DivisionList_Previews: PreviewProvider {
static var previews: some View {
DivisionList()
}
}

Swift 5 AES Encryption/Decryption using CommonCrypto

I've been trying to use the CommonCrypto in iOS to do a blockwise decryption of a larger Data object, but I can't get it to work. I've been reading the documentation, and looked at several examples from Objective-C - none of which I managed to get to work in an Objective-C environment. After 3 days of coding this I'm starting to wear out and I need some help.
I can decrypt and encrypt fine using the CCCrypto approach, but since I use rather large files this eats up too much memory for iOS to allow me to use this method. Thus I need to do this more efficiently and I decided to try an approach where I decipher one block at a time and then replace the block I deciphered with the resulting data block. The code runs, it seems to be working except for the fact that the data I get won't decode back to an UTF8 String.
Code for using CCCryptoCreate() with symmetric block deciphering (DataExtension)
mutating func decryptUsingCCCryptoCreate() {
// Get the first 16 bytes as IV
let IV = self.prefix(kCCBlockSizeAES128)
// Get key as array of bytes
let key = "ABCDEFGHIJKLMNOPQRSABCDEFGHIJKLM".data(using: .utf8) ?? Data()
// Setup totalSize
let totalSize = self.count
let operation = kCCDecrypt
let algorithm = kCCAlgorithmAES
let options = kCCOptionPKCS7Padding
var cryptorRef: CCCryptorRef?
// Step one is to create the CCCryptor with correct parameters for AES128 decryption
var status = CCCryptorCreate(CCOperation(operation), CCAlgorithm(algorithm), CCOptions(options), key.withUnsafeBytes { $0.baseAddress }, key.count, IV.withUnsafeBytes { $0.baseAddress }, &cryptorRef)
if status != kCCSuccess {
print("Failed on create: \(status.description)")
return
}
var dataOutMoved: size_t = 0 // The actual data moved
var dataInLength: size_t = kCCBlockSizeAES128 // The in size will always be the size of a kCCBlockSizeAES128
var dataOutLength: size_t = CCCryptorGetOutputLength(cryptorRef, dataInLength, false) // DataOutLength is always less than or equal to the dataInLength
var totalLength: size_t = 0 // The actual length of the deciphered data
var filePtr: size_t = 0 // Keeps track of the current position in the deciphering process
var startByte: Int = 0 // Increments each time with the kCCBlockSizeAES128 until we are done
var dataIn = Data() // Buffer to store the encrypted block to be deciphered
var dataOut = Data() // Buffer to store the decrypted block result
// While startByte is less than totalSize we continue to decrypt the next block
while startByte <= totalSize {
if startByte + kCCBlockSizeAES128 > totalSize {
dataInLength = totalSize - startByte
} else {
dataInLength = kCCBlockSizeAES128
}
// Next block to decrypt
guard let rangeToDecrypt = Range(NSRange(location: startByte, length: dataInLength)) else { return }
dataIn = self.subdata(in: rangeToDecrypt)
// Decipher the block
status = CCCryptorUpdate(cryptorRef, dataIn.withUnsafeBytes { $0.baseAddress }, dataInLength, dataOut.withUnsafeMutableBytes { $0.baseAddress }, dataOutLength, &dataOutMoved)
if status != kCCSuccess {
print("Failed on Update: \(status.description)")
return
}
// Replace the encrypted block with the decrypted block
let rangeToReplace = Range(NSRange(location: filePtr, length: dataOutMoved))!
self.replaceSubrange(rangeToReplace, with: dataOut.withUnsafeBytes { $0.baseAddress! }, count: dataOutMoved)
totalLength += dataOutMoved
filePtr += dataOutMoved
startByte += kCCBlockSizeAES128
}
// Finalize the deciphering
status = CCCryptorFinal(cryptorRef, dataOut.withUnsafeMutableBytes { $0.baseAddress }, dataOutLength, &dataOutMoved)
totalLength += dataOutMoved
if status != kCCSuccess {
print("Failed on final: \(status.description)")
return
}
// We replace the final deciphered block
let decryptedRange = Range(NSRange(location: filePtr, length: dataOutMoved))!
self.replaceSubrange(decryptedRange, with: dataOut.withUnsafeBytes { $0.baseAddress! }, count: dataOut.count)
// Since we are using padding the CCCryptorFinal can contain padding which needs to be truncated.
self = self.prefix(totalLength)
// Finish the CCCryptor process
CCCryptorRelease(cryptorRef)
}
Code for the encryption using CCCrypto()
mutating func encryptUsingCCCrypto() {
let sa = String(data: self, encoding: .utf8) ?? ""
print("Before encryption: \(sa)")
let now = Date()
let key = "ABCDEFGHIJKLMNOPQRSABCDEFGHIJKLM".data(using: .utf8) ?? Data()
let ivRandomData = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let blockSize = kCCBlockSizeAES128
let bufferSize = self.count + blockSize
var encryptedSize = 0
let cryptStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES),
UInt32(kCCOptionPKCS7Padding),
key.withUnsafeBytes { $0.baseAddress },
key.count,
ivRandomData.withUnsafeBytes { $0.baseAddress },
self.withUnsafeBytes { $0.baseAddress },
self.count,
self.withUnsafeMutableBytes { $0.baseAddress },
bufferSize,
&encryptedSize)
self = self.prefix(encryptedSize)
let s = String(data: self, encoding: .utf8) ?? ""
print("Result: \(s)")
}
I use the code like this:
let string = "1234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234"
var data = string.data(using: .utf8) ?? Data()
data.encryptUsingCCCrypto()
data.decryptUsingCCCryptoCreate() // I get a Data object with 112 bytes here
let s = String(data: data, encoding: .utf8) ?? "" // String is nil, and is provided ""

Bad Request: there is no photo in the request

I'm trying to send an image from my application to telegram bot like here
https://newfivefour.com/swift-form-data-multipart-upload-URLRequest.html
Here is the code
let BotToken = "12345"
let ChatID = "123"
func SendToTelegram()
{
var request = URLRequest(url: URL(string: "https://api.telegram.org/bot"+BotToken+"/sendPhoto")!)
request.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let params = [:] as [String: String]
UIGraphicsBeginImageContextWithOptions(ScreenImage.bounds.size, true, 0.0)
ScreenImage.image?.draw(in: CGRect(x: 0, y: 0, width: ScreenImage.frame.size.width, height: ScreenImage.frame.size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
request.httpBody = createBody(parameters: params,
boundary: boundary,
data: UIImageJPEGRepresentation(image!, 0.7)!,
mimeType: "image/jpg",
filename: "hello.jpg")
print(request.httpBody!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? AnyObject
if let parseJSON = json {
print("resp :\(parseJSON)")
}
} catch let error as NSError {
print("error : \(error)")
}
}
task.resume()
}
and get an error
Bad Request: there is no photo in the request";
"error_code" = 400;
ok = 0;
Where do i make a mistake? I'm new in SWIFT and sorry for my English
I know this question is old but the link provided pushed me in the right direction. This is my solution for server side Swift not iOS but you should be able to use it with minimal changes. Remember if you're using iOS, perform none of these operations on the main thread.
class NetworkManager {
func sendTelegramPhoto(_ photo: Data) {
let url = "https://api.telegram.org/bot\(Constants.Telegram.token)/sendPhoto"
let params: [String: Any] = [
"chat_id": Constants.Telegram.uid,
"photo": photo
]
let _ = sendMultiTypePostRequest(url, parameters: params)
}
private func sendMultiTypePostRequest(_ url: String, parameters: [String:String]) -> NetworkResponse {
var networkResponse = NetworkResponse()
let semaphore = DispatchSemaphore(value: 0)
guard let url = URL(string: url) else {
return networkResponse
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let httpBody = createBody(parameters: parameters,
boundary: boundary,
mimeType: "image/jpeg",
filename: "snapshot.jpg")
let config = URLSessionConfiguration.default
config.requestCachePolicy = .reloadIgnoringLocalCacheData
let session = URLSession(configuration: config)
let task = session.uploadTask(with: urlRequest, from: httpBody) { (data, response, error) in
networkResponse.data = data
networkResponse.response = response
networkResponse.error = error
semaphore.signal()
}
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
return networkResponse
}
private func createBody(parameters: [String: String],
boundary: String,
mimeType: String,
filename: String) -> Data {
var body = Data()
let boundaryPrefix = "--\(boundary)\r\n"
for (key, value) in parameters {
if let data = value as? Data {
body.appendString(boundaryPrefix)
body.appendString("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimeType)\r\n\r\n")
body.append(data)
body.appendString("\r\n")
} else if let string = value as? String {
body.appendString(boundaryPrefix)
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(string)\r\n")
}
}
body.appendString("--".appending(boundary.appending("--")))
return body
}
}
private extension Data {
mutating func appendString(_ string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
append(data!)
}
}

how can i convert code to objective c for SMS verification

I want to parse data for twilio url,which will be used for SMS verification
Please help to convert swift to objective for following code:
#IBAction func pressedSend(sender: AnyObject) {
let code = arc4random_uniform(8999) + 1000
var data = [
"To" : textTo.text as String,
"From" : "<replace with your Twilio local number>",
"Body" : String(code) as String
]
var swiftRequest = SwiftRequest()
swiftRequest.post("https://api.twilio.com/2010-04-01/Accounts/ACc4e304c952c972c26699b927422e668953/Messages",
auth: ["username" : "ACc4e304c952c972c26699b927422e668953", "password" : "5ab5312824b1d057dea249668e2c4189"],
data: data,
callback: {err, response, body in
if err == nil {
println("Success: (response)")
} else {
println("Error: (err)")
}
})
}
Thanks for help
I do think it should be something like this. not sure about swiftRequest so I assumed its your network request class.
-(IBAction)pressedSend:(id) sender{
NSInteger code = arc4random_uniform(8999)+1000;
NSDictionary *data = #{#"To":textTo.text, // guessing this is a label?
#"From":"<replace with your Twilio local number>",
#"Body":[NSString stringWithFormat:#"%d",code]
};
SwiftRequest *swiftRequest = [SwiftRequest new];
[swiftRequest Post:#"https://api.twilio.com/2010-04-01/Accounts/ACc4e304c952c972c26699b927422e668953/Messages"
auth:#{#"username" : #"ACc4e304c952c972c26699b927422e668953",
#"password" : #"5ab5312824b1d057dea249668e2c4189"}
callback:(NSerror *error, id response){
if(error != nil){
// has error
}
else{
// has no error
}
}
}];
}//end method

Best practice to safely load image from url

I have the following code snippet to load an image from an url:
let url = NSURL(string: imageUrl)
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)
In case that my variable imageUrl has a valid string value, what is the most secure way to protect this code against possible edge cases?
Following code seems not to be very handy:
if let url = NSURL(string: imageUrl) {
if let data = NSData(contentsOfURL: url) {
if let image = UIImage(data: data) {
// success -> do something with the image...
}
else {
// print error message
}
}
else {
// print error message
}
}
else {
// print error message
}
The best practice is not to use a synchronous method like contentsOfURL to load data from over the network.
The recommended way is NSURLSession which works asynchronously.
This is a simple example with a completion block and an enum with associated types,
it catches all possible errors
enum Result {
case Success(UIImage), Failure(NSString)
}
func loadImage(string : String, completion: (Result) -> ()) {
guard let url = NSURL(string: string) else {
completion(.Failure("Bad URL"))
return
}
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
if error != nil {
completion(.Failure(error!.localizedDescription))
} else {
guard let image = UIImage(data: data!) else {
completion(.Failure("Could not load image data"))
return
}
completion(.Success(image))
}
}.resume()
}
Call it with:
loadImage("http://myserver.com/path/to/image.png") { result in
switch result {
case .Success(let image) :
// do something with the image
case .Failure(let error) :
print(error)
}
}