AS3 Сохраните SWF на устройстве iOS, а затем загрузите его обратно в мувиклип.

У меня есть приложение для iOS, использующее AS3 и AIR. У меня внешние swf-файлы загружаются с сервера и нормально воспроизводятся — все работает отлично.

Я не хочу, чтобы пользователю приходилось загружать эти swf-файлы каждый раз, когда они запускают приложение, поэтому после первой загрузки swf-файла я хочу сохранить его на диск. Таким образом, я могу загрузить его из локальной копии, когда мне это понадобится в будущем, вместо того, чтобы загружать его снова. Я нашел этот пример онлайн для сохранения файлов в AS3:

var file:File = File.applicationStorageDirectory.resolvePath("Swfs/" + "mySwfName" + ".swf");
var wr:File = new File(file.nativePath);
var stream:FileStream = new FileStream();
stream.open(wr, FileMode.WRITE);
stream.writeBytes(SWF_FILE_GOES_HERE, 0, SWF_FILE_DATA_LENGTH_GOES_HERE);
stream.close();

Проблема в строке writeBytes. Образец, который я нашел, предназначался для сохранения изображений на диск, и эта строка читалась так:

stream.writeBytes(imageData, 0, imageData.length);

Но мне нужно сделать это для swf, а не для изображения, и я не знаю, как получить необходимые данные из моего swf-файла. Я искал в Интернете информацию о сохранении swf-файлов, получении данных из swf-файлов и т. д. Но ничего не нашел. Мне нужно получить данные swf и длину данных (я предполагаю, что это количество байтов?). Кто-нибудь решал эту проблему раньше или есть ресурс, на который они могут указать мне направление?


ОБНОВЛЕНИЕ: основываясь на комментариях @LondonDrugs_MediaServices, я понял строку writeBytes:

stream.writeBytes(mySwf.loaderInfo.bytes, 0, mySwf.loaderInfo.bytesTotal);

Кажется, это работает, поскольку компилируется и работает без ошибок. Но когда я пытаюсь получить файл и поместить его обратно в клип, я получаю эту ошибку:

Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.

Это означает, что файл на самом деле не был правильно сохранен. Однако когда я печатаю расположение файлов, они кажутся правильными! Когда я сохраняю файл в applicationStorageDirectory:

/Users/MyName/Library/Preferences/com.appdir/Local Store/Swfs/mySwName.swf

И имя файла, когда я пытаюсь загрузить его из хранилища в видеоклип:

/Users/MyName/Library/Preferences/com.appdir/Local Store/Swfs/mySwName.swf

Это код, который я использую, чтобы попытаться загрузить его обратно в клип:

var videoFileName:String = "Swfs/" + ENVAR.currentVideoSelected + ".swf";
var videoFilePath:File = File.applicationStorageDirectory.resolvePath(videoFileName);   
var inFileStream:FileStream = new FileStream(); 
trace("[Loading] filepath: ", videoFilePath.nativePath);
inFileStream.open(videoFilePath, FileMode.READ); 
var fileContents:String = inFileStream.readUTFBytes(inFileStream.bytesAvailable);   
inFileStream.close(); 

var req:URLRequest = new URLRequest(videoFilePath.nativePath);
var mLoader:Loader = new Loader();
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onVideoLoadComplete);
mLoader.load(req);

И моя функция onVideoLoadComplete содержит эти строки:

var myMC:MovieClip = e.target.content as MovieClip;
addChild(myMC);

Но я получаю эту ошибку 2044, и она не думает, что файл существует. Кто-нибудь может определить проблему? Спасибо!


