ios - Flex ActionScript3 FileStream.writeObject 在 iOS 中静默失败 - 我做错了什么?

标签 ios apache-flex mobile actionscript filestream

使用 Flash Builder 4.7、AIR 3.5、Flex 4.6.0(内部版本 23201)的最终版本,并运行/调试快速构建到运行 iOS 6.0.1 (10A523) 的 iPad2 MC981LL

我已经浪费了一天多的时间在我认为应该相当简单的事情上,但在这一点上我完全不知所措。任何帮助表示赞赏。

我没有收到任何错误消息。运行后该文件存在,但大小仅为 128 字节。不用说,它只能作为 NULL 读入。我什至在 writeObject 函数中实例化了一个 Object() ,只是为了确定不是我的更复杂的对象导致了困难(为了简单起见,我暂时将 bitmapData 和缩略图属性留空)。没有骰子。

除了我试图在对象中读回之外,我已经包含了所有相关代码。

不用说,这最初是一个具有读取和写入功能的简单类,随着我不断尝试获取有关失败原因的可用信息,它变得越来越复杂。最初没有跟踪语句,没有自定义 even 和调度程序,没有 try、catch、finally,也没有事件监听器,任何可以给我线索的东西。

此外,我可能做错了整个自定义事件/处理程序/监听器/调度程序,因为使整个球滚动的类中的 statusMessage(底部的最后一个代码块)显示“将图像和缩略图保存到库”但从来没有“文件保存到库”

非常感谢任何帮助。

这是我的踪迹:

[SWF] PictureToolsOnTheMoveMakeIt.swf - 4,154,904 bytes after decompression
FileSerializer FUNCTION writeObjectToFile()
FileStream.openAsync(write) finally
FileStream.writeError() finally

FileSerializer 类:

package classes
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.errors.*;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;

    import events.FileSerializerEvent;

    import vo.PTotmImageVO;

    [Event(name = "writeComplete", type = "events.FileSerializerEvent")]
    [Event(name = "readComplete", type = "events.FileSerializerEvent")]

    public class FileSerializer extends EventDispatcher
    {
        private var fileStream:FileStream = new FileStream();

        public function FileSerializer(target:IEventDispatcher=null)
        {
            super(target);
        } // End CONSTRUCTOR FileSerializer

        public function writeObjectToFile(ptotmImageVO:PTotmImageVO, fnam    e:String):void
        {
            trace("FileSerializer FUNCTION writeObjectToFile()");
            var file:File = File.applicationStorageDirectory.resolvePath(ptotmImageVO.userid+"-"+ptotmImageVO.timestamp+".PTotmImageVO");

            fileStream.addEventListener(Event.CLOSE, close);
            fileStream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);

            try
            {
                fileStream.openAsync(file, FileMode.WRITE);
            }
            catch (e:SecurityError)
            {
                // The file location is in the application directory, and the fileMode parameter is set to "append",
                // "update", or "write" mode.

                trace("FileStream.openAsync(write) SecurityError "+e);
            }
            finally
            {
                trace("FileStream.openAsync(write) finally");
            }

            try
            {
                fileStream.writeObject(ptotmImageVO);
            }
            catch (e:IOError)
            {
                // The file has not been opened; the file has been opened, but it was not opened with write capabilities;
                // or for a file that has been opened for synchronous operations (by using the open() method), the file
                // cannot be written (for example, because the file is missing).
                trace("FileStream.writeObject() IOError "+e);
            }           
            finally
            {
                trace("FileStream.writeObject() finally");
            }
        } // End FUNCTION writeObjectToFile

        protected function close(e:Event):void
        {
            trace("FileSerializer FUNCTION close()");
            dispatchEvent(new FileSerializerEvent(FileSerializerEvent.WRITE_COMPLETE, null,true,true));
        } // End FUNCTION close

        protected function ioErrorEventHandler(event:Event):void
        {
            trace("FileSerializer FUNCTION ioErrorEventHandler()");
        } // End FUNCTION ioErrorEventHandler

        public function readObjectFromFile(fname:String):Object
        {
            var file:File = File.applicationStorageDirectory.resolvePath(fname);

            if(file.exists)
            {
                var obj:Object;
                var fileStream:FileStream = new FileStream();
                fileStream.addEventListener(Event.COMPLETE, readComplete);
                fileStream.open(file, FileMode.READ);
                obj = fileStream.readObject();
                fileStream.close();
                return obj;
            }
            return null;
        } // End FUNCTION readObjectFromFile

        protected function readComplete(event:Event):void
        {
            dispatchEvent(new FileSerializerEvent(FileSerializerEvent.READ_COMPLETE, event.target));            
        } // End FUNCTION readComplete
    } // End CONSTRUCTOR FileSerializer
} // End PACKAGE classes

