NativeScript / ios-jsc

NativeScript for iOS using JavaScriptCore
http://docs.nativescript.org/runtimes/ios
Apache License 2.0
298 stars 59 forks source link

iOS - To extend NSProtocol and override methods in Native-script Plugin which is created in iOS Native Framework #1264

Closed iOSTeam-git closed 4 years ago

iOSTeam-git commented 4 years ago

What we are expecting?

In one of our Native script application, We made one framework using Native iOS Code and wants to send some data from Native iOS Framework to Native script Plugin.

Now in Native script plugin, we wants to extend Native iOS NSProtocol so we can override methods of our custom iOS NSProtocol.

We search for the use of Protocol delegate in Native script but there is only syntax available which can create NSProtocol and implements it in Native script only and our requirement is to create NSProtocol in iOS Framework and implements it’s methods in Native script.

Please suggest us a proper way or syntax to implement it.

Thanks in advance!

mbektchiev commented 4 years ago

Hello,

You can take a look at these two sections for examples on how to implement protocols from JS and TS: https://docs.nativescript.org/core-concepts/ios-runtime/how-to/ObjC-Subclassing#calling-base-methods-Protocol and https://docs.nativescript.org/core-concepts/ios-runtime/how-to/ObjC-Subclassing#typescript-support

I hope this helps! :)

iOSTeam-git commented 4 years ago

Hello @mbektchiev,

Thanks for the quick reply but i already go through with this links and it wasn't work in our case. We wants to extend custom protocol which is made in Native iOS .framework.

can you please help me by providing an example with custom protocol?

mbektchiev commented 4 years ago

The syntax is the same. It doesn't matter whether the protocol is custom or system. You can see the iOS runtime's test cases here: Protocol implementation and Protocol definition

iOSTeam-git commented 4 years ago

Hello @mbektchiev ,

I am facing an issue like Delegate name can not be found in when extending protocol.

public MyObject = (NSObject as any).extend({
    GetBytes: function(arr: any) {
        let self = this.super.GetBytes();
        if (self) {
            // The base class initialized successfully
            console.log("Initialized");
        }
        return self;
    }
  },
    {
      name: "NativeBluetoothCode",
      protocols: [BLECommunicationDelegate]
    }
);
![Screenshot 2020-04-02 at 9 45 01 PM](https://user-images.githubusercontent.com/59596311/78272535-4337df00-752b-11ea-91d4-b33aeefbb981.png)

is it correct way to do it or not?
mbektchiev commented 4 years ago

You seem to have not generated typings (.d.ts files) for your plugin. Follow these instructions to do it: https://docs.nativescript.org/plugins/Use-Native-iOS-Libraries#generating-typescript-typings

In the meantime you can nevertheless access the protocol from TS, you just have to make the compiler happy by replacing BLECommunicationDelegate with global["BLECommunicationDelegate"] or (<any>global).BLECommunicationDelegate

iOSTeam-git commented 4 years ago

Hello @mbektchiev ,

I tried as per your suggestions, but still i am getting below error:

JS ERROR Error: The protocols property must be an array

can you please guide me how i can solve this?

for your knowledge only, currently method does not contains any params still i am getting this error.

My code is

public MyObject = (NSObject as any).extend({
    GetBytes: function() {
        let self = this.super.GetBytes();
        if (self) {
            // The base class initialized successfully
            console.log("Initialized");
        }
        return self;
    }
  },
    {
      name: "NativeBluetoothCode1",
      protocols: global["BLECommunicationDelegate"]
    }
);
mbektchiev commented 4 years ago

As the error states you'll have to make the protocols property an array: protocols: [global["BLECommunicationDelegate"]]

iOSTeam-git commented 4 years ago

I tried the following code but it's now throwing an exception that is the "unrecognized selector sent to instance".

declare var iOSBluetoothProtocol: any

public NativeBluetoothCode1 = (NSObject as any).extend({
     TestNotifDelegate: function () {
          console.log("TestNotifDelegate called in Plugin");
        }
    }, {
name: "NativeBluetoothCode1",
        protocols: [iOSBluetoothProtocol]
    });

even I am not able to use NSObject and this is an error we received, Cannot find the name 'NSObject'. Did you mean 'Object'?

Here, can you help me to fix an issue?

mbektchiev commented 4 years ago

I assume that this error is coming from the TypeScript compiler. One possible reason could be that you haven't included the NativeScript's typings declarations. Can you install as an NPM dev dependency this module: https://www.npmjs.com/package/tns-platform-declarations and follow the instructions in the README, namely:

Create reference.d.ts and add the following content:

/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />