AV Foundation in relation to Camera issue - swift

I am trying to be able to use a custom camera, and I am converting code from swift 2 to swift 3; I am pretty much complete; but I am getting this error in relation to devices; I want to have a rear and front facing camera and before in swift 2 you would set the devices like so:
let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as! [AVCaptureDevice]
now I am using what xcode is telling me to use which is:
let devices = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDevice], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition)
but i am getting this error
cannot convert value of type 'AVCaptureDevice.type' to expected argument type '[AVCaptureDeviceType]'

For the deviceTypes parameter you need to pass in an array of one or more AVCaptureDeviceType's. Your choices are:
builtInMicrophone
builtInWideAngleCamera
builtInTelephotoCamera
builtInDualCamera
See here for more information on these constants.
With that said, you are probably looking for something like:
let devices = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera, AVCaptureDeviceType.builtInTelephotoCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.unspecified)

Related

Proper way to declare ExtAudioFileRef in swift 5 for macOS

I have been working on an audio application where I can seek to a specific point in an ExtAudioFile and load a specific number of frames that represent a particular length (time) of playback into an AVAudioPCMBuffer and start playing it. If the user selects a checkbox during playback of that audio segment, the buffer is then fed the remaining contents of the audio file so it will play to the end.
However, I have hit a roadblock. I have found older examples of code that loads these resources. They way they're declaring the calls is not working in Swift 5 for me. I am getting errors. Specifically:
import Cocoa
import AVFoundation
import AudioToolbox
do {
var err:OSStatus = noErr
let url = URL(fileURLWithPath: "./audio files/myAudioFile.mp3")
let track = try AVAudioFile(forReading: url)
var trackRef = ExtAudioFileRef?
err = try ExtAudioFileOpenURL(url as CFURL, trackRef)
} catch {
print(error)
}
The first error I am getting is for trackRef. The editor is flagging this line as "Expected member name or constructor call after type name." But the example I was following only had the property declared as shown in the code above.
The next line err = try ExtAudioFileOpenURL(orl as CFURL, trackRef) has error "Cannot convert value of type 'ExtAudioFileRef?.Type' (aka 'Optional.Type') to expected argument type 'UnsafeMutablePointer<ExtAudioFileRef?>' (aka 'UnsafeMutablePointer<Optional>')."
The editor is suggesting I change trackRef declaration to ver trackRef = ExtAudioFileRef?() or var trackRef = ExtAudioFileRef?.self but neither of those are any help because if I try using the first suggestion I then get "Cannot invoke initializer for type 'ExtAudioFileRef?' with no arguments" and a gray note showing "1. Overloads for 'ExtAudioFileRef?' exist with these partially matching parameter lists: (Wrapped), (from: Decoder), (nilLiteral: ())." But the error for err = ExtAudioFileOpenURL(url as CFURL, trackRef) goes away. If I try using the second suggestion let trackRef = ExtAudioFileRef?.self there is no error on that line, but then I get an error on the err = ExtAudioFileOpenURL(url as CFURL, trackRef) line that reads "Cannot convert value of type 'ExtAudioFileRef?.Type' (aka 'Optional.Type') to expected argument type 'UnsafeMutablePointer<ExtAudioFileRef?>' (aka 'UnsafeMutablePointer<Optional>')"
I am not versed enough to know what these errors mean as I don't know what UnsafeMutablePointer is. I was just following the example code to try and achieve what I want to do. Unfortunately I've not been able to get any of the audio tools in Swift to do what I want to do and this is the next rabbit hole for me.
Thanks for any help.
I finally found some recent code that uses this in later Swift.
I do not need to initialize the trackRef property, which was what was causing the errors to appear in the declarations. I also didn't need the try method.
Here's the proper way to declare it:
var trackRef: ExtAudioFileRef?
err = ExtAudioFileOpenURL(url as CFURL, &trackRef)
Now for the next rabbit hole...

Swift MetalKit unknknown return type MTKMesh.newMeshes