值对象类:

package vo
{
    import flash.display.BitmapData;

    [remoteClass(alias="PTotmImageVO")]

    public class PTotmImageVO
    {
        public var userid:String;
        public var thumbnail:BitmapData;
        public var image:BitmapData;
        public var timestamp:Number;
        public var description:String;
        public var type:String;

        public function PTotmImageVO()
        {

        } // End Constructor PTotmImageVO
    } // End Class PTotmImageVO
} // End Package vo

事件类 FileSerializerEvent:

package events
{
    import flash.events.Event;

    public class FileSerializerEvent extends Event
    {
        public static const WRITE_COMPLETE:String = "writeComplete";
        public static const READ_COMPLETE:String = "readComplete";

        public function FileSerializerEvent(type:String, data:*=null, bubbles:Boolean = true, cancelable:Boolean = true)
        {
            super(type, bubbles, cancelable);

            switch(type)
            {
                case WRITE_COMPLETE:
                    break;
                case READ_COMPLETE:
                    break;
            }
        }
    }
}

最后,我创建对象、实例化类并使用创建的对象调用类的 writeObjectToFile() 函数的代码:

            private var ptotmImageVO:PTotmImageVO = new PTotmImageVO();
            private var fileSerializer:FileSerializer = new FileSerializer();

            protected function createThumbnail():void
            {
                thumbBmpData = ImageResizer.bilinearIterative(bmpData, borderRect.width, borderRect.height, ResizeMath.METHOD_LETTERBOX , true, 3);

                saveImageToLibrary();
            }

            protected function saveImageToLibrary():void
            {
                statusMessage.text = "Saving Image and Thumbnail to Library...";

                ptotmImageVO.userid = parentApplication.userid;
                ptotmImageVO.description = "";
                ptotmImageVO.timestamp = new Date().getTime();
//              ptotmImageVO.thumbnail = thumbBmpData;
//              ptotmImageVO.image = bmpData;
                ptotmImageVO.type = "PictureTools - On The Move - Photo Entity";

                    fileSerializer.addEventListener(FileSerializerEvent.WRITE_COMPLETE, saveComplete);
                fileSerializer.writeObjectToFile(ptotmImageVO, ptotmImageVO.userid+"-"+ptotmImageVO.timestamp+".PTotmImageVO");
            }

            protected function saveComplete(event:FileSerializerEvent):void
            {
                statusMessage.text = "File Saved to Library";
            }

