"The native class hasn't been loading" error with my bindings - ios

I'm trying to create bindings for GPUImage project, but none of binded classes is working.
For example, GPUImageView:
In ObjC it's declared like this (header in git):
#interface GPUImageView : UIView <GPUImageInput>
//then some fields, properties and methods I'm not interested in
So, my ApiDefinition.cs looks like this:
namespace GPUImage
{
[BaseType (typeof(NSObject))]
[Model]
interface GPUImageInput {
}
[BaseType (typeof(UIView))]
interface GPUImageView : GPUImageInput {
[Export ("initWithFrame:")]
IntPtr Constructor(RectangleF frame);
}
}
LinkWithAttributes:
[assembly: LinkWith ("libGPUImage.a", LinkTarget.Simulator | LinkTarget.ArmV7 | LinkTarget.ArmV7s, ForceLoad = true, Frameworks = "CoreMedia CoreVideo OpenGLES QuartzCore AVFoundation UIKit Foundation")]
It builds ok and creates dll. But when I try to use it in my project like this:
var iv = new GPUImageView (new RectangleF (0, 0, 100, 100));
Exception throwed:
Could not create an native instance of the type 'GPUImage.GPUImageView': the native class hasn't been loaded.
It is possible to ignore this condition by setting Class.ThrowOnInitFailure to false.
Stacktrace
After MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure == false iv was created, but unusable (e.g. AddSubview(iv) show nothing).
I suppose there is something wrong with GPUImage.a file, but I don't know how to test it in any way.
Here is 7z with 2 projects in it: TryingBindings -- bindings themselves; TryingGPUImage -- bindings in use;
Thanks in advance.
P.S. Here is the link to this post on xamarin forums.

Thanks to Rolf Bjarne Kvinge
There are two problems:
1) The file with the LinkWith attribute (libGPUImage.linkwith.cs) is
not compiled. Just right-click the TryingBindings project, Add, Add
files and select it.
2) The native library does not contain code for i386 (simulator), only
arm (device). If you're building the native library yourself you can
either create a universal library that contain code for all the
architectures, or you can use several native libraries, each
supporting a different set of architectures, and just have a LinkWith attribute for each native library.
Bug 11497

Related

How to generate a .framework depending from another with Kotlin/native?

