Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application freezes when trying to present rear camera on iPad

The application that i am working on runs on both iPhone & iPad . One of the functionality that the application has, is to capture image from camera. I am using UIImagePickerController for this functionality. Here is my code block;

self.imagePicker.sourceType = .camera            
self.imagePicker.cameraCaptureMode = .photo
self.present(self.imagePicker, animated: true, completion: nil)

The app works as it designed in iPhones how ever when i run the same code on iPad the app freezes. This problem only occurs in iPad but just for the rear camera. If i choose front camera from image picker the app starts the camera, but it freezes when i press switch camera button.

As far as i understand from the logs problem occurs when the app is trying to draw the camera.

Logs:

2016-12-20 20:10:33.708816 Ronin[681:148977] CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Dec 20 20:10:33  Ronin[681] <Error>: CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-12-20 20:10:33.708925 Ronin[681:148977] clip: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Dec 20 20:10:33  Ronin[681] <Error>: clip: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-12-20 20:10:33.708991 Ronin[681:148977] CGContextSetFillColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Dec 20 20:10:33  Ronin[681] <Error>: CGContextSetFillColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-12-20 20:10:33.709047 Ronin[681:148977] CGContextFillRects: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Dec 20 20:10:33  Ronin[681] <Error>: CGContextFillRects: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

The iPad that i am using for test is : iPad Air 2 - iOS 10.2

EDIT

UIImagePickerController.isSourceTypeAvailable(.camera) code block returns true for my test case. I have already added this control but didn't mention before.

Also i have noticed that when the application is frozen, memory consumption started increasing and at same point application crashed because of using too much memory.

Additionally i created an empty project and implemented same approach for capturing image, which worked as it designed in the empty project. At this point what i think is this problem might be related with some project setting.

EDIT - 2

I added symbolic breakpoint for CGPostError, here is the stacktrace:

enter image description here

It seems like invalid context sent to UIProgressView is the reason for the problem.

Any help will be appreciated.

EDIT - 3

As i mentioned before I do check the UIImagePickerController.isSourceTypeAvailable(.camera) in my code block, the problem is not related with camera availability. Also the camera works as popover when i present it modally.

like image 684
Yiğit Doğuş Özçelik Avatar asked Dec 21 '16 06:12

Yiğit Doğuş Özçelik


Video Answer


4 Answers

Finally I solved the problem,

I implement a Theme approach for all application. In my AppDelegate file i set user interface settings while the application is being initialize.

Here is the issue,

There is a UISlider in camera UI, this slider view is always visible in iPad rear camera but in iPhones it is only visible when your are using zoom.

    UISlider.appearance().minimumTrackTintColor = themeUI.PrimaryColor.withAlphaComponent(100)
    UISlider.appearance().thumbTintColor = themeUI.PrimaryColor

These two lines changes appearance for all the sliders in the application, which means it also changes the UI for camera slider.

As you can see at the screen shot that i granted, while drawing camera CoreGraphics library calls

    [UISlider setMinimumTrackTintColor];

Somehow setting minimumTrackTintColor for slider is causing invalid context error.

Additionally setting thumTintColor works fine, it is also changing the thumb color for UISlider in Camera :)

Maybe this issue is related with Swift 3, I will report a bug and we will see :)

like image 86
Yiğit Doğuş Özçelik Avatar answered Oct 25 '22 00:10

Yiğit Doğuş Özçelik


You should check camera is available or not:

if UIImagePickerController.isSourceTypeAvailable(.camera) {
    // Implement UIImagePickerController
} else {
    // Show error message
}
like image 23
nynohu Avatar answered Oct 25 '22 01:10

nynohu


Here's how you can set an environmental variable: https://stackoverflow.com/a/31874419/3724800

And here's the code I use to open the camera in a Universal app:

if UIImagePickerController.isSourceTypeAvailable(.camera) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = .camera;
            imagePicker.allowsEditing = false
            present(imagePicker, animated: true, completion: nil)
}
like image 1
Frank Eno Avatar answered Oct 25 '22 01:10

Frank Eno


Replace your code with this:

Swift 3

   if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
    {
        let imagePicker:UIImagePickerController = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerControllerSourceType.camera
        imagePicker.allowsEditing = true
        self.present(imagePicker, animated: true, completion: nil)
    }
    else
    {
        let alert:UIAlertController = UIAlertController(title: "Camera not available", message: "Unable to find a camera on this device", preferredStyle: UIAlertControllerStyle.alert)
        self.present(alert, animated: true, completion: nil)
    }

Swift 2

    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)
     {
          let imagePicker:UIImagePickerController = UIImagePickerController()
          imagePicker.delegate = self
          imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
          imagePicker.allowsEditing = true
         self.presentViewController(imagePicker, animated: true, completion: nil)
     }
     else
     {
          let alert:UIAlertController = UIAlertController(title: "Camera not available", message: "Unable to find a camera on this device", preferredStyle: UIAlertControllerStyle.Alert)
          self.presentViewController(alert, animated: true, completion: nil)
     }
like image 1
User511 Avatar answered Oct 25 '22 01:10

User511