person WendiKidd    schedule 31.08.2012    source источник
comment
help.adobe.com/en_US/ FlashPlatform/ссылка/actionscript/3/   -  person BadFeelingAboutThis    schedule 31.08.2012
comment
поэтому теоретически я думаю, что вы должны иметь возможность использовать свойство loaderInfo.bytes вашего swf, чтобы снова сохранить их с помощью stream.writeBytes, но никогда не пробовал, поэтому я не делаю этого в качестве ответа.   -  person BadFeelingAboutThis    schedule 31.08.2012
comment
Если вы собираетесь отправить это приложение в App Store, я думаю, оно будет отклонено, поскольку оно загружает и запускает внешний код (swf).   -  person sch    schedule 31.08.2012
comment
Если swf представляет собой просто контент, такой как воспроизводимый фильм или активы, и не содержит кода, все должно быть в порядке.   -  person Barış Uşaklı    schedule 31.08.2012
comment
@LondonDrugs_MediaServices Спасибо за информацию! Я попробую. BarisUsakli Да, это так. Это просто фильм :)   -  person WendiKidd    schedule 31.08.2012
comment
@LondonDrugs_MediaServices Еще раз спасибо за вашу помощь. Пожалуйста, смотрите мое обновление; Я думаю, что теперь я сохраняю его правильно, но я не могу понять, как использовать writeBytes, чтобы вытащить его обратно в мувиклип. Если вы можете указать мне правильное направление, вы получите мою вечную благодарность (и примите, если вы опубликуете это как ответ!)   -  person WendiKidd    schedule 01.09.2012
comment
Разве вы не могли бы просто получить его так же, как и удаленно, но вместо этого использовать локальный путь? Как с загрузчиком. У меня нет большого опыта загрузки файлов на iOS (например, что Apple блокирует и не разрешает).   -  person BadFeelingAboutThis    schedule 01.09.2012
comment
@LondonDrugs_MediaServices Ха-ха, я только что снова обновил вопрос, как только вы опубликовали это :) Я подумал об этом и попробовал, но выдает ошибку «URL не найден», подразумевая, что файл на самом деле не был сохранен должным образом. .   -  person WendiKidd    schedule 01.09.2012
comment
@LondonDrugs_MediaServices videoFilePath.exists возвращает значение true. Сейчас я пытаюсь преобразовать массив байтов в мувиклип — я понял, что использовал readUTFBytes, когда действительно хотел readBytes. Но документы кажутся противоречивыми — они говорят Reads the number of data bytes, specified by the length parameter, from the file stream, byte stream, or byte array. Но когда я пробую var swfBytes:ByteArray = inFileStream.readBytes(inFileStream);, мне говорят, что мне нужно передать объект ByteArray в readBytes. Если у меня уже есть массив байтов, какой смысл его читать? Не получайте использование этого fcn.   -  person WendiKidd    schedule 01.09.2012
comment
@LondonDrugs_MediaServices Как только я получу массив байтов, я думаю, что могу использовать такой загрузчик mLoader.loadBytes(swfBytes, loaderContext);, чтобы получить мувиклип из byteArray, но в первую очередь у меня возникают проблемы с получением byteArray.   -  person WendiKidd    schedule 01.09.2012
comment
давайте продолжим это обсуждение в чате   -  person BadFeelingAboutThis    schedule 01.09.2012


Ответы (1)


Вы можете получить необработанные байты загруженного SWF-файла, используя его параметр loaderInfo.bytes. Итак, для вашего примера вы можете сделать это:

var file:File = File.applicationStorageDirectory.resolvePath("Swfs/" + key + ".swf"); 
var wr:File = new File(file.nativePath); 
var stream:FileStream = new FileStream(); 
stream.open(wr, FileMode.WRITE); 
stream.writeBytes(mySwf.loaderInfo.bytes, 0, mySwf.loaderInfo.bytesTotal); 
stream.close(); 

Затем, чтобы вытащить его обратно в MovieClip:

var videoFileName:String = "Swfs/" + ENVAR.currentVideoSelected + ".swf";
var videoFilePath:File = File.applicationStorageDirectory.resolvePath(videoFileName); 
var inFileStream:FileStream = new FileStream(); 
inFileStream.open(videoFilePath, FileMode.READ); 
var swfBytes:ByteArray = new ByteArray();
inFileStream.readBytes(swfBytes);
inFileStream.close(); 

var mLoader:Loader = new Loader();
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
loaderContext.allowCodeImport = true;
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onVideoLoadComplete);
mLoader.loadBytes(swfBytes, loaderContext);
person BadFeelingAboutThis    schedule 31.08.2012