I have some dependencies issues with KMP and iOS Framework.
Here is some context:
I have 2 KMP modules:
An API module: define only interfaces
A classic lib use the API module as injection
I also have 2 android projects and 2 iOS projects:
an Android and iOS application (that use the KMP ClassicLib)
an Android and iOS lib that implement the API module
On Android, I have the following :
// KMP API project
public interface Foo
// KMP libA project
public class Bar {
fun doSomething(foo: Foo)
}
// ANDROID: libB project
import API
public class FooImpl: Foo { }
// ANDROID app
import libA
import libB
var foo = FooImpl()
var bar = Bar()
bar.doSomething(foo) // <----- Everything is fine here
but on iOS, I have this:
// iOS app
import libA
import libB
var foo = FooImpl()
var bar = Bar()
bar.doSomething(foo) // <----- Error here : FooImpl is of type APIFoo but here LibAAPIFoo is excpected
Indeed when I take a look into the generated headers, I have the following:
// KMP API.h
#protocol APIFoo
#end;
// KMP libA.h
#protocol LibAKAFoo // <----- here we have a redefinition of the protocol.
#end;
#interface Bar
- (void)doSomething:(KMPKAFoo)foo;
#ends;
I was expecting to have something more like :
// KMP API.h
#protocol APIFoo
#end;
// KMP libA.h
#include <API/API.h> // <----- import the API
#interface Bar
- (void)doSomething:(APIFoo)foo; // <----- use it
#ends;
Is there a special configuration that I'm missing into my build.gradle ?
I've tried to use compileOnly into the dependencies definition, but it had no effect and have the same behavior as implementation
val commonMain by getting {
dependencies {
compileOnly("com.poc.sample:KMPAPI:0.0.1")
}
You cannot create multiple Kotlin iOS frameworks and use them in the same project interchangeably. When the Kotlin compiler creates an iOS framework, it is its "own world", as in it includes everything you need (dependencies, etc). It's one big binary.
The summary is, the config you want is not possible. You can use multiple Kotlin iOS frameworks in the same project, but they need to be fully independent. They won't be able to communicate with each other.

Xamarin Dependency Injection fails - crash while trying to get platform specific implementation

I've got a Xamarin Forms interface that defines a Bluetooth controller. I'm following the usual technique when trying to create an Android specific implementation of this (I will also do an iOS one when I get this working).
I define my interface as follows :
namespace ArduinoRobotController.Models
{
public interface BluetoothControllerInterface
{
List<string> GetPairedDevices();
..
Then I have my platform specific implementation like this :
[assembly: Xamarin.Forms.Dependency(typeof(BluetoothControllerInterface))]
namespace ArduinoRobotController.Droid.Implementations
{
public class BluetoothController : BluetoothControllerInterface
{
..
Then finally back in one of my view models, I have this code to get the platform specific instance I need :
BluetoothControllerInterface bt = Xamarin.Forms.DependencyService.Get<BluetoothControllerInterface>();
It builds and runs, but crashes on the line above. The error states :
System.MissingMethodException: Default constructor not found for type ArduinoRobotController.Models.BluetoothControllerInterface at SystemRuntimeType.CreateInstanceMono
.. etc.
I've tried lots of different ways around doing this, including calling to register the implementation in normal code rather than as [assembly etc. Any help on this really appreciated.
your registration needs to point to the concrete class, not the interface
[assembly: Xamarin.Forms.Dependency(typeof(BluetoothController))]

How to use Namespaces in Swift?

The documentation only mentions nested types, but it's not clear if they can be used as namespaces. I haven't found any explicit mentioning of namespaces.
I would describe Swift's namespacing as aspirational; it's been given a lot of advertising that doesn't correspond to any meaningful reality on the ground.
For example, the WWDC videos state that if a framework you're importing has a class MyClass and your code has a class MyClass, those names do not conflict because "name mangling" gives them different internal names. In reality, however, they do conflict, in the sense that your own code's MyClass wins, and you can't specify "No no, I mean the MyClass in the framework" — saying TheFramework.MyClass doesn't work (the compiler knows what you mean, but it says it can't find such a class in the framework).
My experience is that Swift therefore is not namespaced in the slightest. In turning one of my apps from Objective-C to Swift, I created an embedded framework because it was so easy and cool to do. Importing the framework, however, imports all the Swift stuff in the framework - so presto, once again there is just one namespace and it's global. And there are no Swift headers so you can't hide any names.
EDIT: In seed 3, this feature is now starting to come online, in the following sense: if your main code contains MyClass and your framework MyFramework contains MyClass, the former overshadows the latter by default, but you can reach the one in the framework by using the syntax MyFramework.MyClass. Thus we do in fact have the rudiments of a distinct namespace!
EDIT 2: In seed 4, we now have access controls! Plus, in one of my apps I have an embedded framework and sure enough, everything was hidden by default and I had to expose all the bits of the public API explicitly. This is a big improvement.
Answered by SevenTenEleven in the Apple dev forum:
Namespaces are not per-file; they're per-target (based on the
"Product Module Name" build setting). So you'd end up with something
like this:
import FrameworkA
import FrameworkB
FrameworkA.foo()
All Swift declarations are considered to be part of
some module, so even when you say "NSLog" (yes, it still exists)
you're getting what Swift thinks of as "Foundation.NSLog".
Also Chris Lattner tweeted about namespacing.
Namespacing is implicit in Swift, all classes (etc) are implicitly
scoped by the module (Xcode target) they are in. no class prefixes
needed
Seems to be very different what I have been thinking.
While doing some experimentation with this I ended up creating these "namespaced" classes in their own files by extending the root "package". Not sure if this is against best practices or if it has any implications I'm mot aware of(?)
AppDelegate.swift
var n1 = PackageOne.Class(name: "Package 1 class")
var n2 = PackageTwo.Class(name: "Package 2 class")
println("Name 1: \(n1.name)")
println("Name 2: \(n2.name)")
PackageOne.swift
import Foundation
struct PackageOne {
}
PackageTwo.swift
import Foundation
struct PackageTwo {
}
PackageOneClass.swift
extension PackageOne {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
PackageTwoClass.swift
extension PackageTwo {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
Edit:
Just found out that creating "subpackages" in above code wont work if using separate files. Maybe someone can hint on why that would be the case?
Adding following files to the above:
PackageOneSubPackage.swift
import Foundation
extension PackageOne {
struct SubPackage {
}
}
PackageOneSubPackageClass.swift
extension PackageOne.SubPackage {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
Its throwing a compiler error:
'SubPackage' is not a member type of 'PackageOne'
If I move the code from PackageOneSubPackageClass.swift to PackageOneSubPackage.swift it works. Anyone?
Edit 2:
Fiddling around with this still and found out (in Xcode 6.1 beta 2) that by defining the packages in one file they can be extended in separate files:
public struct Package {
public struct SubPackage {
public struct SubPackageOne {
}
public struct SubPackageTwo {
}
}
}
Here are my files in a gist:
https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
I believe this is achieved using:
struct Foo
{
class Bar
{
}
}
Then it can be accessed using:
var dds = Foo.Bar();
Namespaces are useful when you need to define class with the same name as class in existing framework.
Suppose your app has MyApp name, and you need to declare your custom UICollectionViewController.
You don't need to prefix and subclass like this:
class MAUICollectionViewController: UICollectionViewController {}
Do it like this:
class UICollectionViewController {} //no error "invalid redeclaration o..."
Why?. Because what you've declared is declared in current module, which is your current target. And UICollectionViewController from UIKit is declared in UIKit module.
How to use it within current module?
var customController = UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
How to distinguish them from another module?
var customController = MyApp.UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
Swift uses modules much like in python (see here and here) and as #Kevin Sylvestre suggested you can also use the nested types as namespaces.
And to extend the answer from #Daniel A. White, in WWDC they were talking about the modules in swift.
Also here is explained:
Inferred types make code cleaner and less prone to mistakes, while
modules eliminate headers and provide namespaces.
You can use extension to use the mentioned structs approach for namespacing without having to indent all of your code towards the right. I've been toying with this a bit and I'm not sure I'd go as far as creating Controllers and Views namespaces like in the example below, but it does illustrate how far it can go:
Profiles.swift:
// Define the namespaces
struct Profiles {
struct Views {}
struct ViewControllers {}
}
Profiles/ViewControllers/Edit.swift
// Define your new class within its namespace
extension Profiles.ViewControllers {
class Edit: UIViewController {}
}
// Extend your new class to avoid the extra whitespace on the left
extension Profiles.ViewControllers.Edit {
override func viewDidLoad() {
// Do some stuff
}
}
Profiles/Views/Edit.swift
extension Profiles.Views {
class Edit: UIView {}
}
extension Profiles.Views.Edit {
override func drawRect(rect: CGRect) {
// Do some stuff
}
}
I haven't used this in an app since I haven't needed this level of separation yet but I think it's an interesting idea. This removes the need for even class suffixes such as the ubiquitous *ViewController suffix which is annoyingly long.
However, it doesn't shorten anything when it's referenced such as in method parameters like this:
class MyClass {
func doSomethingWith(viewController: Profiles.ViewControllers.Edit) {
// secret sauce
}
}
Even though it is possible to implement namespaces using Framework and Libraries but the best solution is to use local packages using Swift Package Manager. Besides having access modifiers, this approach has some other benefits. As in Swift Package Manager, the files are managed based on the directory system, not their target member ship, you won't have to struggle with merge conflicts that arise frequently in teamworks. Furthermore, there is no need to set file memberships.
To check how to use local Swift packages refer to the following link:
Organizing Your Code with Local Packages
In case anyone was curious, as of June 10th 2014, this is a known bug in Swift:
From SevenTenEleven
"Known bug, sorry! rdar://problem/17127940 Qualifying Swift types by their module name doesn't work."

Dart 2 libraries in one lib folder causing type 'X' is not a subtype of type 'X'

I have a following problem:
In my application, I have web and lib folders.
Lib folder is supposed to contain utility libraries.
Example:
lib/my_lib.dart
library my_lib;
part 'src/person.dart';
lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
In my_lib1, I want to use classes defined in my_lib
the classes are as follows:
lib/src/person.dart
part of my_lib;
class Person {
}
lib/src/other.dart
part of my_lib1;
class Other {
Person p;
Other(this.p) {
print(p);
}
}
Now, in web/testpackage.dart
import 'package:TestPackage/my_lib.dart';
import 'package:TestPackage/my_lib1.dart';
void main() {
Person p = new Person();
Other o = new Other(p);
}
Fails with:
Exception: type 'Person' is not a subtype of type 'Person' of 'p'.
Other.Other (package:testpackage/src/other.dart:7:14)
How should I structure my project to prevent that?
My libraries are local to the app, and I don't really want to develop them separately for my toy project.
Problem in that the your library my_lib is a publiclibrary and anyone (and you, of course) can use it elsewhere outside of lib directory.
In this case it must be imported (becuase it's a public library) always as the package library.
To solve this this problem you must change your source code.
From this lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
To this lib/my_lib1.dart
library my_lib1;
import 'package:TestPackage/my_lib.dart';
part 'src/other.dart';

How to use the [mixin] tag in AS3 applications?

I have the following two projects in in Flex Builder 3:
One AS3 library project (generates a SWC file)
One Flex application project (MXML Application)
The MXML Application references to the AS3 library project (Flex build path). So far, so good. I now want to run code automatically when an application uses the AS3 library. The [mixin] tag should do exactly what I need.
I followed the instructions from http://nondocs.blogspot.com/2007/04/metadatamixin.html and checked out the AutoQuick project. The latter is an example project by Adobe showing the use of the automation framework. In this project they are using the [mixin] tag (class AQAdapter).
I followed the examples but my code is not working. The static init method is not called. I added the library to the compiler arguments list that didn't work either.
How do I get this to work?
/* class to be automatically loaded */
package {
/* includes */
[mixin]
public class TestApp extends Sprite {
/* additional members */
private static var mContainer:DisplayObjectContainer;
private static var mInstance:TestApp;
/**
* #private
*/
public static function init(root:DisplayObject):void
{
if(!mInstance)
{
mContainer = root as DisplayObjectContainer;
mContainer.addEventListener(FlexEvent.APPLICATION_COMPLETE, applicationCompleteHandler);
}
}
}
}
With the [Mixin] tag, the static init() method will be called at application start-up, as long as the class is referenced directly or indirectly from the main application.
Also, you have to remember that this method is run in a static context, so you shouldn't reference methods or attributes that require an instance (non-static), without creating the instance first.
Link: http://adamflater.blogspot.com/2007/03/static-code-blocks.html

Resources