Not able to import "project-name-Swift.h" file xcode - objective-c

I have 2 files.
"CodeInjection.m"
#import <Foundation/Foundation.h>
#import "BiplovCodeInjection-Swift.h"
#interface CodeInjection: NSObject
#end
#implementation CodeInjection
static void __attribute__((constructor)) initialize(void){
NSLog(#"==== Code Injection in Action==== with sniffer");
[[CodeInjectionSwift shared] performTask];
}
#end
My second file is.
"BiplovCodeInjectionSwift.swift"
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()
}
}
It fails on the line "#import "BiplovCodeInjection-Swift.h"
I built a new project > framework.
Here's my file strucuture
Why is it that I can't import the header file?

Related

Custom React Native Plugin is null (iOS)

I'm creating a react native plugin. Android works like charm, but iOS makes some troubles. The plugin is always null.
Files:
myPlugin-bridging-header.h
#import <React/RCTBridgeModule.h>
myPlugin.m
#import <React/RCTBridgeModule.h>
#interface RCT_EXTERN_MODULE(MyPlugin, NSObject)
RCT_EXTERN_METHOD(multiply:(float)a withB:(float)b
withResolver:(RCTPromiseResolveBlock)resolve
withRejecter:(RCTPromiseRejectBlock)reject)
#end
myPlugin.swift
import Foundation
#objc(MyPlugin)
class MyPlugin: NSObject {
#objc(multiply:withB:withResolver:withRejecter:)
func multiply(a: Float, b: Float, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
resolve(a*b)
}
}
index.js
import { NativeModules } from 'react-native';
const { MyPlugin } = NativeModules;
export default MyPlugin;
Usage
import MyPlugin from 'my-plugin';
[...]
console.log(MyPlugin); // is null
MyPlugin.multiply(2, 8).then((value) => {
console.log('value: ', value);
});
I don't know what is missing. The plugin is always null. Is #interface RCT_EXTERN_MODULE(MyPlugin, NSObject) not enough to make the module available?
Add missing function moduleName in your swift file
override class func moduleName() -> String! {
return "MyPlugin"
}

How to call swift native function from react native?

I have a swift class, which i am exposing to react-native, inside that i have a function that is also exposed to react-native. Now when react native calls that function it does a lot of this internally, but after some point of time it returns an object.
Now it will call a specific function that will get the object. I cannot change the parameter to that function. But i have another function, to which i want to return to react native. How can i do it.
func AckCallback(response:APIResponse) -> Void
{
print(response)
}
for this function I cannot change the paremeter, becaused it had been used a lot of places, But I want to return that response from this function to react-native. If anybody know this issue, please let me know.
#objc func sendEvent(_ response: APIResponse, callback: (NSObject) -> ())
-> Void {
callback( [[
"responseCode" : "Working",
]] as NSObject)
}
I just want to know how to use this sendEvent inside the AckCallback, or is there any other way to send that **
response: APIResponse
**
to react-native.
For the first create Swift class (e.g YourModule.swift)
//
// YourModule.swift
//
#objc(YourModule)
class YourModule: NSObject {
#objc func callNativeEvent(callback:RCTResponseSenderBlock)
-> Void {
// Here you can do your work and pass an object to the callback function.
// You can save assign a `callback` to the class property (e.g self.eventCallback = callback)
// and invoke that self.eventCallback after the asynchronous code ol somewhere else
NSObject *obj = [[NSObject alloc] init]; // your object here
callback([NSNull(), obj]);
// or if you want to return an error
// callback(["Error calling NativeEvent", NSNull()]);
// I'm not sure that RCTResponseSenderBlock works the same as in previous react-native versions. Maybe now you can pass an Object instead of an Array.
}
}
Create a Bridge file (e.g. YourModuleBridge.m)
//
// YourModuleBridge.m
//
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
#import <React/RCTBridgeModule.h>
#interface RCT_EXTERN_MODULE(YourModule, NSObject)
RCT_EXTERN_METHOD(callNativeEvent:(RCTResponseSenderBlock)callback);
#end
Also, you need Bridging-Header file if it doesn't exist in your project.
//
// YourModule-Bridging-Header.h
//
#ifndef YourModule_Bridging_Header_h
#define YourModule_Bridging_Header_h
#if __has_include("RCTBridgeModule.h")
#import "RCTBridgeModule.h"
#else
#import <React/RCTBridgeModule.h>
#endif
#endif /* YourModule_Bridging_Header_h */
And from JS
import { NativeModules } from 'react-native';
const YourModule = NativeModules.YourModule;
...
YourModule.callNativeEvent((error, response) => {
console.log('Error', error, 'Response', response);
});
In iOS Project Create 2 Files
SwiftComponentManager.swift and SwiftComponentManager.m create these 2 files.
SwiftComponentManager.swift ->
#objc(SwiftComponentManager)
class SwiftComponentManager: NSObject {
#objc func passValueFromReact(_ value : String) {
debugPrint(" Print Here \(value)")
}
}
In SwiftComponentManager.m
#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"
#interface RCT_EXTERN_MODULE(SwiftComponentManager, NSObject)
RCT_EXTERN_METHOD(passValueFromReact:(NSString *)value) //Here exported your swift function for React Native
#end
Here start work in React-Native project
Now How will call this Swift function in React Native.
Import your SwiftComponent in React JS file
const { SwiftComponentManager } = NativeModules
Now call your function with value where you want in JS file
SwiftComponentManager.passValueFromReact("Hello World")

