How come SPPlaylistFolder doesn't conform to SPAsyncLoading? - cocoalibspotify-2.0

I'm using CocoaLibSpotify 2.0 for my app.
With the 2.0 version of CLS, a bunch of objects conform to the SPAsyncLoading protocol, allowing you to use ´-waitUntilLoaded:...´. But SPPlaylistFolder doesn't conform to the protocol – does that mean that all its metadata is loaded as soon as I get hold of the instance or do I have to use KVO on its properties?
Is there a reason as to why SPPlaylistFolder doesn't conform to the SPAsyncLoading protocol?

If you have a SPPlaylistFolder, it's been loaded — due to various boring implementation details, folder metadata is loaded alongside SPPlaylistContainer, so as soon as that's loaded and you can access folders, folder metadata has already completed loading.

Related

Using Realm in a Swift framework creating challenges for host iOS apps also using Realm

I'm working on a closed source Swift framework that uses Realm internally. In the process of testing this framework, I'm using the framework within an iOS app that also uses Realm.
When the framework creates it's own Realm, it uses a Realm.Configuration specific to the framework. The host app creates Realm objects using the default Realm configuration. The Realms are 'separate'.
There are a couple problems:
When the host app creates a Realm reference, the underlying database ends up with tables for all the private Realm Object classes that are inside the framework. This exposes some knowledge of the internals of our framework to anyone that uses our framework and creates their own Realm.
Because all tables are getting created in all Realms, there is a problem when a migration is required. Inside our framework, we can provide a migration to run, but when the host app creates it's Realm, and the framework internal classes are updated, there is no migration for the host app to run, and the app crashes with a migration error.
Is there any way to use two completely separate Realms within one app?
I may be able to specify the list of classes for the framework Realm when using RealmConfiguation's objectTypes option, but that would require any user of our framework to do the same. That seems unreasonable, and also still allows 1. above to be a problem.
Yes, it's possible to have two separate libraries/frameworks/codebases in an app use Realm independently and keep their model objects completely separate.
If you have a collection of Realm Object subclasses that you would like to keep private, you can mark them so they won't automatically be added to the app's default schema by adding the following static method override:
public class MyModel: Object {
public override class func shouldIncludeInDefaultSchema() -> Bool {
return false
}
}
This class will then only be added to a Realm database if it is explicitly declared in the objectTypes property of that Realm's Configuration object.
This way, you can isolate all of your own Realm model classes to just your own framework, and the parent app can use Realm in the original context without any objects getting mixed up in it.

What is the purpose of RegisterFmxClasses?

What is the purpose of RegisterFmxClasses ? When i create some components, i always do RegisterComponents, but in the Delphi source file i see that they also do (not always) RegisterFmxClasses. But i can't understand what is the exact purpose of RegisterFmxClasses. In the help they say :
Registers a set of FireMonkey classes and adds a set of classes to the
FireMonkey group objects.
I create components for the firemonkey framework, but with or without RegisterFmxClasses they work well.
From the RegisterFmxClasses() documentation:
Call RegisterFmxClasses to register a set of custom classes in a single line. Each class is registered by calling RegisterClass. Unregistered classes cannot be loaded or saved by the component streaming system.
The GroupClasses classes are added to the group where TFmxObject resides by calling GroupDescendentsWith.

Classes in NSBundles

The most common use of NSBundle seems to be to keeb nib files and such files. But from what I read it seems I could bundle classes as well but I can't find any example of how to achieve this. Could you provide an example of this and if so, can you tell me if dynamically loading the methods of such class into an existing class would be forbiden by Apple?
It is indeed forbidden to dynamically load framework bundles in iOS. See below link for relevant docs:
https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW28
Note: The creation and use of loadable bundles is not supported in
iOS.

Read CoreData in Today Widget in Swift or Objective-C

