Buy any Easy Native Extensions 2nd Edition package and get our $99 iOS + Android ANE Template completely free before the end of June 2015.
- step-by-step guide to making your iOS extension in under an hour
- library for data conversion between ActionScript and native code
- tutorials
- infographics
- code included
At the end of this part you will have
A confirmation of whether all of that code you piled up so far actually works.
Seriously, though, here is where you put the plumbing of your ANE together and start the camera from your test app. Dive in.
Time
5-6 minutes
Wait, have you done these first?
- Part 1: Create a test app – 15-20 minutes
- Part 2: Set up the Xcode project – 8-10 minutes
- Part 3: Set up the AIR Library – 8-10 minutes
- Part 4: Connect to the camera in Objective-C – 15-20 minutes
Step 1: Create an instance of CameraDelegate
Open CameraLibiOS.m and first include the CameraDelegate.h header file, then (naughtily) declare a global pointer to CameraDelegate at the top of the file:
1 2 3 |
#import "CameraDelegate.h" CameraDelegate * g_cameraDelegate = NULL; |
Then add a function that will create a CameraDelegate instance for g_cameraDelegate to point to, when needed. Put that in your Auxiliary functions section, where you declared sendMessage() in Part 2.
1 2 3 4 5 6 7 8 9 |
void ensureCameraDelegate() { // If we haven't created an instance of CameraDelegate already, // do it now: if ( NULL == g_cameraDelegate ) { g_cameraDelegate = [ [ CameraDelegate alloc ] init ]; } } |
Step 2: Get CameraDelegate to start the camera
In CameraLibiOS.m find the ASStartCameraPreview function you declared in Part 2 of this tutorial. It should look like this:
1 2 3 4 5 |
FREObject ASStartCameraPreview( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] ) { // ActionScript will call this function to set up and start the camera return NULL; } |
Replace the two lines in the function with code that will do actual work:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// 1. Make sure we have a CameraDelegate instance: ensureCameraDelegate(); // 2. Now get CameraDelegate to start the camera: BOOL isCameraStarting = [ g_cameraDelegate startCamera ]; // 3. Pass the result back to ActionScript: FREObject isCameraStartingResult = NULL; FRENewObjectFromBool( isCameraStarting, &isCameraStartingResult ); // Note that startCamera returning true doesn't mean that the camera HAS started. // It only means that there weren't any errors generated when we prepared // and asked the camera to start. // The actual camera firing up is asynchronous // and we will be notified about it later on with CAMERA_STARTED_EVENT. return isCameraStartingResult; |
Step 3: Check your ActionScript call
In Flash Builder find your CameraTutorialAIRLib project and open CameraDriver.as. Make sure CameraDriver calls your native code – you added this in Part 3 of the tutorial, so it should already be there:
1 2 3 4 5 |
public function startCameraPreview() : void { // This will call ASStartCameraPreview() in CameraLib_iOS.m m_extContext.call( "as_startCameraPreview" ); } |
Step 4: Get notified when the camera starts
Time to do something useful in the onStatusEvent() handler you added in Part 3. Find onStatusEvent() and replace the trace() statement in it with the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private function onStatusEvent( _event : StatusEvent ) : void { switch ( _event.code ) { case CAMERA_STARTED_EVENT: { // Let the app know that the camera is now running dispatchEvent( new DataEvent( CAMERA_STARTED_EVENT ) ); } break; default: break; } } |
Then define CAMERA_STARTED_EVENT public, so apps that use your ANE can listen for it:
1 |
public static const CAMERA_STARTED_EVENT : String = "CAMERA_STARTED_EVENT"; |
Step 5: Make the call in your test app
Time to test whether that pile of code actually works. In Flash Builder open the test app project, CameraTutorialApp, you set up in Part 1 of the tutorial.
What? You skipped that part? No worries, you can set it up now or use an app you already have. Go on, do it – I’ll be here waiting.
Ready? The steps below refer to the files and functions in CameraTutorialApp – you can pretend it’s called something else if you are using your own app.
5.1. Open CameraTutorialAppHomeView.mxml and inside the <fx:Script> section first include the CameraDriver class:
1 |
import com.diadraw.extensions.CameraDriver; |
Then add a CameraDriver variable:
1 |
private var m_cameraDriver : CameraDriver = null; |
5.2. Create the CameraDriver instance and hook to its CAMERA_STARTED_EVENT.
Remember the ensureCameraDriver() placeholder function you added in Part 1 of this tutorial? Let’s get it to work:
1 2 3 4 5 |
private function ensureCameraDriver() : void { m_cameraDriver = new CameraDriver(); m_cameraDriver.addEventListener( CameraDriver.CAMERA_STARTED_EVENT, onCameraStarted ); } |
A good place to call ensureCameraDriver() is the view’s creationComplete handler:
1 2 3 4 |
protected function view1_creationCompleteHandler( _event : FlexEvent ) : void { ensureCameraDriver(); } |
5.3. Implement onCameraStarted():
1 2 3 4 5 6 7 8 |
private function onCameraStarted( _event : Event ) : void { // 1. Update the UI btnStart.enabled = false; btnStop.enabled = true; // 2. TODO: start requesting video frames } |
As you may have noticed, your work here is not yet done. Once the camera has started, your test app can begin requesting video frames: that will be your objective in Part 7: Pass video frames to ActionScript.
5.4. Find the btnStart click handler that you added in Part 1 of the tutorial and get it to start the camera preview:
1 2 3 4 |
protected function btnStart_clickHandler( event : MouseEvent ) : void { m_cameraDriver.startCameraPreview(); } |
6. Run!
No, don’t run from this tutorial, run your app and see if it receives CAMERA_STARTED_EVENT. You should see the Start button go disabled and the Stop button become enabled when that happens.
If you get errors, crashes or other dodgy behaviour instead, post a comment below and let’s see if we can sort it out together. Details and excerpts from your code would be very helpful. (OK, my code – we can agree that when it doesn’t work, it’s my code.)
Check out the DiaDraw Camera Driver ANE.
Leave a Reply