Viewcontroller class method is not calling - ios

hello i want to play through watchKit .i have set all things.but when i am awake parent application from watchKit on button press it awake but from playerController class i have a method to play poem. but this method is not called my code in appdelegate is below.
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString *str=[userInfo objectForKey:#"counterValue"];
//reply(#{#"one":#"string"});
PlayerController *vc=[[PlayerController alloc] init];
if ([vc isKindOfClass:[PlayerController class]]){
if ([str isEqualToString:#"1"]) {
[vc playpoems];
NSString *theee=#"12345";
reply(#{#"one":theee});
}
}
}
in this code i got Log from reply block but only method from class is not calling...this method is properly working in class.

you are creating a new instance of viewcontroller in appdelegate.
please try with this code as i am telling.
in your .m file
#implementation PlayerController
PlayerController *selfvc;
+(PlayerController *)getInstance{
return selfvc;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
selfvc =self;
}
and in your header file
#interface PlayerController : UIViewController
+(PlayerController *)getInstance;
#end
and then in your appdelegate try with this code
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
NSString *str=[userInfo objectForKey:#"counterValue"];
//reply(#{#"one":#"string"});
PlayerController *vc=[PlayerController getInstance];
if ([vc isKindOfClass:[PlayerController class]]){
if ([str isEqualToString:#"1"]) {
[vc playpoems];
NSString *theee=#"12345";
reply(#{#"one":theee});
}
}
}
and then your controller function will be called.

Related

ReactNative iOS sendEventWithName cause "RCTCallableJSModules is not set"

i've the following situation.
2 identical react-native apps (differs only for bundleId, app icon etc) structured like this:
-> project structure
My goal it's to emit an event from native side to the JS layer through the bridge when a push notification has been received or tapped by the user (assuming that the app is in foreground and app has finished launching).
On the first App the following code works as expected when i trigger a push notification to my simulator with the command xcrun simctl push <device-id> <bundleId> <filename>.apns, the second app crash immediatly with the following error:
Thread 1: "Error when sending event: pushDelivered with body: <the string passed as body>. RCTCallableJSModules is not set. This is probably because you've explicitly synthesized the RCTCallableJSModules in CustomEventsEmitter, even though it's inherited from RCTEventEmitter."
-> xcode view
Here is the code implementation of RCTEventEmitter's sendEventWithName that provoke the assertion.
I don't know if it's a problem with my implementation. In 1 of the 2 apps works like a charm, in the other 💥.
Anyone can help me find the problem in the code ? Probably a problem with the bridge?
i've tried many times to reinstall pods, clean project and rebuild. The code works on the project A and not on the project B.. i cannot figure out the reason
AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridgeModule.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, RCTBridgeModule, UNUserNotificationCenterDelegate>
#property (nonatomic, strong) UIWindow *window;
#property (nonatomic, strong) NSDictionary *receivedNotificationUserInfo;
#end
AppDelegate.mm
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTAppSetupUtils.h>
#import <UserNotifications/UserNotifications.h>
#import "CustomEventsEmitter.h"
#implementation AppDelegate
bool hasFinishedLaunching = false;
CustomEventsEmitter *customEventsEmitter = NULL;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
hasFinishedLaunching = true;
customEventsEmitter = [CustomEventsEmitter allocWithZone: nil];
RCTAppSetupPrepareApp(application);
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"MyAppName", initProps);
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
-(void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
// The method will be called on the delegate when the user responded to the notification by opening
// the application, dismissing the notification or choosing a UNNotificationAction. The delegate
// must be set before the application returns from applicationDidFinishLaunching:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
NSLog(#"didReceiveNotificationResponse response: %#", response);
NSDictionary *userInfo = response.notification.request.content.userInfo;
if (userInfo[#"_od"]){
// if no listeners has been registered yet, store the value
// this is the case when the notification was clicked from closed app
if(![customEventsEmitter hasListeners]) {
// handle this case ...
}
// if listeners has been registered, emit an event
// this is the case when the notification was clicked from foreground app
else {
[self emitPushTappedEvent:userInfo[#"_od"]];
}
}
if (completionHandler != nil) {
completionHandler();
}
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo;
NSLog(#"User Info : %#", userInfo);
[self emitPushDeliveredEvent:userInfo[#"_od"]];
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
-(void)emitPushDeliveredEvent:(NSString*)value {
NSLog(#"emitPushDeliveredEvent called");
[customEventsEmitter sendEventWithName:#"pushDelivered" body:value];
}
-(void)emitPushTappedEvent:(NSString*)value {
NSLog(#"emitPushTappedEvent called");
[customEventsEmitter sendEventWithName:#"pushTapped" body:value];
}
#end
And this are the CustomEventsEmitter files:
CustomEventsEmitter.h
#ifndef CustomEventsEmitter_h
#define CustomEventsEmitter_h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#interface CustomEventsEmitter : RCTEventEmitter <RCTBridgeModule>
- (void)sendEventName:(NSString *)eventName body:(id)body;
- (bool)hasListeners;
#end
#endif
CustomEventsEmitter.m
#import "CustomEventsEmitter.h"
#implementation CustomEventsEmitter
{
bool hasListeners;
}
RCT_EXPORT_MODULE(CustomEventsEmitter);
+ (id)allocWithZone:(NSZone *)zone {
static CustomEventsEmitter *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
- (NSArray<NSString *> *)supportedEvents {
return #[#"pushDelivered", #"pushTapped"];
}
// Will be called when this module's first listener is added.
-(void)startObserving {
hasListeners = YES;
// Set up any upstream listeners or background tasks as necessary
}
// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
hasListeners = NO;
// Remove upstream listeners, stop unnecessary background tasks
}
-(bool)hasListeners {
return hasListeners;
}
- (void)sendEventName:(NSString *)eventName body:(id)body {
if (hasListeners) {
NSLog(#"CustomEventsEmitter sendEventName emitting event: %#", eventName);
[self sendEventWithName:eventName body:body];
} else {
NSLog(#"CustomEventsEmitter sendEventName called without listeners: %#", eventName);
}
}
#end
HELP ME UNDERSTAND PLEASEEEE
Oh i've solved it!
It was a mistake of mine.
The AppModule didn't invoke the CustomEventsEmitter's methods correctly..
changing the code like below makes the events be emitted correctly through the RN bridge
-(void)emitPushDeliveredEvent:(NSString*)value {
NSLog(#"emitPushDeliveredEvent called");
[customEventsEmitter sendEventName:#"pushDelivered" body:value];
//[customEventsEmitter sendEventWithName:#"pushDelivered" body:value];
}
-(void)emitPushTappedEvent:(NSString*)value {
NSLog(#"emitPushTappedEvent called");
[customEventsEmitter sendEventName:#"pushTapped" body:value];
//[customEventsEmitter sendEventWithName:#"pushTapped" body:value];
}

Configuring push notifications iOS

I used Pushbots to configure push notifications for my app. After I get the notification, I am able to put it into a UITableview. However the notification only appears after the user restarts the app. Is there a way to immediately add the notification text after the user gets it, or when the user clicks the notification?
In my AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Pushbots sharedInstanceWithAppId:#"--myAppid--"];
[[Pushbots sharedInstance] receivedPush:launchOptions];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// This method will be called everytime you open the app
// Register the deviceToken on Pushbots
[[Pushbots sharedInstance] registerOnPushbots:deviceToken];
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(#"Notification Registration Error %#", [error userInfo]);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Handle notification when the user click it while app is running in background or foreground.
[[Pushbots sharedInstance] receivedPush:userInfo];
//NSLog(#"UserInfo: %#", userInfo);
NSString *msg = [userInfo valueForKey:#"aps"];
NSString *alertMsg = [msg valueForKey:#"alert"];
//NSLog(#"Push Notification:%#",alertMsg);
[[NSUserDefaults standardUserDefaults]setObject:alertMsg forKey:#"ReceivedNotifications"];
NSLog(#"Alert: %#", alertMsg);
}
In my ViewController.m:
#import "ViewController.h"
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *notifTableView;
#end
#implementation ViewController
{
NSMutableArray *notif;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.notifTableView.dataSource = self;
self.notifTableView.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *checkAlert = [[NSString alloc] init];
checkAlert = [defaults stringForKey:#"ReceivedNotifications"];
NSLog(#"Alert Message: %#", checkAlert);
notif = [NSMutableArray arrayWithObjects:checkAlert, nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [notif count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [notif objectAtIndex:indexPath.row];
return cell;
}
In your ViewController viewDidLoad method start listen to a NSNotification as below,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"TestNotification"
object:nil];
Add this receiveNotification to your ViewController as well. Inside this if condition you can reload the TableView.
- (void) receiveNotification:(NSNotification *) notification
{
// [notification name] should always be #"TestNotification"
// unless you use this method for observation of other notifications
// as well.
if ([[notification name] isEqualToString:#"TestNotification"])
NSLog (#"Successfully received the test notification!");
}
Don't forget to remove the notification when you dealloc the ViewController,
[[NSNotificationCenter defaultCenter] removeObserver:self];
Then from your AppDelegate once you receive a notification, post a Notification to TestNotification name
[[NSNotificationCenter defaultCenter]
postNotificationName:#"TestNotification"
object:nil]; //You can set object as nil or send the object you want to get from the ViewController
try to use NSNoticationCenter same as DilumN said in his answer , when you receive the notification then reload the tableview in that method.

Pause Background Music from ViewController to AppDelegate

I have backgroundmusic, declared in my app delegate for all my viewcontrollers.
appdelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate, AVAudioPlayerDelegate>{
AVAudioPlayer *backgroundMusic;
}
appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *backgroundMusicString =[[NSBundle mainBundle]pathForResource:#"backgroundmusic" ofType:#"mp3"];
backgroundMusic = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:backgroundMusicString] error:nil];
backgroundMusic.delegate=self;
backgroundMusic.numberOfLoops=-1;
backgroundMusic.volume=0.2;
[backgroundMusic play];
return YES;
}
works fine. But how can i pause my background music in a viewcontroller?
i have a button to toggle it on off, but [backgroundMusic pause]; doesn't work.
- (IBAction)backgroundMusicOnOff:(id)sender {
}

Block for CallState not invoked iOS 7

I am trying to monitor the callStates.I implemented an own class for this with this init method:
- (id) init
{
self = [super init];
if (!self) return nil;
callCenter = [[CTCallCenter alloc] init];
[callCenter setCallEventHandler: ^(CTCall* call) {
if ([call.callState isEqualToString: CTCallStateConnected]) {
} else if ([call.callState isEqualToString: CTCallStateDialing]) {
} else if ([call.callState isEqualToString: CTCallStateDisconnected]) {
} else if ([call.callState isEqualToString: CTCallStateIncoming]) {
}
NSLog(#"\n\n callEventHandler: %# \n\n", call.callState);
}];
return self;
}
#property(nonatomic, strong) CTCallCenter* callCenter;
I linked the CoreTelephony Framework in my Project...But the Block never gets called...If i put the same Code in my AppDelegate, it works...
Des it only work in AppDelegate?!
UPDATE:
I allocate my Class in my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
VoiceReceiver *v __attribute__((unused)) = [[VoiceReceiver alloc] init];
....
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
VoiceReceiver *v __attribute__((unused)) = [[VoiceReceiver alloc] init];
....
}
Will not work. As soon as this callback is finished v will be dealloc'd.
If you need to use it in the appDelegate. Make the calss a property in the .h and init it where you are now.
e.g.
appDeletage.h
#property (nonatomic, strong) VoiceReceiver *voiceReciever;
appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
voiceReciever = [[VoiceReceiver alloc] init];
....
}
The key difference here is that the appDeleagte is a singleton that will always be in memory so long as the app is running. Adding a strong property to this means it won't be removed unless the app crashes.

Xcode error: xpected to have a root view controller at the end of application launch

I'am getting this error ( Applications are expected to have a root view controller at the end of application launch ) and i'am not sure why? I was expecting something like the token is: 38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7c e90d56e9 fe145bcc 6c2c594b. But no :(
Really hope someone has a solution for this issue. Thank you, for using you time on this.
The code is as follow.
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:viewController.view];
//[self.window setRootViewController:viewController];
[window makeKeyAndVisible];
NSLog(#"Registering for push notifications...");
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *str = [NSString
stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(str);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError: (NSError *)err {
NSString *str = [NSString stringWithFormat: #"Error: %#", err];
NSLog(str);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
for (id key in userInfo) {
NSLog(#"key: %#, value: %#", key, [userInfo objectForKey:key]);
}
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
Your code is out of date. You should not be adding your view controller's view as a subview of your window. You should be setting the rootViewController property of your window to your view controller:
window.rootViewController = viewController;

Resources