I really need some simple code for me how to read CoreData in TodayWidget
This steps I made:
Create new project with using CoreData (in AppDelegate)
Make an Entity in CoreData model and some Attributes like a name or date
in ViewController of App fill name and date with one record like "Martin" "10/11"
And Now I need to read this name in TodayViewController
Please really post here just some simple code from it, or how to edit AppDelegate for using appgroup ...
Thanks !
Widgets have to be able to read the data in their code. In order to do this, you need to setup your CoreData files to be located in a 'group' folder in your project (You can set your CoreData Stack to relocate it's files in this folder). Then you'll configure a CoreData Stack in your extension that points to the same files. These group folders are folders that can be access across multiple targets/applications that have permissions for the group.
I will point out that it's far easier to use and sync NSUserDefaults across a widget and it's appropriate application than it is CoreData.
You'll want to read Apple's documentation about sharing extension data below:
Apple docs
Note the following section:
Sharing Data with Your Containing App
Even though an app extension bundle is nested within its containing
app’s bundle, the running app extension and containing app have no
direct access to each other’s containers.
BACKGROUND
To learn about containers, read About the iOS File System in File
System Programming Guide.
You can, however, enable data sharing. For example, you might want to
allow your app extension and its containing app to share a single
large set of data, such as prerendered assets.

How to duplicate a MovieClip in AS3 that is contained in an external SWF, loaded from an iOS air application?

I have an iOS application for a catalog that loads assets (with no ActionScript) from a remote server, so those assets (a catalog), can be updated by the catalog editors in order to create a new issue of the catalog every month.
Air for iOS allows you to load SWF files without ActionScript code on them. So I´m loading my assets from external SWF files and testing succesfully by compiling in Ad Hoc, or App Store modes.
Some of those assets are animated movieclips (with intenal movieclips, several frames and motion animations) which need to be instantiated several times (a random number of times) in the app, for an interactive feature.
SOME BACKGROUND:
The standard way to create repeatable items is by assigning them a Linkage Class Name in the Flash IDE, which works fine for desktop apps, but this seems to be interpreted as code by iOS, so it is not imported when I load the assets, so the element can not be instantiated from the APP.
There are several attempts to replicate the old as2 duplicateMovieClip function but they don´t duplicate internal movieclips, motions and internal movieclips. This is an example.
In this question, they say it´s not possible and propose a solution in which the movieclip has to be included in the main app, but in that way the editors would not be able to update the graphics and the animations once the app is approved in the store. The whole point is to allow the editor to update the products catalog.
Here is an additional discussion about the topic.
POSSIBLE SOLUTIONS TO EXPLORE:
I´m thinking of implementing some kind of recursive iteration creating every DisplayObject from scratch, but I still can´t find a concistent way to duplicate a shape created by the editor in the Flash UI. In fact, they say it´s not possible either, all that can be done is to create "bitmap" copies which is likely to be too heavy in processing specially if one create too many copies.
I guess, probably the only way is to find some compilation hack to make let the external SWF define the new Class so the instance can be created in the main app. For now, the editor is not going to be able to change duplicable objects.
There is also the possibility of having the duplicable element in a separate SWF, and load it several times, but I don´t know if that would work although that would be a little unglier for the designer.
I also tried to serialize an unserialize the whole movieclip, but I have not been able to find a concistent method for that either.
A note for the developers of Adobe Flash :
The ARM/iOS implementation of the AS3 Loader class should be changed to include the linked classes in the execution context, because the developer expects to be able to instantiate movieclips with a linked class even if they are contained in an external SWF loaded from an iOS air application. Currently the instantiation fails in iOS-air, but it works fine in desktop. I understand that apple does not allow the execution of code loaded from the external SWF, but this is not code execution, this is just a Class linkage that can be used to create multiple instances of the movieclip from the actual application code.
Can anyone help?
Had the same issue myself, and I ended up using the duplicated symbol on the stage of the external SWF. I duplicated the symbol about 30 times on the stage
I named the instances sequentially, e.g. card0 card1 card2 etc
Then in the code, I have a for loop that gets a reference to these objects, inside the loaded SWF, and puts them in an pool (Array) and then removes them as children from the external swf
The garbage collector doesn't seem to delete the objects, as they are still referenced by the Array
I then have code that manages the allocation of items from the pool, rather than instantiating them.
It does make the external swf a bit bigger, but not much for the 30 items in my pool as they are only references to the symbol in the library
You could write a JSFL script to do the duplication and naming in the FLA to automate the process.
BTW.
I tried a few other (cleaner) methods, but none of them worked on iOS
On the PC I was able to get the class definition from the symbol inside the external SWF if I marked it as Export For ActionScript, and then instantiated the class.
e.g.
applicationDomain.getDefinition("Card") as Class;
Note. I set the loader context
var ldrContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain );
for the loaded swf to be the same as the current application domain, as otherwise iOS isnt able to load and use the SWF at all.
However this only worked on the PC and strangely not on the Mac (OSX).
My next attempt was to put one copy of the symbol on the stage and use
e.g.
_cardSWFClass = Object(_contentSWF.card).constructor;
where contentSWF is MC object of the externally loaded swf, and "card" is the instance name on stage of of the object to be cloned.
This method works on both the PC and the Mac, but not on iOS
However, I have a feeling that this was only working, on PC and Max, because, I may have had the same class name in the FLA that was loading the external SWF, as the external SWF, as I'd copied the symbol from the App to the external content.
It also makes me wonder if whether it would be worth trying having the external MC use the same package name as the App code, rather than the external swf that was loaded in my case didn't have a class or package name defined for the SWF
i.e define empty classes in the App FLA / code, and in the external SWF reference the same class names, within the same package as the App FLA.
These classes would probable need to be empty (possibly no AS file at all), as iOS is not supposed to load external SWF's that contain code.
However in practice it seems that iOS will load external SWF's that contain timeline code, but the code is removed by the loader.
Further avenues to explore could be the method that is available to build code for externally loaded SWF's inside the core App code, and which is somehow bound at run time.
A byproduct of this may allow instantiation of external symbols (in fact I guess it would definitely need to, otherwise it seems pointless)
i.e as in this overview http://blogs.adobe.com/airodynamics/2012/11/09/packaging-and-loading-multiple-swfs-in-air-apps-on-ios/
However time pressures prevented me from exploring this any further.
Edit. Ignore the link. I think its a red herring.
Edit 2.
I have a partial, solution which may work for some people.
My hunch about using the same package names and class names in both the class that loads the SWF and the external SWF itself seems to be correct.
However it only works using this method where there is an instance of the symbol on the stage of the external content, which can be used to access the constructor for the external symbol.
It doesn't seem to work using the getDefinition method.
e.g. this code gets the Class of the instance called "card" in _contentSWF
_cardSWFClass = Object(_contentSWF.card).constructor;
Also note, that on the PC (though not on the Mac and possibly not on the iOS), it was necessary for the Class in question to define all of its named sub objects i.e as if you were not automatically declaring instances on the Stage.
In my case, my "card" symbol had a TextField named txt, and some other attributes I needed to store data, so I had to add these to the class e.g.
package DragAndDrop
{
import flash.display.MovieClip;
import flash.text.TextField;
/**
* ...
* #author Roger Clark
*/
public class Drag extends MovieClip
{
public var txt:TextField;
public var originalX:Number;
public var originalY:Number;
public var itemData:XML;
public function Drag()
{
}
}
}
One Note.
The Class that is instantiated is not DragAndDrop.Drag (or just Drag) i.e although both PC and Mac report that trace(_cardSWFClass); is [class Drag] on the Mac this fails at runtime and gives an error #1034 (Type Coercion failed) as the runtime type was reported as DragAndDrop.Drag#9a40e51 on my Mac
So its necessary to declare the object type as :MovieClip that is instantiated. It doesn't seem to be possible to cast it to Drag (only to MovieClip)
Just one caveat. I've not done extensive testing to see if there are any other limitations to this, but it does appear to work for me using AIR 4 and iOS6.
Edit 3.
I just spotted one more thing. Its not necessary for the Class source file to be accessible by the external FLA when the SWF is "published".
I realized that I had accidentally got the paths wrong, and that my external FLA didn't have access to the class AS file, and was creating its own empty class definition on the fly.
I retested it, with the correct paths, and it didn't seem to make any difference, i.e it still worked on PC, Mac and iOS
Additionally, I tried to remove the properties from the external Class definition file, for items which were not defined in the external FLA e.g. originalX and originalY, but without these, I get runtime errors on the PC.
I find these runtime errors quite strange, as I'm declaring the class that is instantiated as being a MovieClip and MovieClip is a dymanic class.
So its as if Flash considers the class that its instantiating to be some special type of non-dynamic MovieClip
Edit 4.
I've come across another caveat to this work around.
It appears that, under some circumstances, the symbols that are needed for duplication (by accessing their constructor), need to be present on frame 1 of the external SWF, and possibly all other frames in the external MC.
If you attempt to get the constructor of these instances, and they are not present on frame 1, the class that Flash returns is just MovieClip and not the class that has been defined for the symbol (defined in the library).
Note. The symbols are marked for export on frame 1, so that's not the reason.
At the moment, I'm not entirely sure the exact circumstances when this occurs, as it may be something to do with the path the external swf is loaded from, or it could be caused when an AIR app loads the external SWF.
i.e it works OK when I load the SWF directly into another SWF (on the PC), but fails (on the PC) when the external SWF is loaded from an SWC which is compiled as part of an AIR App.
I will post more information if I ever get to the precise cause of these discrepancies.
Edit 5.
This is a bit of an ongoing saga.
I have found one issue with using this approach.
On iOS you need to load the SWF into the current ApplicationDomain, otherwise the SWF can't be used at all.
However, if you load different SWF's with symbols in them with the same class name, Flash caches the first instance (symbol) that is instantiated using this method.
The normal work around for this is to create a new Application domain for each swf that is loaded, and release the domain afterwards.
See ApplicationDomain clarifiation needed
However this doesn't work on iOS as you appear to always need to load into ApplicationDomain.current domain
See problems with loading embedded swf files in air app
So although my work-around does work, it will not be of much use if you want to load multiple external swfs each with symbols with the same class name, but different graphic content.

Resources