Highlighted

ActionScript's File.upload does not work on Air SDK for iOS devices

Community Beginner ,
Feb 24, 2015

Copy link to clipboard

Copied

  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 even 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.

http://stackoverflow.com/questions/5967382/flex-4-filereference-issues-with-firefox

http://stackoverflow.com/questions/351258/how-do-i-make-flex-file-upload-work-on-firefox-and-safari

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

  • Development 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.

Hi KA RYU,

We have successfully reproduced the issue, our team would be working on this.

-Tushar

TOPICS
Development

Views

2.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

ActionScript's File.upload does not work on Air SDK for iOS devices

Community Beginner ,
Feb 24, 2015

Copy link to clipboard

Copied

  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 even 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.

http://stackoverflow.com/questions/5967382/flex-4-filereference-issues-with-firefox

http://stackoverflow.com/questions/351258/how-do-i-make-flex-file-upload-work-on-firefox-and-safari

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

  • Development 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.

Hi KA RYU,

We have successfully reproduced the issue, our team would be working on this.

-Tushar

TOPICS
Development

Views

2.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Feb 24, 2015 0
Adobe Employee ,
Mar 11, 2015

Copy link to clipboard

Copied

Moved to the development forum

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 11, 2015 1
Community Beginner ,
Mar 12, 2015

Copy link to clipboard

Copied

Chris.campbell, thank you very much to move this article to the right place. Hope someone will help me about this.

Recently I tried the same code on iOS6, and it works good. So probably this is a bug of the SDK, or a incompatibility issue with iOS8 .

I will also report it to Adobe as a bug report.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 12, 2015 0
Adobe Employee ,
Mar 13, 2015

Copy link to clipboard

Copied

Hi KA RYU,

We tried to reproduce the issue at our end. We tested with both AIRSDK 16 & 17, but it was found to be working fine for both iOS7 & iOS8, without using the above mentioned work-around (OnTrickyButtonPressed) . We could successfully upload the files to the web server. I am sharing the sample app that we made on the basis of code provided by you. Can you try reproducing the issue with the latest AIRSDK build?

Dropbox - fileUploadTest.fxp

Thanks,

Tushar

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 13, 2015 1
Community Beginner ,
Mar 20, 2015

Copy link to clipboard

Copied

Hi, tdwivedi. Thank you very much for your reply.

After I checked the issue thoroughly, 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,

not on iOS6. That is to say, the issue only happens on on iOS7 and iOS8 when you set your

[http proxy] in the wifi connection you use to [Auto],and input a URL that points to a *.pac file in your internal network.

To make it more clear, I listed below conditions under which the problem happens or not.

1.  Http Proxy [Off]

  • iOS6 : Everything is ok.
  • iOS7 : Everything is ok.
  • iOS8 : Everything is ok.

2.  Http Proxy [Auto] with a URL that points to a *.pac file in your internal network.

  • iOS6 : Everything is ok.
  • iOS7 : Can not upload using File.upload, but can upload using URLLoader.load.
  • iOS8 : Can not upload using File.upload, but can upload using URLLoader.load.

Firstly, I had thought that iOS7 and iOS8 does not process the  proxy Auto configuration file correctly,

but then I found that doesn't make sense considered the following questions.

1.  Why URLLoader.load works, while File.upload does not? (Just like File.upload, URLLoader.load also needs to get the *.pac file when the application tries to access network for the first time. )

2.  And why my browsers(Safari and Chrome) work fine with the same pac file.

So I thing the problem is in File.upload instead of iOS.

Then I tried to capture packets from iOS7 and iOS8, and found that URLLoader.load did send a http request to

the server in the internal network that hosts the pac file (Let us call it pac server). On the other hand,

File.upload's communication with the pac server failed in the TCP layer , so no http request was sent.

(I am sure that there is no firewall in the pac server that is trying to block the request.)

But on iOS6, both URLLoader.load and File.upload  successfully sent the http request to the pac server,

and as a result, everything works as expected.

So, in a word, I think that File.upload and URLLoader.load maybe use the different iOS APIs when trying to access the pac file, and the API which File.upload is using is no longer working after the iOS is updated to 7 or 8. Maybe File.upload should be modified to use the same ios API with whichever API URLLoader.load is using.

