[TIMOB-23935] iOS: Ti.Media.switchCamera() fails to switch camera.
| GitHub Issue | n/a | 
|---|---|
| Type | Bug | 
| Priority | High | 
| Status | Closed | 
| Resolution | Fixed | 
| Resolution Date | 2016-09-29T06:50:28.000+0000 | 
| Affected Version/s | Release 5.4.0, Release 5.5.0 | 
| Fix Version/s | Release 6.0.0 | 
| Components | iOS | 
| Labels | camera, iOS, qe-6.0.0, switchCamera | 
| Reporter | Motiur Rahman | 
| Assignee | Hans Knöchel | 
| Created | 2016-09-21T18:22:56.000+0000 | 
| Updated | 2016-09-29T17:44:46.000+0000 | 
Description
	Titanium.Media.switchCamera() fails to load the front-facing camera.
*Steps to Reproduce:*
1.Run Code
var win = Ti.UI.createWindow({
    layout: "vertical"
});
win.open();
var button = Ti.UI.createButton({
    title: "Camera",
    top: 20,
    width: 200,
    height: 200
});
button.addEventListener("click", takePics);
win.add(button);
var view = Ti.UI.createView();
var take = Ti.UI.createView({
    bottom: 20,
    backgroundColor: "white",
    width: 70,
    height: 70,
    borderRadius: 35
});
var switchCamera = Ti.UI.createButton({
    top: 30,
    title: "Switch",
    right: 30,
    backgroundColor: "red",
    width: 50,
    height: 50,
    borderRadius: 25
});
// Add to the parent view.
view.add(take);
view.add(switchCamera);
function takePics() {
    Ti.Media.showCamera({
        success: function(e) {
            Ti.API.info(e.media);
        },
        error: function(e) {
            alert(e);
        },
        autohide: false,
        overlay: view,
        saveToPhotoGallery: true,
        mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO],
        showControls: false
    });
}
take.addEventListener('click', function(e) {
    Ti.Media.takePicture();
});
//var value = true;
switchCamera.addEventListener('click', function() {
	Ti.API.info("Switch camera!");
    if (Ti.Media.camera == Ti.Media.CAMERA_FRONT) {
        Ti.Media.switchCamera(Ti.Media.CAMERA_REAR);
    } else {
        Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT);
    }
});
Note: Similar to TIMOB-17470, the camera can only be switched after the UI is displayed!
Hans -- Ive had something similar in our app prior to 5.5.0.GA and XCode8 -- and it worked. I added a _.delay() to wait for the UI to load, and the camera would switch. Now using IOS10 on the device and XCode 8 with Ti 5.5.0.GA, if I use the example above (and same with my app's code) and add the same kind of delay to wait for the UI to be loaded, Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT) does not fire anymore on a device with IOS10. i can put other things in the event listener for the switchCamera button click event, and they do fire, so I know the click event is being handled. I can alert the current Ti.Media.camera, which comes up as 0 when the camera loads and the UI is ready. I updated the sample code of this ticket as follows, the _.delay() of applying the eventListener (to simulate that the UI has completed loading) is at the end. I can't get the camera to switch checking the current camera, or by setting it explicitly. Thanks, Eric TI 5.5.0.GA XCode 8 OSX Sierra 10.12 TI CLI 5.0.9 IPhone 6+ / IOS 10.0.1
var win = Ti.UI.createWindow({ layout: "vertical" }); win.open(); var button = Ti.UI.createButton({ title: "Camera", top: 20, width: 200, height: 200 }); button.addEventListener("click", takePics); win.add(button); var view = Ti.UI.createView(); var take = Ti.UI.createView({ bottom: 20, backgroundColor: "white", width: 70, height: 70, borderRadius: 35 }); var switchCamera = Ti.UI.createButton({ top: 30, title: "Switch", right: 30, backgroundColor: "red", width: 50, height: 50, borderRadius: 25 }); // Add to the parent view. view.add(take); view.add(switchCamera); function takePics() { Ti.Media.showCamera({ success: function(e) { Ti.API.info(e.media); }, error: function(e) { alert(e); }, autohide: false, overlay: view, saveToPhotoGallery: true, mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO], showControls: false, allowEditing: false }); } take.addEventListener('click', function(e) { Ti.Media.takePicture(); }); _.delay(function() { switchCamera.addEventListener('click', function() { alert(Ti.Media.camera); if (Ti.Media.camera == Ti.Media.CAMERA_FRONT) { Ti.Media.switchCamera(Ti.Media.CAMERA_REAR); alert('switch to rear camera'); Ti.Media.vibrate(); } else { Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT); alert('switch to front camera'); Ti.Media.vibrate(); } alert('should switch') Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT); Ti.Media.vibrate(); }); });Hans, Nevermind my reply here -- I think there might be something else going on. Thanks
Hans, Follow up here -- the ability to be able to switch the camera seems to rely on having this property in tiapp.xml
Hey Eric, good catch! I guess I know in which direction we can investigate now. Thanks!
[~capsizeno4] Fixed! The issue was that we did not ensure that the code is being executed from the correct thread (UI-thread). I also scanned the rest of the camera-API to ensure it includes the macro as well - it does. PR (master): https://github.com/appcelerator/titanium_mobile/pull/8443 [~cng] Please let me know if we can consider this fix for 6.0.0 as well. Demo:
var win = Ti.UI.createWindow({ layout: "vertical" }); win.open(); var button = Ti.UI.createButton({ title: "Camera", top: 20, width: 200, height: 200 }); button.addEventListener("click", takePics); win.add(button); var view = Ti.UI.createView(); var take = Ti.UI.createView({ bottom: 20, backgroundColor: "white", width: 70, height: 70, borderRadius: 35 }); var switchCamera = Ti.UI.createButton({ top: 30, title: "Switch", right: 30, backgroundColor: "red", tintColor: "white", width: 60, height: 60, borderRadius: 30 }); // Add to the parent view. view.add(take); view.add(switchCamera); function takePics() { Ti.Media.showCamera({ success: function(e) { Ti.API.info(e.media); }, error: function(e) { alert(e); }, autohide: false, overlay: view, mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO], showControls: false }); } take.addEventListener('click', function(e) { Ti.Media.takePicture(); }); //var value = true; switchCamera.addEventListener('click', function() { Ti.API.info("Switch camera!"); if (Ti.Media.camera == Ti.Media.CAMERA_FRONT) { Ti.Media.switchCamera(Ti.Media.CAMERA_REAR); } else { Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT); } });excellent Hans nice one Eric
This is like a regression so yes we need it for 6.0.0.
PR (6_0_X): https://github.com/appcelerator/titanium_mobile/pull/8447
CR and FT passed. PRs merged.
Verified as fixed. Tested On: {noformat} iPhone 5 9.3.5 iPhone 6 10.0 Mac OSX El Capitan 10.12 Ti SDK: 6.0.0.v20160929031439 Appc Studio: 4.8.0.201609232005 Appc NPM: 4.2.8-7 App CLI: 6.0.0-54 Xcode 8.0 Node v4.4.7 {noformat} *Closing ticket.*