xmlking
xmlking

Reputation: 636

How to implement NativeScript Class in TypeScript with self delegate?

I am creating a NativeScript plugin that wrap a Swift CocoaPod lib.

In my NativeScript plugin, I am using a separate class to add required delegate to main class.

Will it be possible to implement delegate methods in main class and avoid the delegate class completely?

i.e.,

export class MicrosoftBandService  extends NSObject implements ConnectionDelegate {

  static new(): MicrosoftBandService {
    return <MicrosoftBandService>super.new()
  }

  constructor() {
    let _self= this;
    this.mbk = MicrosoftBand.alloc().init();
    this.mbk.connectDelegate = _self
  }

  onConnecte() {
    //

  onDisconnecte() {
    //
  }

  onErrorWithError(error) {
    //
  }

}

even better, I like to do like this

export class MicrosoftBandService  extends MicrosoftBand implements ConnectionDelegate {

  static new(): MicrosoftBandService {
    return <MicrosoftBandService>super.new()
  }

  constructor() {
    let _self= this;
    this.connectDelegate = _self
  }

  onConnecte() {
    //
  }

    onDisconnecte() {
      //
    }

    onErrorWithError(error) {
      //
    }

  }

I don't know proper syntax to implement constructor with self delegate in TypeScript for NativeScript

My current code works, but I am looking for help to simplify and reduce code by eliminating separate delegate class.

Upvotes: 2

Views: 1470

Answers (1)

HHristov
HHristov

Reputation: 141

When TypeScript is converted to Javascript interfaces are lost. So you need to use ObjCProtocols static field and declare which protocols are implemented by this class like:

export class MicrosoftBandService extends NSObject implements ConnectionDelegate {    
   public static ObjCProtocols = [ ConnectionDelegate ];
   ...
}

Second TypeScript constructors are not called on native objects (you probably have warning in the console about that). So you should do init method and set all fields there:

public static initWithOwner(band: MicrosoftBand): MicrosoftBandService {
    let delegate = <MicrosoftBandService>MicrosoftBandService.new();
    delegate._band = band; 
    band._delegate = delegate;
    band.connectDelegate = delegate.
}

There are few things to note here:

  1. Avoid new() overload. Could cause issues on some native object.

  2. Pass the band instance so that you could call it in the delegate methods (if you need it)

  3. Keep reference of the delegate locally on the band - most delegates are implemented as weak references. If you don't keep a reference to it no one will and it will be collected by the GC at some point.

More information about protocol implementation can be found here: http://docs.nativescript.org/runtimes/ios/how-to/ObjC-Subclassing

edit: It should be possible to do:

export class MicrosoftBandService extends MicrosoftBand implements ConnectionDelegate

as long as you add the static ObjCProtocols field. Then you won't need to keep a reference to the delegate because it will be the same instance. Still TypeScript constructor won't be called so you need to call the correct init native method.

Upvotes: 3

Related Questions