Up until now I have been following a tutorial (released around the time of Metal 1), to learn Metal. I haven't encountered any errors I couldn't figure out until this point. I am trying to execute this code
var meshes: [AnyObject]?
//code
let device = MTLDevice() //device is fine
let asset = MDLAsset() //asset works fine
do{
meshes = try MTKMesh.newMeshes(asset: asset, device: device)
} catch //...
The error i'm getting is Cannot assign value of type '(modellOMeshes: [MDLMesh], metalKitMeshes: [MTKMesh])' to type '[AnyObject]?'
What is type of MTKMesh.newMeshes, and how can I store it in a variable? I tried casting it as! [AnyObject], but then xcode tells me that this cast would fail every time.
The return type of that method is ([MDLMesh], [MTKMesh]), a tuple comprised of an array of MTLMeshes and an array of MTKMeshes. The reason for this is that you might want the original collection of MDLMesh objects contained in the asset, in addition to the MTKMesh objects that are created for you.
So, you can declare meshes like this:
var meshes: ([MDLMesh], [MTKMesh])
Or, if you don't care about the original MDLMeshes, you can "destructure" the tuple to get just the portion you care about into a variable of type [MTKMesh]:
var meshes: [MTKMesh]
(_, meshes) = try MTKMesh.newMeshes(asset: asset, device: device)
As the function signature and the compiler error clearly show, the return type is (modelIOMeshes: [MDLMesh], metalKitMeshes: [MTKMesh]), so you should declare meshas accordingly:
var meshes: (modelIOMeshes: [MDLMesh], metalKitMeshes: [MTKMesh])?
The type is a named tuple containing two Arrays, holding MDLMesh and MTKMesh instances respectively.

Cannot get value from Accelerometer, Gyro and DeviceMotion

I'm making an app to track your sleep by getting any movement of the iPhone. I searched everywhere and there are many ways you can get data from this but non worked. Here's my code.
func startManager() {
let manager = CMMotionManager()
manager.startAccelerometerUpdates()
let accelerometer = manager.accelerometerData
}
But manager.accelerometerData is nil. I also tried it with DeviceMotion, Gyro and UserAcceleration, non of them worked. I also tried this.
print(manager.isAccelerometerActive)
It printed false so I think this is the problem but I still cannot make it active.
I tried putting the let manager = CMMotionManager() to the top and it still won't work.
I tried putting manager.startAccelerometerUpdates() in the ViewDidLoad and still doesn't work.
I also tried another way which is this.
manager.startAccelerometerUpdates(to: OperationQueue.main) { (data : CMAccelerometerData, error : Error) in
print(data)
}
but it gave me an error saying that I have to add as! CMAccelerometerHandler but after I added that it tell me to add it again.
I want to get raw value from the Accelerometer as x, y and z
(I imported CoreMotion)
I'm doing this using Swift 3 on XCode 8.2.1 and testing it on iPhone 6s.
In Swift3, you should use optional parameters in the handler
motionManager.startAccelerometerUpdates(
to: OperationQueue.main ,
withHandler:{ (data : CMAccelerometerData?, error : Error?) in
print(data)
})

MacOS and Swift 3 with CIAffineClamp filter

I need to use CIAffineClamp in order to extend the image and prevent Gaussian Blur from blurring out edges of the image. I have the following code working in Swift 2:
let transform = CGAffineTransformIdentity
let clampFilter = CIFilter(name: "CIAffineClamp")
clampFilter.setValue(inputImage, forKey: "inputImage")
clampFilter.setValue(NSValue(CGAffineTransform: transform), forKey: "inputTransform")
In Swift 3 CGAffineTransformIdentity was renamed to CGAffineTransform.identity. My code compiles however I get the following error message in the console:
[CIAffineClamp inputTransfom] is not a valid object.
Documentation on Apple's websites states that inputTransform parameter on MacOS takes an NSAffineTransform object whose attribute type is CIAttributeTypeTransform. but I'm unsure how to use it.
Any help would be appreciated.
Seems NSAffineTransform has an initializer NSAffineTransform.init(transform:) which takes AffineTransform.
Please try this:
let transform = AffineTransform.identity
let clampFilter = CIFilter(name: "CIAffineClamp")!
clampFilter.setValue(inputImage, forKey: "inputImage")
clampFilter.setValue(NSAffineTransform(transform: transform), forKey: "inputTransform")
Or the last line can be:
clampFilter.setValue(transform, forKey: "inputTransform")
NSAffineTransform
Important
The Swift overlay to the Foundation framework provides the
AffineTransform structure, which bridges to the NSAffineTransform
class. The AffineTransform value type offers the same functionality as
the NSAffineTransform reference type, and the two can be used
interchangeably in Swift code that interacts with Objective-C APIs.
This behavior is similar to how Swift bridges standard string,
numeric, and collection types to their corresponding Foundation
classes.

ABAddressBook in Swift 2 fails

In Xcode7/Swift 2, the call
ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue()
returns a non-null CFArrayRef, but when I cast it "as? NSArray" or "as? [ABRecordRef]" (which used to work) I now get nil. I understand that we should move to the Contacts framework, but the old way should still work for a while. What's up?
Correct syntax for Swift 2 requires you to string two casts in a row:
let rawCFArrayRef =
ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue()
let swiftArray = rawCFArrayRef as? NSArray? as? [ABRecordRef]
Note that the ? on NSArray? is crucial.