Why do I have to label my second argument for a react native to swift bridged function

Say I have the following Swift class:
#objc(ExampleClass)
class ExampleClass: NSObject {
init() {}
#objc func exampleMethod(_ message: String, _ properties: [String: Any]? = nil) -> Void {}
}
And the following Header:
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#interface RCT_EXTERN_MODULE(ExampleClass, NSObject)
RCT_EXTERN_METHOD(exampleMethod:(NSString *)name (NSDictionary *)properties)
#end
Which I then call with the following React Native code:
import { NativeModules } from 'react-native'
NativeModules.ExampleClass.exampleMethod('example', {'hello': 'world'})
This results in the following error message:
ExceptionsManager.js:73 Exception 'exampleMethod: is not a recognized Objective-C method.' was thrown while invoking trackEvent on target SegmentTracker with params (
"example",
{
hello = world;
}
)
However, if I change the function signature to be labelled like so:
#objc func exampleMethod(_ message: String, withProperties properties: [String: Any]? = nil) -> Void {}
}
And adjust the RCT_EXTERN_METHOD function like so:
RCT_EXTERN_METHOD(exampleMethod:(NSString *)name withProperties:(NSDictionary *)properties)
Why does the second argument have to be labelled? Why doesn't the first one?

Swift 2 Protocol Extensions and Conformance for Objective-C Types

I have a setup like this:
#interface Model: NSManagedObject
...
#end
And a Swift protocol like this:
#objc protocol Syncable {
var uploadURL: String { get }
var uploadParams: [String: AnyObject]? { get }
func updateSyncState() throws
}
extension Syncable where Self: NSManagedObject {
func updateSyncState() throws {
... /* default implementation */ ...
}
}
In a new Swift file, I try to do this:
extension Model: Syncable {
var uploadURL: String {
return "a url"
}
var uploadParams: [String: AnyObject]? {
return [:]
}
}
I keep getting an error, with Xcode saying "type 'Model' does not conform to protocol 'Syncable'". Xcode also keeps suggesting that I put an #objc somewhere in my extension but it can't seem to figure out where it should go.
Is what I'm doing impossible? (It seems to work under simple conditions in a playground - but with my Objective-C class being written in Swift, obviously).
If it is impossible, help in understanding why would be appreciated.
The problem is the attempt to mix Objective-C and Swift features. This pure Swift code compiles just fine (note that I've eliminated NSManagedObject from the story, as it has nothing to do with the issue):
class MyManagedObject {}
class Model: MyManagedObject {}
protocol Syncable {
var uploadURL: String { get }
var uploadParams: [String: AnyObject]? { get }
func updateSyncState()
}
extension Syncable where Self: MyManagedObject {
func updateSyncState() {
}
}
extension Model: Syncable {
var uploadURL: String {
return "a url"
}
var uploadParams: [String: AnyObject]? {
return [:]
}
}
That's because Swift knows what a protocol extension is. But Objective-C doesn't! So as soon as you say #objc protocol you move the protocol into the Objective-C world, and the protocol extension has no effect - and thus Model doesn't conform, as it has no updateSyncState implementation.

swift class in Objective-C: unknown receiver

I wrote a class in a swift-file:
class UtilityMethods {
class func userId() -> Integer {
...
}
class func setUserId(userId : Int) {
...
}
}
I'm importing the -swift.h-header which compiles fine, but I can't use
[UtilityMethods userId];
in my Objective-C code:
Unknown receiver 'UtilityMethods'; did you mean 'UtilMethods'?
UtilMethodsis an Objective-C class I'd like to replace. Am I missing something?
EDIT
With the help of Lance, the class is now recognized, but the getter method isn't, unfortunately, the header files looks like the following:
SWIFT_CLASS("_TtC15...14UtilityMethods")
#interface UtilityMethods : NSObject
+ (void)setUserId:(NSInteger)userId;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
#end
Why is the getter missing?
In order to have a Swift class available to Objective C you have two options:
Option 1: Subclass NSObject (or some other Objective C class)
class UtilityMethods : NSObject {
class func userId() -> Int {
...
}
class func setUserId(userId: Int) {
...
}
}
Option 2: Add the #objc attribute to your class telling the Swift compiler to make an Objective C object that uses dynamic dispatch rather than static dispatch for method calls
#objc class UtilityMethods {
class func userId() -> Int {
...
}
class func setUserId(userId: Int) {
...
}
}
In my case, I was doing #objc correctly, but in changing from my old Objective-C .h file to my new swift file, I had accidentally lost the Target Membership of the new file, so it wasn't being included in the build.