0

I've been trying to create a custom camera for several weeks. Been trying different tutorials but nothing seem to work. Now I feel like I have a good structure of the code yet after giving permission to use the camera on my physical device I just end up with a white screen. Any Ideas what the problem might be?

Here is my code:

import SwiftUI
import FirebaseCore

@main
struct FirebaseAuthYoutubeApp: App {
    @StateObject var viewModal = AuthViewModel()
    
    init() {
        FirebaseApp.configure()
    }
    
    
    var body: some Scene {
        WindowGroup {
           /* ContentView()
                .environmentObject(viewModal)
       */
            CameraView2()
        }
        
    }
}
import SwiftUI
import AVFoundation
import UIKit


struct CamerVIEW2Kavsoft: View {
    var body: some View {
        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
    }
}

struct CamerVIEW2Kavsoft_Previews: PreviewProvider {
    static var previews: some View {
        CameraView2()
    }
}

struct CameraView2: View {
    @StateObject var camera = cameraModel()
    var body: some View{
        ZStack{
            
            //Going to be the camera preview...
            CameraPreview(camera: camera)
                .ignoresSafeArea(.all, edges: .all)
            
            VStack{
                
                if camera.isTaken {
                    
                    HStack{
                        Spacer()
                        Button(action: camera.retaTake, label: {
                            Image(systemName: "arrow.triangle.2.circlepath.camera")
                                .foregroundColor(.black)
                                .padding()
                                .background(Color.white)
                                .clipShape(Circle())
                        })
                        .padding(.trailing,10)
                        
                    }
                }
                
                Spacer()
                
                HStack {
                    
                   
                    // if taken showing save and again take button
                    
                    if camera.isTaken {
                        
                        Button(action: {if !camera.isSaved{camera.savePic()}}, label: {
                            Text(camera.isSaved ? "Saved" : "Save")
                            .foregroundColor(.black)
                            .fontWeight(.semibold)
                            .padding(.vertical,10)
                            .padding(.horizontal,20)
                            .background(Color.white)
                            .clipShape(Capsule())
                               
                               })
                        .padding(.leading)
                        Spacer()
                        
                    } else {
                        
                        Button(action: {camera.takePic()}, label: {
                            
                            ZStack{
                                
                                Circle()
                                    .fill(Color.white)
                                    .frame(width: 65, height: 65)
                                
                                Circle()
                                    .stroke(Color.white, lineWidth: 2)
                                    .frame(width: 75, height: 75)
                            }
                            
                        })
                    }
                }
                .frame(height: 75)
            }
        }
        .onAppear(perform: {
            camera.Check()
        })
    }
}


//Camera Model...

class cameraModel: NSObject, ObservableObject,  AVCapturePhotoCaptureDelegate {
    @Published var isTaken = false
    @Published var session = AVCaptureSession()
    @Published var alert = false
    
    // Since wew going to read pic data...
    @Published var output = AVCapturePhotoOutput()
    
    // preview
    @Published var preview : AVCaptureVideoPreviewLayer!
    
    @Published var isSaved = false
    @Published var picData = Data(count: 0)
    
    
    func Check() {
        //first checking cameras got permission..
        switch AVCaptureDevice.authorizationStatus(for:  .video) {
        case .authorized:
            //setting up session
            setUp()
            return
        case .notDetermined:
            // retesting for permission...
            AVCaptureDevice.requestAccess(for: .video) { (status) in
                if status {
                    self.setUp()
                }
            }
            
        case .denied:
            self.alert.toggle()
            return
        default:
            return
            
        }
        
    }
    
    func setUp() {
        // setting up camera
        
        do {
            
            // setting configs..
            self.session.beginConfiguration()
            
            if let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back) {
                
                do {
                    let input = try AVCaptureDeviceInput(device: device)
                    
                    //checking and adding to session
                    
                    if self.session.canAddInput(input) {
                        self.session.addInput(input)
                    }
                } catch {
                    print(error.localizedDescription)
                }
                
                // Same for outputs...
                
                if self.session.canAddOutput(self.output) {
                    self.session.addOutput(self.output)
                }
                
                self.session.commitConfiguration()
            }
        }catch {
                print(error.localizedDescription)
            }
        }
        
        // take and retake functions...
        
        func takePic(){
            DispatchQueue.global(qos: .background).async {
                self.output.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
                self.session.stopRunning()
                
                DispatchQueue.main.async {
                    withAnimation{self.isTaken.toggle()}
                    // clearing
                    self.isSaved = false
                }
            }
        }
        
        func retaTake() {
            DispatchQueue.global(qos: .background).async {
                self.session.startRunning()
                
                DispatchQueue.main.async {
                    withAnimation{self.isTaken.toggle()}
                }
            }
        }
        
        
        func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
            if error != nil{
                return
            }
            
            print("pic taken...")
            
            guard let imageData = photo.fileDataRepresentation() else {return}
            self.picData = imageData
        }
        
        func savePic() {
            let image = UIImage(data: self.picData)!
            
            // saving Image...
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
            self.isSaved = true
            
            print("saved succeded ")
        }
    }
    
    //Setting view for preview...
    
    
    struct CameraPreview: UIViewRepresentable {
        
        @ObservedObject var camera : cameraModel
        func makeUIView(context: Context) -> UIView {
            
            let view = UIView(frame: UIScreen.main.bounds)
            
            camera.preview = AVCaptureVideoPreviewLayer(session: camera.session)
            camera.preview.frame = view.frame
            
            // Your own properties...
            
            camera.preview.videoGravity = .resizeAspectFill
            view.layer.addSublayer(camera.preview)
            
            //starting session
            camera.session.startRunning()
            
            return view
        }
        
        func updateUIView(_ uiView: UIView, context: Context) {
            
        }
    }
    
    

This is my permissions info.plist setting:

enter image description here

Earlier I got a fatal error on the  letinput =try AVCaptureDeviceInput(device: device) line in my setUp function so I tried to use optional binding instead but no luck.

  • https://stackoverflow.com/questions/73615100/captureoutput-from-avcapturevideodataoutputsamplebufferdelegate-is-not-being-cal/73615683#73615683 – lorem ipsum Aug 22 '23 at 00:12

1 Answers1

0

So i figured out the problem, In my setUp method I called the wrong camera on this line if let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back) {

It was supposed to be:

if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) {