Reputation: 91
We are trying to compile a recent fork of the route-me iOS SDK (Alpstein, MapBox or xmap) and create a Xamarin Binding Project from that.
The code we already tried can be found at these repositories (in descending order of freshness):
Unfortunately we are stuck at a pretty initial stage. route-me needs a TileSource to supply the tiles which are to be drawn on the canvas. So we need to expose the RMAbstractWebMapSource class to our C# Xamarin client code via the bindings. Since this class inherits from the RMAbstractMercatorTileSource class, we need to bind that one, too. At last we have to bind the RMTileSource protocol which RMAbstractMercatorTileSource implements.
Below are the definitions of the relevant classes and protocols in the Objective-C source:
Abstract class defined in RMAbstractWebMapSource.h
@interface RMAbstractWebMapSource : RMAbstractMercatorTileSource
Abstract class defined in RMAbstractMercatorTileSource.h
@interface RMAbstractMercatorTileSource : NSObject <RMTileSource>
Protocol defined in RMTileSource.h
@protocol RMTileSource <NSObject>
[BaseType (typeof (RMAbstractMercatorTileSource))]
public partial interface RMAbstractWebMapSource { ... }
[BaseType (typeof (NSObject))]
public partial interface RMAbstractMercatorTileSource : RMTileSource { ... }
[Model, Protocol, BaseType (typeof (NSObject))]
public partial interface RMTileSource { ... }
These Bindings compile fine. But at runtime..
RMAbstractWebMapSource tileSource = new MyTileSource(1234);
Where MyTileSource is defined as:
public sealed class MyTileSource: RMAbstractWebMapSource { ... }
The following run-time error gets thrown upon instantiation of a MyTileSource object (constructor call), simultaneously crashing the app:
NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead
NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement doesNotRecognizeSelector: -- abort
This error message can be found via Google (eg. http://www.touch-code-magazine.com/does-not-implement-methodsignatureforselector-trouble-ahead/). The answers found on the web indicate a problem with inheritance. It seems as though the MyTileSource class does not inherit from NSObject as it should. However, the generated code from the Xamarin Bindings project (found in ProjectDir/obj after a build) suggests otherwise:
public unsafe abstract partial class RMAbstractWebMapSource : RMAbstractMercatorTileSource { ... }
public unsafe partial class RMAbstractMercatorTileSource : NSObject, IRMTileSource { ... }
public unsafe partial class RMTileSource : NSObject, IRMTileSource { ... }
public interface IRMTileSource : INativeObject, IDisposable { ... }
We could not determine which selector failed. Trying to override void DoesNotRecognizeSelector(Selector sel) in MyTileSource yields a vaguely different error:
NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead
...(200x)...
NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead
And finally the native code crashes with a segmentation fault (SIGSEGV). We alse get a stacktrace from the mono runtime this time around. It basically starts at the invocation of the constructor of MyTileSource and dies in NSObject, as far as we can see:
mono-rt: at <unknown> <0xffffffff>
mono-rt: at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging.intptr_objc_msgSend (intptr,intptr) <IL 0x00026, 0xffffffff>
mono-rt: at MonoTouch.Foundation.NSObject.AllocIfNeeded () [0x00015] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSObject2.cs:390
mono-rt: at MonoTouch.Foundation.NSObject..ctor (MonoTouch.Foundation.NSObjectFlag) [0x00006] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSObject2.cs:102
mono-rt: at XMap.RMAbstractMercatorTileSource..ctor (MonoTouch.Foundation.NSObjectFlag) <IL 0x00002, 0x0002b>
mono-rt: at XMap.RMAbstractWebMapSource..ctor () <IL 0x00006, 0x00033>
mono-rt: at Saalplan.RxTileSource..ctor (int) [0x00000] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/RxTileSource.cs:12
mono-rt: at Saalplan.TileViewController.InitMapView () [0x00006] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/TileViewController.cs:24
mono-rt: at Saalplan.TileViewController.ViewDidLoad () [0x00008] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/
What is the correct way of binding this combination of inheritance and protocol implementation?
Upvotes: 1
Views: 1313
Reputation: 2647
For what it's worth for others coming across this. My issue was that my linkwith.cs file didn't contain LinkTarget.Simulator64. I was getting the error object xxx of class yyy does not implement methodSignatureForSelector: -- trouble ahead message.
Upvotes: 0
Reputation: 91
We got the bindings working now. The problem was our linkwith.cs file. Using the above bindings and the following linkwith.cs file worked:
[assembly: LinkWith ("libXMap.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, Frameworks = "CoreLocation QuartzCore UIKit Foundation CoreGraphics", LinkerFlags = "-lz -lsqlite3", ForceLoad = true, IsCxx = true)]
Upvotes: 1
Reputation: 2231
Have you had a look at the existing monotouch binding example? You can find it here:
https://github.com/mono/monotouch-bindings/tree/master/Route-Me
Upvotes: 0