0

I am trying to use ActionScript's File.upload to upload a file on Air SDK for iOS environment, but the File.upload does not work properly. No handler about the file upload is executed after File.upload is invoked, and no exception is caught. When I check the network traffic of the server side, I found that no http request even hit the server after executing File.upload. The code is below.

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <fx:Script>
        <![CDATA[

            private var file:File;
            private var dir:File;

            //This method is executed to create a file and upload it when the Upload Button is pressed. 
            protected function OnUploadButtonPressed(event:MouseEvent):void{
                trace("upload button clicked");

                var urlReq:URLRequest = new URLRequest("http://10.60.99.31/MyPath/fileUploadTest.do");
                urlReq.method = URLRequestMethod.POST;

                var str:String = 'This is test';

                var imageBytes:ByteArray = new ByteArray();
                for ( var i:int = 0; i < str.length; i++ ) {
                    imageBytes.writeByte( str.charCodeAt(i) );
                }

                trace("size = " + imageBytes.length);

                try{
                    dir = File.applicationStorageDirectory
                    //I also tested in several different directories
                    //dir = File.createTempDirectory();
                    //dir = File.documentsDirectory;
                    var now:Date = new Date();
                    var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + now.milliseconds + ".txt";
                    file = dir.resolvePath( filename );
                    var stream:FileStream = new FileStream();
                    stream.open( file, FileMode.WRITE );
                    stream.writeBytes( imageBytes );
                    stream.close();

                    //Read back the file contents to check whether the file is written successfully.
                    var readStream:FileStream = new FileStream();
                    readStream.open(file, FileMode.READ);
                    var result:String = readStream.readUTFBytes(readStream.bytesAvailable);
                    trace("read back result = " + result);//The result is shown here as expected.

                    file.addEventListener( Event.COMPLETE, uploadComplete );
                    file.addEventListener( IOErrorEvent.IO_ERROR, ioError );
                    file.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityError );
                    file.addEventListener(ErrorEvent.ERROR, someError);
                    file.addEventListener(ProgressEvent.PROGRESS, onProgress);


                    file.upload( urlReq );//This line does not work. No handler is executed. No http request hit the server side.
                    trace("after file upload test");
                }
                catch( e:Error )
                {
                    trace( e );
                }
            }

            //Complete Handler
            private function uploadComplete( event:Event ):void
            {
                trace( "Upload successful." );
            }

            //IOError handler
            private function ioError( error:IOErrorEvent ):void
            {
                trace( "Upload failed: " + error.text );
            }

            //SecurityError handler
            private function securityError(error:SecurityErrorEvent):void{
                trace( "Security error:" + error.text );
            }

            //Other handler
            private function someError(error:ErrorEvent):void{
                trace("some error" + error.text);
            }

            //Progress handler
            private function onProgress(event:ProgressEvent):void{
                trace("progressHandler"); 
            }


            //This method is executed to invoke the URLLoader.load when the Tricky Button is pressed.
            protected function OnTrickyButtonPressed(event:MouseEvent):void{
                var urlReq:URLRequest = new URLRequest("http://200.60.99.31/");//This points to a non-existed server
                urlReq.method = URLRequestMethod.POST;

                urlReq.data = new ByteArray();
                var loader:URLLoader = new URLLoader();

                try{
                    loader.load(urlReq);//This line seems very important in iOS7. It decides whether the latter file.upload can work. 
                                        //But in iOS8, file.upload does not work even if this line is executed.
                    trace("after urlloader load");
                }catch(e:Error){
                    trace(e);
                }
            }


        ]]>

    </fx:Script>

    <s:Button x="200" y="200"  width="400" height="200" label="Upload" click="OnUploadButtonPressed(event)" />
    <s:Button x="200" y="500"  width="400" height="200" label="Tricky" click="OnTrickyButtonPressed(event)" />  
</s:View>

When executed on Air Simulator, it works fine as expected, and the file is successfully uploaded to the server. But When executed on iOS devices(in my case, iPad), as I explain early, no handler about the file upload is executed, and no the http request event hit the server. So I think the problem may be in the client side.

During my try to solve the problem, I found something tricky about this problem on iOS7. That is, if you invoke the URLLoader.load method (even if the URLLoader.load points to a non-existed address) before invoking the File.upload method, the File.upload will work as expected on iOS7. More specifically, when method OnTrickyButtonPressed above is executed before method OnUploadButtonPressed, File.upload will succeed on iOS7. But this only happens on iOS7. On iOS8, File.upload always refuses to work, regardless of whether the URLLoader.load is executed before.

I think in my case the problem is not the Sandbox problem or Firefox session problem described in the two links below, because not even any http request hit the server side. It seems that the Air SDK for iOS just failed to send the http request for some reason.

Flex 4 FileReference Issues With Firefox

How do I make Flex file upload work on firefox and safari?

To make my problem more clear, I list my environment below:

  • Develoment Environment: Windows7 (64bit) / Mac os 10.9.4 (Tested on two OS platforms.)
  • IDE: Flash Builder 4.7
  • Air SDK: 3.8 / 16.0.0 (After I updated to the lastest Air SDK 16.0.0 , the problem still exists.)
  • Application Server: Tomcat7 + Spring

Finally, I would like to mention that uploading file using URLLoader.load is not an option in my case because I want to upload large files in the future, which can not be handled with the URLLoader.load.

I have been struggling for this for days. So I really appreciate it if anyone has any idea about this. Thanks in advance.

Community
  • 1
  • 1
bluewind
  • 11
  • 4
  • If you really stuck with this problem can you make small project representing this issue, and upload it somwhere. I never had problems with file.upload – Dmitry Malugin Feb 26 '15 at 06:46
  • Dear Dmitry, thank you very much for your reply. I will make a small project and upload it as soon as possible. Thank you. – bluewind Feb 27 '15 at 01:01
  • Dear Dmitry, I have uploaded the flex project file SimpleFileUpload.fxp in the following address. [https://github.com/bluewindjava8/actionscript_file_upload_for_ios](https://github.com/bluewindjava8/actionscript_file_upload_for_ios) .I really really appreciate your help. Thank you very much. (I only upload the client side code because in my case, the problem is that the client side does not send the request to the server. So what the server side looks like doesn't matter here.) Waiting for your reply. – bluewind Mar 01 '15 at 13:18
  • Client-side is OK, I'll look at this code tomorrow – Dmitry Malugin Mar 01 '15 at 18:54
  • Dear Dmitry, will you please check that code for me if you have time. I think it is a bug of Air SDK for ios. If the same thing happens on your environment , I will report this bug to Adobe. Thank you very very much! – bluewind Mar 05 '15 at 01:05
  • I having a hard times on my work, will try to look at it on this week, sorry for false promising. – Dmitry Malugin Mar 05 '15 at 07:07
  • Dear Dmitry, thank you very much for your reply. I completely understand the hard time on your work. So I will wait until you have time to check it for me. Thanks , again. – bluewind Mar 06 '15 at 04:56
  • Dear Dmitry, finally I found the that the real problem is not about my code, it is about the http proxy Auto configuration, and this problem happened on iOS7 and iOS8. Please check the following link if you have time. Thank you for your cooperation. https://forums.adobe.com/thread/1716036 – bluewind Apr 03 '15 at 05:11
  • Thanks alot for comment and pointing out the problem, sorry that I encouraged you but didn't keep promise. – Dmitry Malugin Apr 03 '15 at 07:06
  • Dmitry, it is ok. Never mind. We may cooperate in the future. – bluewind Apr 04 '15 at 07:53
  • Dear Emitry, long time no see! I have another question about Flex Mobile CameraUI. Will you please give me some hint if convinient? Please check the following link. Thank you very much. http://stackoverflow.com/questions/29428148/how-to-record-a-time-limited-video-with-adobe-air-for-ios – bluewind Apr 14 '15 at 07:48

1 Answers1

0

Finally I found that the real problem is not about the code I provided, it is about the http proxy Auto configuration, and this problem happened on iOS7 and iOS8. I described the problem and a workaround in detail in the following link. Hope this will help some of you.

https://forums.adobe.com/thread/1716036

bluewind
  • 11
  • 4