Hi, I'm trying to generate a xamarin.iOS Binding Library which exposes a dynamic swift library (.framework).
I did follow the tutorial using _objective sharpie tool _and the c# wrapper is well generated.
The SDK is working fine, but I have some _callbacks _in my application which are well called, but some of them are passing me references **to complex objects who inherit from NSObject.
I know the objects composition (it's a swift structure) so I should be able to access my objects properties using > obj.ValueForKey("propertyName"), but every time this raises a **NSUnknownKeyException: this class is not key value coding-compliant for the key propertyName.
For exemple here i'm interested into TripPoint object, this is the native library definition :
@class TripPoint; @class CLLocation; SWIFT_PROTOCOL("_TtP20DriveKitTripAnalysis12TripListener_") @protocol TripListener - (void)tripStartedWithStartMode:(enum StartMode)startMode; - (void)tripPointWithTripPoint:(TripPoint * _Nonnull)tripPoint; - (void)tripFinishedWithPost:(PostGeneric * _Nonnull)post response:(PostGenericResponse * _Nonnull)response; - (void)tripCancelledWithCancelTrip:(enum CancelTrip)cancelTrip; - (void)tripSavedForRepost; - (void)beaconDetected; - (void)significantLocationChangeDetectedWithLocation:(CLLocation * _Nonnull)location; - (void)sdkStateChangedWithState:(enum State)state; @end SWIFT_CLASS("_TtC20DriveKitTripAnalysis9TripPoint") @interface TripPoint : NSObject - (nonnull instancetype)init SWIFT_UNAVAILABLE; + (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable"); @end
The website documentation references this object as :
public struct TripPoint { let latitude: Double let longitude: Double let speed: Double let accuracy: Double let elevation: Double let distance: Double let heading: Double let duration: Double }
So sharpie is generating the entity in ApiDefinitions.cs as :
// @interface TripPoint : NSObject
[BaseType (typeof(NSObject), Name = "_TtC20DriveKitTripAnalysis9TripPoint")]
[DisableDefaultCtor]
interface TripPoint
{
}
and the output object looks like :
public unsafe partial class TripPoint : NSObject { [BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)] static readonly IntPtr class_ptr = Class.GetHandle ("_TtC20DriveKitTripAnalysis9TripPoint"); public override IntPtr ClassHandle { get { return class_ptr; } } [BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)] [EditorBrowsable (EditorBrowsableState.Advanced)] protected TripPoint (NSObjectFlag t) : base (t) { IsDirectBinding = GetType ().Assembly == global::ApiDefinitions.Messaging.this_assembly; } [BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)] [EditorBrowsable (EditorBrowsableState.Advanced)] protected internal TripPoint (IntPtr handle) : base (handle) { IsDirectBinding = GetType ().Assembly == global::ApiDefinitions.Messaging.this_assembly; } } /* class TripPoint */
Everything looks fine to me and my guess is that I should be accessing TripPoint properties like this : > tripPoint.ValueForKey((NSString)"speed"), but I have NSUnknownKeyExceptionevery time. So I must be missing something.
Maybe you would have a guess ?
Thanks
Posts
I don't believe this is a safe assumption. The definition for TripPoint:
Does not list any selector for them, and I don't believe arbitrary swift struct properties are available via ValueForKey.
Unless you have an objective-c sample showing that this works, I don't think this works that way. The NSUnknownKeyException you see is not coming from us but the native object, so I believe you would get the same behavior from an objective-c app.
Hi Chris, thank you for your answer.
As you suggested, I implemented the native iOS SDK into a native Swift application using Pod dependency tool.
I jumped to the definition of this specific class to get this :
`@objc public class TripPoint : NSObject {
}`
And with that I can access my TripPoint properties into my AppDelegate callback :
func tripPoint(tripPoint: TripPoint) { let speed = tripPoint.speed }
It feels like I have a shortened class definition into my .framework header (the one that is used by objective sharpie to generate the C# wrapper), but the whole definition is located into the compiled swift library files located into .swiftmodule folder, and it can be understood/ compiled from a native application.
Beside, the SDK is working well, all the methods are called without any error, I just miss this final piece.
Thanks
I tried to update the ApiDefinitions.cs like this :
[BaseType(typeof(NSObject), Name = "_TtC20DriveKitTripAnalysis9TripPoint")]
[DisableDefaultCtor]
interface TripPoint
{
// @property (readonly) double speed;
//[BindAs(typeof(NSNumber))]
[Export("speed")]
NSNumber Speed { [Bind("speed")]get; }
}
But I still got
I believe you may need to use the @objc attribute to expose those properties to the objective c runtime.
Hi Chris,
just to let you know, I resolved my issue by creating my own native iOS swift framework, which is serving as a proxy to expose everything I need from the original framework (the one I don't access the source code).
Just as you stated, @objc annotation is used to expose methods/properties/classes to the objectiveC runtime, and it indicates to objective sharpie to generate the corresponding c# instructions.
Thank you for your assistance.