I uploaded my latest project file in the following link. Will you please check it. I think the same problem will also happen to you if you set [http proxy]  to [Auto].

https://github.com/bluewindjava8/upload

Thank you very much.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 20, 2015 0
Adobe Employee ,
Mar 26, 2015

Copy link to clipboard

Copied

Hi KA RYU,

Thank you for the information provided.

It's always great to work with someone who is ready to provide such details of the issue.

I will try to simulate such scenario. Will use your sample project as well for the investigation.

-Tushar

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 26, 2015 0
Community Beginner ,
Mar 26, 2015

Copy link to clipboard

Copied

Hi, Tushar

   Thank you very much for your reply.  So I look forward to your next message.

   Just for you to reproduce the issue easily, I list below the precise versions of iOS and devices I used.

  • iOS6 : 6.0.2 on iPad Mini
  • iOS7 : 7.1.2 on iPad4
  • iOS8 : 8.1.1 / 8.2 on iPad4

   Thanks, again.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 26, 2015 0
Adobe Employee ,
Apr 21, 2015

Copy link to clipboard

Copied

Hi KA RYU,

We have successfully reproduced the issue, our team would be working on this.

-Tushar

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Apr 21, 2015 2
New Here ,
Jun 01, 2015

Copy link to clipboard

Copied

Hello Tushar,

This problem looks a lot like a bug I submitted here "Bug#3997814 - flash.filesystem.File.Upload does not use the system proxy on iOS and Android"

Is it the same thing ? If yes, could you please give the info to your team ? Or give me a link to a bug that I could upvote ?

And do you have any idea when this bug will be fixed ?

Many Thanks,

Sebastien

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jun 01, 2015 0
Adobe Employee ,
Jun 04, 2015

Copy link to clipboard

Copied

Hi sebastienn1596843 ,


Please vote on the same bug that you have raised as there isn't any bug filed for this issue. We could reproduce the issue, but due to many other higher priority tasks at hand our team will be picks up the bug for fixing if there are substantial votes on the bug.

-Tushar,

Adobe AIR team

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jun 04, 2015 0
New Here ,
Jun 04, 2015

Copy link to clipboard

Copied

Thanks Tushar,

I can not vote for my own bug ... let's just say that this bug probably won't be fixed, so that people reading this thread don't get their hopes to high when they read "our team would be working on this".

People if you want this bug fixed, vote for the bug here : Bug#3997814 - flash.filesystem.File.Upload does not use the system proxy on iOS and Android"

Thanks anyways

Sebastien

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jun 04, 2015 0
Explorer ,
Jun 21, 2018

Copy link to clipboard

Copied

It looks like the bug has been marked "Closed/NeverFix". People were reporting it as late as AIR 18 I believe. Is there anyone who has made this work successfully on iOS or Mac? I am thinking about trying upload via FileReference (along the lines of here: https://discuss.as3lang.org/t/send-a-file-to-a-server-as-an-attachment-in-an-urlrequest-urlloader/32...), rather than File.upload(), but I don't know if that will make any difference.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jun 21, 2018 0
sbf LATEST
New Here ,
Mar 09, 2020

Copy link to clipboard

Copied

this is working for me

var file:File = selectedFile;
var multi:String = "-----------------------------" + nonce;
var pre:String = multi + "\r\nContent-Disposition: form-data; name=\"fname\"; filename=\""
    + text + "\"\r\nContent-Type: application/octet-stream\r\n\r\n";
var post:String = "\r\n" + multi + "\r\nContent-Disposition: form-data; name=\"nonce\"\r\n\r\n"
    + nonce + "\r\n" + multi + "--\r\n\r\n";
var urlRequest:URLRequest = new URLRequest(uploadURL);
urlRequest.method = "POST";
var header:URLRequestHeader = new URLRequestHeader("Content-Type", 
    "multipart/form-data; boundary=" + multi.substr(2));
urlRequest.requestHeaders.push(header);
var readStream:FileStream = new FileStream();
readStream.open(file, FileMode.READ);				
var data:String = readStream.readUTFBytes(readStream.bytesAvailable);
urlRequest.data = pre + data + post;
var loader:URLLoader = new URLLoader();
loader.load(urlRequest);

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Mar 09, 2020 0