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?
Related
I have two files, one that's called CodeInjection.m with the content like
#import <Foundation/Foundation.h>
#import "Someheaderfile.h"
#interface CodeInjection: NSObject
#end
#implementation CodeInjection
static void __attribute__((constructor)) initialize(void){
NSLog(#"==== Code Injection in Action====");
[[CodeInjectionSwift shared] performTask];
}
#end
Then I have a CodeInjectionSwift.swift file with content
import Foundation
import NetworkInterceptor
#objc class CodeInjectionSwift: NSObject {
#objc public static let shared = CodeInjectionSwift()
override private init(){}
#objc func performTask(){
let requestSniffers: [RequestSniffer] = [
RequestSniffer(requestEvaluator: AnyHttpRequestEvaluator(), handlers: [
SniffableRequestHandlerRegistrable.console(logginMode: .nslog).requestHandler()
])
]
let requestRedirectors: [RequestRedirector] = [
RequestRedirector(requestEvaluator: DomainHttpRequestEvaluator(domain: "www.antennahouse.com"), redirectableRequestHandler: AlternateUrlRequestRedirector(url: URL(string: "https://www.rhodeshouse.ox.ac.uk/media/1002/sample-pdf-file.pdf")!))
]
let networkConfig = NetworkInterceptorConfig(requestSniffers: requestSniffers,
requestRedirectors: requestRedirectors)
NetworkInterceptor.shared.setup(config: networkConfig)
NetworkInterceptor.shared.startRecording()
}
}
When trying to use "CodeInjectionSwift", I get errors like this
Make #objc func performTask() public:
#objc public func performTask()
My original answer is wrong. I've left it below for context.
In fact the whole problem is that you need to import a special header into your Objective-C class.
#import "TestImportSwift-Swift.h"
where TestImportSwift is replaced by the name of your project.
Old wrong answer
shared is not a class member, it is a static member. Unfortunately, Swift doesn't support class variables, only functions, so you could try
#objc class CodeInjectionSwift: NSObject {
static let _shared = CodeInjectionSwift()
#objc public class func shared() -> CodeInjectionSwift { return _shared }
// Rest of the class
Note that I haven't tried this in a real project.
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.
I am using FXForm Library and want to get data from my Swift file in Objective C file function.
Demo Project Link
Swift Code Implimnetation:
let fontName = "HelveticaNeue"
let fontSizeLarge:CGFloat = 14.0
var hiddenElementFromFormIndex = [Int]()
//fx form variables
#objc class FXFormVariables : NSObject {
public override init() {}
class func FXFontName() -> String { return fontName }
class func FXFontSize() -> CGFloat { return fontSizeLarge }
class func FXHiddenCell() -> NSArray { return hiddenElementFromFormIndex as NSArray }
}
In Objective C file, I am getting error when we write below like:
NSArray *hideArray = [FXFormVariables FXHiddenCell];
I created the bridge header file correctly and Target Membership is checked in the Objective C file.
Error I am getting:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$__TtCC13Social_Engine11AppDelegate15FXFormVariables", referenced from:
objc-class-ref in FXForms.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Architectures and Valid Architectures are:
armv7 and armv64
To use Swift class inside Objective-C file you need to import Xcode-generated header file in your Objective-C file.
#import "ProductModuleName-Swift.h"
I created a Test project with the same name.
Swift File:
//
// FXFormVariables.swift
// Test
//
// Created by Puneet Sharma2 on 12/07/17.
// Copyright © 2017 com.puneet.sh2525. All rights reserved.
//
import Foundation
import UIKit
let fontName = "HelveticaNeue"
let fontSizeLarge:CGFloat = 14.0
var hiddenElementFromFormIndex = [Int]()
//fx form variables
#objc class FXFormVariables : NSObject {
public override init() {}
class func FXFontName() -> String { return fontName }
class func FXFontSize() -> CGFloat { return fontSizeLarge }
class func FXHiddenCell() -> NSArray { return hiddenElementFromFormIndex as NSArray }
}
Objective-C File
#import "ABC.h"
#import "Test-Swift.h"
#implementation ABC
- (void)drawRect:(CGRect)rect {
NSArray *hideArray = [FXFormVariables FXHiddenCell];
}
You can read more about it here.
Literally I spent hours trying to figure out why this was happening with one of my swift files that i was importing into my Objc codebase, and the real reason was due to the use of a nested class.
Such as:
#objc public class MyClass {
#objc public class SecondClass {}
}
And if I tried using SecondClass in my objective-c code, I would the Apple Mach O-Link errors of death. So the solution was to de-nest the class you want to use.
#objc public class MyClass {}
#objc public class SecondClass {}
I often use this statement for extending class without needs of writing a whole separate file. Supposing ClassFromFramework is a class being part of a framework included in library.
public ClassFromFramework {
public String myMethod() {
// operations
}
//lot of other methods....
}
Then in my class I could do the following:
import com.framework.ClassFromFramework;
public MyClass {
public void method() {
ClassFromFramework m = new ClassFromFramework() {
#Override
public String myMethod() {
// do operations...
}
}
m.myMethod();
}
}
I wonder if I can achieve the same with Objective-c without declaring a new combination .h .m files and import in my using class.
You can make a new subclass, and override methods, but all new classes must be in their own .h & .m files. That's how Obj-C operates. In this case, it would make sense to have the additional files.
You can also call the parent method with the word super. This is done all the time when subclassing a ViewController, such as in viewDidLoad.
I'm trying to bind a Xcode library and am pulling my hair out on how to do that. The App crashes terribly when I try to access any event or method.
Below is the description I made
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.ObjCRuntime;
using MonoTouch.UIKit;
namespace BardecodeBinding
{
[BaseType (typeof(NSObject),
Delegates= new string [] {"WeakDelegate"},
Events = new Type [] { typeof(BardecodeDelegate) })]
interface Bardecode
{
[Export ("delegate", ArgumentSemantic.Assign)]
[NullAllowed]
NSObject WeakDelegate { get; set; }
[Wrap ("WeakDelegate")]
[NullAllowed]
BardecodeDelegate Delegate { get; set; }
[Export("ScanBarcodeFromViewFinder")]
void ScanBarcodeFromViewFinder();
}
[BaseType (typeof(NSObject))]
interface BardecodeDelegate
{
[Export ("didfinish:sender:notification:"), EventArgs("BardecodeDidFinish")]
void DidFinish (Bardecode sender, NSNotification notification);
}
}
I'm trying to bind the Bardecode library from Softek (http://www.bardecode.com/). Here's (part of) their header file
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#include "barcode.h"
#if TARGET_IPHONE_SIMULATOR
#interface Bardecode : NSObject <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
#else
#interface Bardecode : NSObject <UINavigationControllerDelegate, UIImagePickerControllerDelegate, AVCaptureVideoDataOutputSampleBufferDelegate>
#endif
{
...
- (void) ScanBarcodeFromViewFinder;
...
}
#interface NSObject(NSWindowNotifications)
- (void)BardecodeDidFinish:(NSNotification*)notification;
#end
And here's how I try to use the generated binding
Bardecode bardecode = new Bardecode();
bardecode.DidFinish += BardecodeDidFinish;
bardecode.ScanBarcodeFromViewFinder();
And the callback routine:
private void BardecodeDidFinish(object sender, EventArgs args)
{
}
Although the documentation states that a class with name BardecodeDidFinishEventArgs should be generated, it is not.
Here's what MonoDevelop generated after adding the library file.
using System;
using MonoTouch.ObjCRuntime;
[assembly: LinkWith ("libbardecode.a", LinkTarget.ArmV6 | LinkTarget.ArmV7 | LinkTarget.Simulator, ForceLoad = true)]
Regards
Paul
I'm trying to bind a Xcode library and am pulling my hair out on how to do that. The App crashes terribly when I try to access any event or method.
Do you have a crash report for these crashes? Do you know exactly which line of managed code causes the crash?
Although the documentation states that a class with name BardecodeDidFinishEventArgs should be generated, it is not.
Bindings projects don't generate source code you'll see, the generated source code is automatically deleted after compiling them. You can run Reflector on the bindings library to see exactly what is generated.