React Native iOS native module pass parameters - ios

I am writing an NPM library that contains iOS & Android native modules. Important is that I need to pass parameters to the native module before startup. This works great for Android:
package ...
import com.facebook.react.bridge.*
class MyNativeModule(reactContext: ReactApplicationContext, parameter: String) {
override fun getName(): String {
return "MyModule"
}
#ReactMethod
fun retrieveParameter(promise: Promise) {
promise.resolve(parameter)
}
}
When turning off autolinking a library user can just create their own RN package and use the following to set the parameter:
class MyAppRNPackage(private val voizeCore: VoizeCore = VoizeCore.getInstance()) : ReactPackage {
override fun createNativeModules(reactApplicationContext: ReactApplicationContext): List<NativeModule> {
return arrayListOf<NativeModule>(
MyNativeModule(reactApplicationContext, "this is the parameter"),
)
}
override fun createViewManagers(reactApplicationContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
In iOS the native module would look something like this:
// MyNativeModule.m
#import "MyNativeModule.h"
#implementation MyNativeModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(retrieveParameter:(RCTPromiseResolveBlock)resolve rejecter: (RCTPromiseRejectBlock)reject)
{
resolve(???)
}
#end
But how is it possible to set a parameter for the iOS module? The problem is that in iOS, native modules can not be registered manually. Furthermore, only classes are registered not class instances.
Any idea how you could pass parameters from native code to the iOS native module?

Related

Can't make using iOS protocol work in NativeScript

I am creating a NativeScript plugin that will work with my iOS and Android SDKs. In my iOS code, I have an optional #protocol that contains a few optional methods with callbacks about the state of the SDK. I am now trying to access this protocol in NativeScript, and I tried searching the internet and following the guide here, but unfortunately, I still have issues with it. Here is a part of the #protocol in iOS:
#protocol BLASessionDelegate <NSObject>
#optional
- (void)sessionInitialized;
...
Here is the code I put in the "index.d.ts" in my plugin:
export interface SessionDelegate {
sessionInitialized?();
...
}
Here is the part in the "bla.ios.d.ts" file in my plugin:
declare interface BLASessionDelegate extends NSObjectProtocol {
sessionInitialized?();
}
#NativeClass()
declare class BLASessionDelegateImpl extends NSObject implements SessionDelegate {
static ObjCProtocols = [BLASessionDelegate];
static new(): BLASessionDelegateImpl {
return <BLASessionDelegateImpl>super.new(); // calls new() on the NSObject
}
sessionDelegate: SessionDelegate;
public sessionInitialized() {
console.log("Adi - inside sessionInitialized");
if(this.sessionDelegate.sessionInitialized !== undefined) {
this.sessionDelegate.sessionInitialized();
}
}
}
Here is the part in the "bla.ios.ts" file in my plugin:
export const setSessionDelegate = function(sessionDelegate: SessionDelegate) {
if(typeof(bla) !== "undefined") {
console.log("Adi - in the setSessionDelegate");
let delegate: BLASessionDelegateImpl = BLASessionDelegateImpl.new();
delegate.sessionDelegate = sessionDelegate;
bla.setSessionDelegate(delegate);
}
}
This is the code I put in the test app in the "app.ts" file:
let delegate: bla.SessionDelegate = {
sessionInitialized: function() {
const sessionLink: string = bla.generateSessionLink();
console.log("Adi - sessionLink = ", sessionLink);
}
}
bla.setSessionDelegate(delegate);
I am still getting the following error with a crash when running the app and I can't figure out why:
***** Fatal JavaScript exception - application has been terminated. *****
NativeScript encountered a fatal error: Uncaught ReferenceError: BLASessionDelegateImpl is not defined
at
setSessionDelegate(file: app/webpack:/myCoolApp/work/native-script-plugin/native-script/src/bla.ios.ts:165:41)
at ./app/app.ts(file: app/webpack:/myCoolApp/app/app.ts:18:0)
at __webpack_require__(file: app/webpack:/myCoolApp/webpack/bootstrap:24:0)
at __webpack_exec__(file:///app/bundle.js:839:39)
at (file:///app/bundle.js:840:318)
at __webpack_require__.X(file: app/webpack:/myCoolApp/webpack/runtime/startup entrypoint:6:0)
at (file:///app/bundle.js:840:47)
at (file:///app/bundle.js:845:3)
at require(:1:137)

How do I add a Global Tag in Axe DevTools (Attest)

I'm using Axe DevTools and I'm trying to figure out how to tag multiple scans with the same build information. Right now I have my tests running like this:
class MyTestCase : XCTestCase {
func myTest() {
Attest.that(view: view)
.isAccessible({ result in })
.andPushResult(withTags: [myBuild])
}
}
How can I add the myBuild tag globally to all tests that I run?
I would build my own class that utilizes the Axe DevTools (Attest) APIs. Then have my test cases interact with my own class instead of interacting with Attest itself!
class AccessibilityTestUtils {
static let buildTag:String = Bundle.main.object(
forInfoDictionaryKey: "CFBundleShortVersionString"
) as! String
init(build: String) {
self.buildTag = build
}
static func runAccessibilityTestOn(aView : View) {
Attest.that(view: aView).isAccessible({ result in })
.andPushResult(withTags: [buildTag])
}
}
Example Usage
class YourTestClass {
func yourTestCase() {
AccessibilityTestUtils.runAccessibilityTestOn(aView)
}
}
Note: This approach also protects you from future changes to the Attest library by making it so that you only have to change one line of code in the event of non backwards compatible changes.

How can I extend an existing package / library in Dart?

How can I extend an existing package / library in Dart?
e.g.
import 'package:eventify/eventify.dart';
extend EventEmitter { // <- object from package
once() {
// my code here
}
}
void main() {
EventEmitter().once(...);
}
It is possible from dart 2.6 (which is currently in dev)
feature specification example
For example:
extension MyEmitter on EventEmitter {
once() {
// code here
}
}
From my understanding, not possible yet, although it has been proposed for a future Dart release.

Create extension method in Dart

Normally When I create a custom class I can create a function that uses that class as a parameter for example:
class Sphere{
double calculateRadius() {return 40.0;}
}
So I can then call Sphere.calculateRadius().
But with pre-existing classes like for example the String one, this can't be done. For Example. I've tried doing something like:
String.createFrom(String s){return "new";}
but it doesn't work (Android Studio doesn't even make me compile.).
Is this possible, and if it is, how could I do it in Dart? And If I created it, how would I access the object I called the method from? (the String in the example)
As of now January 2020, Dart 2.7 officially introduced extension methods.
To extend a class, this can be done:
extension NewExtension on double {
int get myMethod {
return (1/this*10).toInt();
}
}
You probably mean extension methods. That's not yet supported but the Dart team made attempts already to design such a feature and the chances are good it will be added to the language
https://github.com/dart-lang/language/issues/41
Use Extension method
Use the following syntax to create an extension:
extension <extension name> on <type> {
(<member definition>)*
}
Example :
extension MyString on String {
String addHello() {
return 'Hello : $this';
}
}
Usage :
void main() {
var name = 'Kab';
var nameWithHello = name.addHello();
print(nameWithHello);
}
Output : Hello : Kab
Your can learn more here : Dart Extension In Flutter

Create NativeScript Plugin using IOS Static Library issue

I have created .a static library (tested in Xcode for native ios project and Its working fine)
Now I am following this https://github.com/NativeScript/nativescript-plugin-seed to create nativescript plugin using .a static framework.
Plugin structure
module.modulemap file is created by me and it's look like this
module libstaticlibrary {
umbrella header "staticlibrary.h"
export *
}
staticlibrary.h
#import <Foundation/Foundation.h>
#interface staticlibrary : NSObject
+ (NSString *)sayHello;
#end
libstaticlibrary.d.ts also created by me
declare class staticlibrary extends NSObject {
static sayHello():string;
}
Then in helloplugin.common.ts I am trying to access staticlibrary.sayHello() method.
export class Utils {
public static SUCCESS_MSG(): string {
// let msg = `Your plugin is working on ${app.android ? 'Android' : 'iOS'}.`;
let msg = staticlibrary.sayHello();
setTimeout(() => {
dialogs.alert(`${msg} For real. It's really working :)`).then(() => console.log(`Dialog closed.`));
}, 2000);
return msg;
}
I am getting following error.
node_modules/nativescript-helloplugin/helloplugin.common.ts(21,15): error TS2304: Cannot find name 'staticlibrary'.
What is I am doing wrong here?
It's just the TypeScript compiler error, you have to generate typings for your static library (refer docs to know how) or just add this line at top of your file.
declare var staticlibrary: any
I see that you do have a declaration file in your code snippet, if you want to use it you have to include it to your references.d.ts file.

Resources