ActionScript的File.upload不适用于适用于iOS设备的Air SDK

时间:2015-02-25 04:51:38

标签: ios actionscript-3 flash flex air

我正在尝试使用ActionScript的File.upload在Air SDK for iOS环境中上传文件,但File.upload无法正常工作。调用File.upload后,不会执行有关文件上载的处理程序,也不会捕获任何异常。当我检查服务器端的网络流量时,我发现执行File.upload后没有http请求甚至命中服务器。代码如下。

<?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>

在Air Simulator上执行时,按预期正常工作,文件已成功上传到服务器。 但是当在iOS设备(在我的情况下,iPad)上执行时,正如我早期解释的那样,没有关于文件上传的处理程序被执行,并且没有http请求事件到达服务器。所以我认为问题可能在客户端。

在我尝试解决问题的过程中,我在iOS7上发现了一些棘手的问题。也就是说,如果在调用File.upload方法之前调用URLLoader.load方法(即使URLLoader.load指向不存在的地址),File.upload将在iOS7上按预期工作。更具体地说,当方法 OnUploadButtonPressed 之前执行 OnTrickyButtonPressed 方法时,File.upload将在iOS7上成功。但这只发生在iOS7上。在iOS8上,File.upload总是拒绝工作,无论之前是否执行过URLLoader.load。

我认为在我的情况下问题不是下面两个链接中描述的沙盒问题或Firefox会话问题,因为甚至没有任何http请求到达服务器端。 似乎因为某些原因,iOS版Air SDK无法发送http请求。

Flex 4 FileReference Issues With Firefox

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

为了使我的问题更清楚,我在下面列出了我的环境:

  • 开发环境:Windows7(64位)/ Mac OS 10.9.4(已测试 两个OS平台。)
  • IDE:Flash Builder 4.7
  • Air SDK:3.8 / 16.0.0(在我更新到最新的Air SDK 16.0.0之后 ,问题仍然存在。)
  • Application Server:Tomcat7 + Spring

最后,我想提一下,在我的情况下,使用URLLoader.load上传文件不是一个选项,因为我希望以后上传大文件,而这些文件无法使用URLLoader.load进行处理。

我已经为此奋斗了好几天。如果有人对此有任何想法,我真的很感激。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

最后我发现真正的问题不在于我提供的代码,而是关于http代理自动配置,而这个问题发生在iOS7和iOS8上。我在以下链接中详细描述了问题和解决方法。希望这会对你们中的一些人有所帮助。

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