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.
Related
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?
I'm trying to implement a framework using swift but the header file is not been updated with the class or the functions:
Here is my code in my swift file:
public class one{
public func two(name:String) -> String {
print(name)
}
}
#objc public class SwiftInObjc:NSObject {
public func bla(){
}
}
After I build this is what I see in my header file:
#import <UIKit/UIKit.h>
FOUNDATION_EXPORT const unsigned char sampleFramework[];
framework using statements like #import <sampleFramework/PublicHeader.h>
How can generate update to the header file?
And then it could be linked and used from Objective-C with the
#import MyStaticLib;
syntax.
If so, how, exactly, do you do this.
You can create a static library with .modulemap file to use #import syntax
[Create Objective-C static library]
If you can edit the library Xcode project you can create a *.modulemap file and set it to the MODULEMAP_FILE Build Setting.
Sample map file from CocoaLumberjack:
framework module CocoaLumberjack {
umbrella header "CocoaLumberjack.h"
export *
module * { export * }
}
module CocoaLumberjack.DDContextFilterLogFormatter {
header "DDContextFilterLogFormatter.h"
export *
}
module CocoaLumberjack.DDDispatchQueueLogFormatter {
header "DDDispatchQueueLogFormatter.h"
export *
}
module CocoaLumberjack.DDMultiFormatter {
header "DDMultiFormatter.h"
export *
}
module CocoaLumberjack.DDASLLogCapture {
header "DDASLLogCapture.h"
export *
}
module CocoaLumberjack.DDAbstractDatabaseLogger {
header "DDAbstractDatabaseLogger.h"
export *
}
You can by creating a framework from this static library, you can follow all the instructions here
Once finished, you can import your static library like that:
#import MyStaticLib;
The iOS-Universal-Framework's page : https://github.com/kstenerud/iOS-Universal-Framework
It is an XCode project template to build universal (arm6, arm7, and simulator) frameworks for iOS.
I have build my framework by use this template,but i got a problem,i have pack all my class in the template,including a macro definition #define kCOMPANYID 2 in a .h file Macro.h,but the problem is ... the kCOMPANYID must can be modified by the one who use my framework,so the kCOMPANYID must define out of the framework,but the problem is , some classes in my framework must use the kCOMPANYIDïĵso it is a conflict,i don't know how to do,please help me,thanks.
you should avoid #define as much as possible
one way is to make a setter/getter function to for it
e.g.
// public header file
void SetCompanyId(int value);
// int GetCompanyId(); // it can be in public header or private header
// some .m or .c or .cpp file
static int companyId;
int GetCompanyId() { return copanyId; }
void SetCompanyId(int value) { companyId = value; }
or if the user mush provide a id, just make it a global variable. you can add const to it so the value can't change
// header file in your framework
extern const int kCompanyId;
// some implementation file in user code
const int kCompanyId = 2;
then user must provided a company id otherwise it will have linker error
I am writing a library in Dart and I have static files under the library folder. I want to be able to read those files, but I'm not sure how to retrieve the path to it... there is not __FILE__ or $0 like in some other languages.
Update: It seems that I was not clear enough. Let this help you understand me:
test.dart
import 'foo.dart';
void main() {
print(Foo.getMyPath());
}
foo.dart
library asd;
class Foo {
static Path getMyPath() => new Path('resources/');
}
It gives me the wrong folder location. It gives me the path to test.dart + resources/, but I want the path to foo.dart + resources/.
As mentioned, you can use mirrors. Here's an example using what you wanted to achieve:
test.dart
import 'foo.dart';
void main() {
print(Foo.getMyPath());
}
foo.dart
library asd;
import 'dart:mirrors';
class Foo {
static Path getMyPath() => new Path('${currentMirrorSystem().libraries['asd'].url}/resources/');
}
It should output something like:
/Users/Kai/test/lib/resources/
There will probably be a better way to do this in a future release. I will update the answer when this is the case.
Update: You could also define a private method in the library:
/**
* Returns the path to the root of this library.
*/
_getRootPath() {
var pathString = new Path(currentMirrorSystem().libraries['LIBNAME'].url).directoryPath.toString().replaceFirst('file:///', '');
return pathString;
}
The dart mirrors API (still experimental, and not available on all platforms such as dart2js yet) exposes a url getter on the LibraryMirror. This should give you what you want.
I'm not aware of any other way to get this information on a library.
#import('dart:mirrors');
#import('package:mylib/mylib.dart');
main(){
final urlOfLib = currentMirrorSystem().libraries['myLibraryName'].url;
}
Generally the usual method of accessing resources which are located at a static position with your library is by use using a relative path.
#import('dart:io');
...
var filePath = new Path('resources/cool.txt');
var file = new File.fromPath(filePath);
// And if you really wanted, you can then get the full path
// Note: below is for example only. It is missing various
// integrity checks like error handling.
file.fullPath.then((path_str) {
print(path_str);
});
See addition API information on Path and on File
As an aside.. If you absolutely wanted to get the same type of output as __FILE__ you can do something like the following:
#import('dart:io');
...
var opts = new Options();
var path = new Path(opts.script);
var file = new File.fromPath(path);
file.fullPath().then((path_str) {
print(path_str);
});