I have an iOS project with three targers:
-Main App (parent)
-Today Extension (widget)
-Framework that holds some objects and methods, that are common to the parent app and the widget. Those members are being accessed from the app and the widget.
Both the app and the widget can send messages to the framework, but the framework cannot send messages to them. I cannot invoke app or widget method from the framework.
My problem is that: from the widget, I invoke some async method in the shared framework. Since the method is async, the widget does not know when the invoked method has finished its task.
I need the framework to notify the widget somehow when its method has finished, and trigger a response method in a widget class.
Is there a way to send message from the framework to the widget? I do not want to use the UserDefaults to share that information between targets.
Related
TLDR: Is there some way I can use a callback or get a return value from react to my native code (iOS)? Or can I use a set of locks to enforce ordering for eventdispatcher and eventemitter listeners to enforce an ordering?
More Information:
So I'm using the event dispatcher in my iOS code (self.bridge.eventDispatcher) and that's working great. I'm able to send events with information to my react code.
However, I noticed that this works asynchronously. I currently use this because if I require information on my iOS side, I send a ping to my react side requesting this information. I then lock upon the request and wait for my react code to use NativeModules and invoke an iOS method where I get the requested data.
Basically, enforcing a synchronous pattern feels a little dangerous because I'm not sure whether bridging methods can fail. For example, I can send an event to react and then lock. If my react side does not get it, or fails to send a notification to the iOS side, then I will never unlock and then will have deadlock. So to this, I have two questions. Is bridging reliable enough to avoid deadlocking through this method? Or is there a better way to accomplish the same result and request information from my react side from my iOS code?
Awesome so I got it, turns out there's a structure called RCTResponseSenderBlock. I made another
iOS method:
-(void)tmpMethod:(RCTResponseSenderBlock)callback{
[self.bridge.eventDispatcher sendAppEventWithName:#"channel" body:#{#"Block":callback}
] ;
}
javascriptReciever:
EventEmitter.addListener("channel", async event => {
console.log(event)
event.Block(["Hello There"]);
return;
});
ios Method Invocation:
[self tmpMethod:^(NSArray* response){
NSLog((NSString*)[response objectAtIndex:0]); //prints Hello There
}];
UPDATE
Turns out when I try to do the same for Android, I can't. The Android platform uses WriteableMap or WriteableArray to send events using the following method:
private void sendEvent(ReactContext reactContext,
String eventName,
#Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
WriteableMap and WriteableArray both do not accept objects such as callbacks which made it not possible to request information from the Javascript side. I also attempted to pass in a Promise as opposed to a WriteableMap or WriteableArray and that threw an error. To communicate asynchronously in a synchronous context for android,
I will have to send an event from native to javascript
lock twice to prevent further execution in side native
on my javascript side invoke a method on my native side once viewing the request with the requested data
unlock within the native method invoked by javascript
resume execution since the program has been unlocked
unlock once further after handling whatever needed to be handled synchronously. (Comment if you want my code implementation)
EDIT AGAIN:
The above flow didn't work. I don't have any control over threads in Android since ReactNative always uses the main thread. So if I end up locking the main thread then react-native cannot enter another method to unlock, thus I have deadlock. So not possible to enforce synchronous exchange of data with android.
I want to send crash report to server, from any view controller.
I tried NSSetUncaughtExceptionHandler but it is implemented in delegate.
As I am creating library, so I want to send crash report from library.
You can use frameworks available
Crashlytics
Instabug
HockeyApp
Parse
Your "library" can be a class, which you can instantiate (e.g. as a singleton), or call class methods. Include the header file, and you can call it from anywhere.
If you instantiate it globally (e.g. as a singleton), then you can also have it handle delegate methods, such as those from NSURLSession.
You can even create your own protocol and delegate methods to bubble up events to the caller.
I have an iPhone app and added a WatchExtension. Now I managed to send a string to the Watch using the MMWormhole. In order to use the string I must call update() inside the WKInterfaceController from a method inside my UIViewController, so the iPhone application.
Is that possible?
I tried to do something like InterfaceController.update() but Xcode complained that it does not know the variable InterfaceController.
Thanks in advance :)
The iPhone App and Watch Extension are TWO seperate process, although they are stored in ONE bundle, so you can not call the method of other process in runtime.
In WatchKit:
If you want to share code, use Framework.
If you want to share data, use App Group.
If you want to use notification, use Inter-Process Communication(In iOS, It's Darwin Notification, and MMWormhole use this feature).
I think you want to let the Watch update its interface when iPhone app do something, you can do like this:
send a message to Watch Extension.
Watch Extension receive that message.
In the message handler, update interface.
In my option, the iPhone App and Watch Extension can be seen as a kind of C/S architecture, iPhone App is Server and Watch Extension is Client, maybe this metaphor is easier to understand.
This question already has answers here:
What is the AppDelegate for and how do I know when to use it?
(4 answers)
Closed 8 years ago.
I have an android background . I want to learn XCode . Now i want to understand what does the Appdelegate.h and Appdelegate.m do? As in Android Manifest.xml is the mainFile which launches other Activities . permissions, feature ,broadcast service etc are written in it.
Now can some one explain me the importance of AppDelegate file and explain its component and benefits ?
And where to include permission or Service or BroadCast in app.
I have created an app in Android . Now i am creating it in IPhone which requires permission and services...
Thanks in Advance..
Edit..
According to my study and knowledge. AppDelegate is a controller, it doesn't visually present data (a view) nor does it represent the actual data (a model) but it does determine what view controllers to show etc and manage other views (status bar etc) at the start of the application .it is the launcher class where the first class launches . it consist of some predefined function didFinishLauching and other functions. Is there any detail explanation.
From:
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/AppArchitecture/AppArchitecture.html
The app delegate is a custom object created at app launch time,
usually by the UIApplicationMain function. The primary job of this
object is to handle state transitions within the app. For example,
this object is responsible for launch-time initialization and handling
transitions to and from the background. For information about how you
use the app delegate to manage state transitions, see “Managing App
State Changes.”
In iOS 5 and later, you can use the app delegate to handle other
app-related events. The Xcode project templates declare the app
delegate as a subclass of UIResponder. If the UIApplication object
does not handle an event, it dispatches the event to your app delegate
for processing. For more information about the types of events you can
handle, see UIResponder Class Reference.
I am using Display.screenshot() to get a screen shot for the current displayed screen.
My application has all available persmissions set to allow,
it works well in all device application, but it doesn't work on Facebook and Twitter app -
on those apps i got an exception:
Error: net.rim.device.api.system.ControlledAccessException: Unauthorized attempt to attach to this application
what should I do to overcome this?
You seem to be calling Application.getApplication() somewhere in the code.
Your ApplicationMenuItem code generally runs within the UI application whose menu it is launched from. So when you click your ApplicationMenuItem within facebook app, it executes within the event dispatcher thread of facebook app.
However, since your code is not a part of the facebook app, it can't access its Application Object using the Application.getApplication() method.
If you are not calling this method yourself, maybe Display.screenshot() calls it internally. To solve this, you need to run the code in your app's event dispatcher thread. This can be done by using the special method addMenuItem(long, ApplicationMenuItem, ApplicationDescriptor) while registering the menu item and passing it your app descriptor.