嗯,好吧。不妨提供所有信息。这是我试图在其中读取对象的类,因为我计划使用 itemRenderer 在 Tile 布局中显示它们(希望 Apache Flex 4.9 中的新 DataGrid 很快)...

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark"
         creationComplete="drawBackground()"
         click="refreshFileListing()">

    <fx:Script>
        <![CDATA[
            import spark.components.VGroup;

            import classes.FileSerializer;          
            import events.FileSerializerEvent;
            import vo.PTotmImageVO;

            [Bindable]
            private var file:File = File.applicationStorageDirectory;
            [Bindable]
            private var directoryListing:String = new String();

            private var files:Array;
            private var fs:FileSerializer = new FileSerializer();


            public function refreshFileListing():void
            {               
                files = file.getDirectoryListing();

                trace("MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.nativePath -- "+file.nativePath);
                trace("MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.isDirectory -- "+file.isDirectory);
                trace("MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.name -- "+file.name);
                trace("MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.getDirectoryListing -- "+file.getDirectoryListing());
                trace("MyLibraryPhotoPanel FUNCTION refreshFileListing -- files.length -- "+files.length);

            var objects:Array = new Array();

                for (var i:uint = 0; i < files.length; i++)
                {
                    fs.addEventListener(FileSerializerEvent.READ_COMPLETE, fileReadComplete);

                    var f:String = files[i].name;
                    var o:PTotmImageVO = fs.readObjectFromFile(f) as PTotmImageVO;
                    objects.push(o); // Desperate at this point pretty much trying nonsense

                    trace("MyLibraryPhotoPanel FUNCTION refreshFileListing in for() -- o -- "+o);

                    // This is destined for an itemRenderer if ever I can get an object serialized to file and read back in.
//                  var b:BitmapData = o.thumbnail as BitmapData;
//
//                  var img:Image = new Image();
//                  img.source = b;
//
//                  var l:Label = new Label();
//                  l.text = files[i].name;
//
//                  var vg:VGroup = new VGroup();
//                  vg.addElement(img);
//                  vg.addElement(l);
//
//                  tg.addElement(vg);              

                    trace("MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#1 -- count/name/size -- "+i+". "+files[i].name+" "+files[i].size+"bytes");
                }

                for(var k:uint = 0; k<objects.length; k++)
                {
                    trace("MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#2 -- file object in Array -- "+k+". "+objects[k]);
                }
            } // End FUNCTION refreshFileListing

            protected function fileReadComplete(event:FileSerializerEvent):void
            {
                trace("MyLibraryPhotoPanel FUNCTION FileReadComplete");
            } // End FUNCTION fileReadComplete

            protected function drawBackground():void
            {
                with(graphics)
                {
                    beginFill(0xffffff,0);
                    drawRect(0,0,parent.width,parent.height);
                    endFill();
                }
            } // End FUNCTION drawBackground

        ]]>
    </fx:Script>
    <s:VGroup id="tg" height="100%" width="100%">
    </s:VGroup> 
</s:Group>

跟踪输出:

[SWF] PictureToolsOnTheMoveMakeIt.swf - 4,152,506 bytes after decompression
FileSerializer FUNCTION writeObjectToFile()
FileStream.openAsync(write) finally
FileStream.writeObject() finally
FileSerializer FUNCTION writeObjectToFile()
FileStream.openAsync(write) finally
FileStream.writeObject() finally
MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.nativePath -- /var/mobile/Applications/926FFAF1-3FBE-4854-A61C-3BB8A3752D50/Library/Application Support/org.PictureTools.Apps.PictureToolsOnTheMoveMakeIt.debug/Local Store
MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.isDirectory -- true
MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.name -- Local Store
MyLibraryPhotoPanel FUNCTION refreshFileListing -- file.getDirectoryListing -- [object File],[object File]
MyLibraryPhotoPanel FUNCTION refreshFileListing -- files.length -- 2
MyLibraryPhotoPanel FUNCTION refreshFileListing in for() -- o -- null
MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#1 -- count/name/size -- 0. 000000-1357831345565.PTotmImageVO 117bytes
MyLibraryPhotoPanel FUNCTION refreshFileListing in for() -- o -- null
MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#1 -- count/name/size -- 1. 000000-1357831356829.PTotmImageVO 117bytes
MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#2 -- file object in Array -- 0. null
MyLibraryPhotoPanel FUNCTION refreshFileListing in for()#2 -- file object in Array -- 1. null

最佳答案

已解决。元数据标记是 [RemoteClass... 而不是 [remoteClass],如我开始工作的示例代码中所示。由于编译器不检查这些标签,并且从技术上讲,编写您自己的标签并不是错误,因此 - 永远 - 不会有任何可用于工作的诊断数据。

关于ios - Flex ActionScript3 FileStream.writeObject 在 iOS 中静默失败 - 我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14259393/

相关文章:

ios - Objective-C 消息被发送到已释放的 'UIActivityIndicatorView' 对象

android - Flex DropDownList 在移动设备中工作异常

ios - Appium:是否可以在 iOS 中访问拨号盘并使用 appium 调用电话?

iOS 照片框架无法获取图像数据/UTI

objective-c - iOS 上的手势过滤

apache-flex - 如何防止 TextField 中的向上/向下箭头默认行为?

javascript - NativeScript SideKick 可以在 Windows 上运行 iOS 应用程序吗?

iphone - 您在开发移动应用程序时修复了哪些由于能源效率低下问题而导致的错误

ios - 请求桌面 html NSURLSession

apache-flex - Eclipse 告诉我在构建路径中检测到一个循环,但这不是真的!