RCT_EXPORT_METHOD unknown argument type - objective-c

I i try to bind my react code with an existing objective-C API. In my code i have:
#import "RcpRfidApi.h"
#implementation RcpRfidApi
// The React Native bridge needs to know our module
RCT_EXPORT_MODULE(RcpRfidApi);
- (NSDictionary *)constantsToExport {
return #{#"greeting": #"Welcome to the DevDactic\n React Native Tutorial!"};
}
RCT_EXPORT_METHOD(setReaderPower:(bool)on:(RCTResponseSenderBlock)callback) {
callback(#[[NSNull null], [NSNumber numberWithBool:on]]);
}
#end
but i have an error when i try to call my function on react
Unknowm argument type '_Bool' in method .... Extend RCTConvert to support this type.

RCT_EXPORT_METHOD() can only support BOOL or NSNumber for booleans.
https://facebook.github.io/react-native/docs/native-modules-ios

If you have this problem you maybe need to add a library to your project. Go in: Xcode > your project > Build Phases > Link binary with libraries.
In my case the Apple ExternalAccesory.framework was needed.

Related

How to show Airplay panel programmatically on iOS using flutter

The desired output looks like this,
how to show this on click event programmatically using flutter(even with native code if possible), it's really appreciated if anyone could show an example.
If there is no direct approach to this then a platform specific example using MethodChannel is also very welcome. Native code example must be in Objective C.
Additionally I have tried to use flutter_to_airplay but project fails to run and also has other functionalities that are not needed in this context, what is needed is showing Airplay panel only.
(Answer by M123 native code completely not working)
Here is a example how to open the AirPlayPanel in objective c.
Setup flutter
First you have to create a channel. To start communicating to the native code.
All channel names used in a single app must be unique; prefix the
channel name with a unique ‘domain prefix
static const platform = const MethodChannel('stack.M123.dev/airplay');
Then you have to invoke a method on the method channel.
Future<void> _openAirPlay() async {
try {
await platform.invokeMethod('openAirPlay');
} on PlatformException catch (e) {
print('error');
}
}
Native part
Now the flutter part is done.
First you have to add suppport for swift. For this open the ios folder in the flutter root with XCode.
Expand Runner > Runner in the Project navigator.
Open the AppDelegate.m located under Runner > Runner in the Project navigator.
Create a FlutterMethodChannel and add a handler inside the application didFinishLaunchingWithOptions: method. Make sure to use the same channel name as was used on the Flutter client side.
#import <Flutter/Flutter.h>
#import "GeneratedPluginRegistrant.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* airPlayChannel= [FlutterMethodChannel
methodChannelWithName:#"stack.M123.dev/airplay"
binaryMessenger:controller.binaryMessenger];
[airPlayChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// Note: this method is invoked on the UI thread.
if ([#"getBatteryLevel" isEqualToString:call.method]) {
int returnValue = [weakSelf openAirPlay];
result(#(returnValue));
}];
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
Add the method in the AppDelegate class, just before #end
- (int)openAirPlay {
//Open air play
return (int)(100);
}
Discalimer: I am not a IOS developer so the steps are mostly theoretical.
I am following the official guide from Flutter. It can be found in full length here.

RCT bridging with react native and objective C

I have been following this tutorial, which is talking about how to communicated from React Native and objective C. I followed the tutorial, and got a good result. The problem started when I wanted to add a new function called sendData. This would be called in JS and it would pass a string, and in objective C, it would receive the string.
But, the bridging wasn't working.
Here is my code:
RCT_REMAP_METHOD(sendData : (NSString*)str,
sendData_resolver:(RCTPromiseResolveBlock)resolve
sendData_rejecter:(RCTPromiseRejectBlock)reject)
{
BOOL response = [_cppApi sendData];
resolve(response);
}
This code gives the error No visible #interface for 'CCCppCom' declares the selector 'sendData' in Xcode. (CCCppCom is a header file)
another function I have, which is getData seems to work fine.
RCT_REMAP_METHOD(getData,
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSString *response = [_cppApi getData];
resolve(response);
}
I'm not entirely sure what is going on here. I checked CCCppCom, and sendData is indeed there.
Can someone help me? Thanks in advance.
I solved the problem by using RCT_EXPORT_METHOD instead of RCT_REMAP_METHOD.

Import Objective-C vendored framework from parent pod using Swift (for a mixed project)

I have a podspec setup as follows:
Pod::Spec.new do |spec|
spec.name = "TMGAdvertising"
spec.default_subspecs = ["Core"]
*** [extra stuff removed] ***
spec.subspec 'Core' do |tmgadvertising|
*** [extra stuff removed] ***
end
spec.subspec 'Inneractive' do |inneractive|
inneractive.dependency "TMGAdvertising/Core"
inneractive.private_header_files = "TMGAdvertising/AdNetworkSupport/Inneractive/SDK/*.h", "TMGAdvertising/AdNetworkSupport/Inneractive/Adapters/*.h"
inneractive.public_header_files = "TMGAdvertising/AdNetworkSupport/Inneractive/InneractiveWrapper.h"
inneractive.source_files = ["TMGAdvertising/AdNetworkSupport/Inneractive/Adapters/*.{h,m,swift}", "TMGAdvertising/AdNetworkSupport/Inneractive/SDK/*.{h,m,swift}", "TMGAdvertising/AdNetworkSupport/Inneractive/InneractiveWrapper.{h,m,swift}"]
inneractive.vendored_frameworks = "TMGAdvertising/AdNetworkSupport/Inneractive/SDK/*.framework"
inneractive.pod_target_xcconfig = { 'OTHER_LDFLAGS' => ['-ObjC'] }
end
end
I have no problem writing wrapper classes for the Inneractive framework in Obj-C (housed within TMGAdvertising). Here's one of my example Obj-C wrappers:
#import "InneractiveWrapper.h"
#import IASDKCore;
#implementation InneractiveWrapper
+ (void)initializeSDK:(NSString *)appId {
[[IASDKCore sharedInstance] initWithAppID:appId];
}
#end
The problem is that I don't want to be writing my wrappers in Objective-C -- I'd prefer to write them in Swift.
Normally I could use a bridging header to accomplish this (that's how it was setup before when integrated directly into the app) but since this is a subspec my understanding is that's not possible.
My question is: is there any way I can directly import this vendored Inneractive framework in a Swift file located in the TMGAdvertising pod?
As far as I know you should be able to import the file in your Bridging Header.
#import IASDKCore;

Swift switch not working with C++ based enum

I'm trying to learn Swift by converting an existing Objective-C app I wrote (a streaming audio player). However, the libraries I'm using don't have Swift equivalents, so I've created a bridging header and am referencing them successfully.
Now, I'm trying to do a switch on an enum from one of these libraries, but Swift is just complaining.
To make things even more confusing (for me, probably not for any of you), a series of if blocks works fine.
Here is the enum from the Objective-C library:
typedef enum {
kFsAudioStreamRetrievingURL,
kFsAudioStreamStopped,
kFsAudioStreamBuffering,
kFsAudioStreamPlaying,
kFsAudioStreamPaused,
kFsAudioStreamSeeking,
kFSAudioStreamEndOfFile,
kFsAudioStreamFailed,
kFsAudioStreamRetryingStarted,
kFsAudioStreamRetryingSucceeded,
kFsAudioStreamRetryingFailed,
kFsAudioStreamPlaybackCompleted,
kFsAudioStreamUnknownState
} FSAudioStreamState;
This works:
if (state == kFsAudioStreamRetrievingURL) {
}
if (state == kFsAudioStreamStopped) {
}
if (state == kFsAudioStreamBuffering) {
}
But this doesn't work:
switch state {
case kFsAudioStreamRetrievingURL:
case kFsAudioStreamStopped:
case kFsAudioStreamBuffering:
break;
}
The second one gives me the following error:
Binary operator '~=' cannot be applied to two 'FSAudioStreamState' operands
I would appreciate any assistance in helping me learn more Swift!
Try this:
switch state {
case .RetrievingURL:
case .Stopped:
case .Buffering:
...
}
---- EDITED!!! ----
I'm wrong, this is C++ enum. So try this:
switch state.value {
case kFsAudioStreamRetrievingURL.value:
case kFsAudioStreamStopped.value:
case kFsAudioStreamBuffering.value:
...
}
In obj-c
Enum definition should be
typedef NS_ENUM(NSInteger, FSAudioStreamState){
FSAudioStreamStateStopped,
...
}
So when they are imported into Swift
enum FSAudioStreamState{
case Stopped
...
}
I think it's C++ enum (Not Objective-C enum), so swift will not regard it as enum and it would be better to use if - else.

How to integrate Chartboost IOS SDK with Swift

I am trying to integrate the Chartboost IOS SDK with Swift. I have followed all the instructions on the Chartboost IOS Integration page https://answers.chartboost.com/hc/en-us/articles/201220095-iOS-Integration and have created a bridging header to use the framework in my swift project.
BridgingHeader.h
#import <Chartboost/Chartboost.h>
#import <Chartboost/CBNewsfeed.h>
#import <CommonCrypto/CommonDigest.h>
#import <AdSupport/AdSupport.h>
My BridgingHeader.h file is loacated in my project root directory http://i.imgur.com/DcTcixo.png and I have followed the necessary steps to add the BridgingHeader.h to my Build Settings http://i.imgur.com/jvtzs7a.png but when I run the project I get 52 errors like -> http://i.imgur.com/WCvyooz.png. Why am I getting these errors and how do I get rid of them?
It looks like the headers require UIKit and Foundation. Add this line at the top of your bridging header.
#import <UIKit/UIKit.h>
Also, have you made sure your bridging header is in the project's root in the file system? The hierarchy of Xcode's Project Navigator isn't necessarily the same as the file system.
It's looking for the header in /Users/andrew/Documents/dev/ios/Protect Paigridge/ Open finder and make sure that the header is in that directory. Xcode may have created it a level deeper where the rest of your code files are. If that's the case, you can edit entry in Build Settings or move the file.
Adding onto the top answer said above try adding both
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <Chartboost/Chartboost.h>
to your BridgingHeader.h File
and make sure they are both above the
#import <Chartboost/Chartboost.h>
as shown above
Swift Chartboost Code, Add it in AppDelegate Class :
func applicationDidBecomeActive(application: UIApplication)
{
let kChartboostAppID = "5472ef8f04b01601a1a5814c";
let kChartboostAppSignature = "5b6222426e68cda48669a1d4d8246d4c3d20db9c";
Chartboost.startWithAppId(kChartboostAppID, appSignature: kChartboostAppSignature, delegate: self);
Chartboost.cacheMoreApps(CBLocationHomeScreen)
}
class func showChartboostAds()
{
Chartboost.showInterstitial(CBLocationHomeScreen);
}
func didFailToLoadInterstitial(location :String!, withError error: CBLoadError)
{
}
func didDismissInterstitial(location :String! )
{
if(location == CBLocationHomeScreen)
{
Chartboost.cacheInterstitial(CBLocationMainMenu)
}
else if(location == CBLocationMainMenu)
{
Chartboost.cacheInterstitial(CBLocationGameOver)
}
else if(location == CBLocationGameOver)
{
Chartboost.cacheInterstitial(CBLocationLevelComplete)
}
else if(location == CBLocationLevelComplete)
{
Chartboost.cacheInterstitial(CBLocationHomeScreen)
}
}
Calling Syntax:
AppDelegate.showChartboostAds()
This issue is how to import.
You can make objC code and bridge.h, to shows in your code
[Chartboost showInterstitial:CBLocationHomeScreen];
For swift
Chartboost.showInterstitial(CBLocationHomeScreen)
i wish that help you