How to catch ios device button press in react native? - ios

I need to catch sound volume button press inside my react-native application. Couldn't find anything in docs.

You can use react-native-system-setting package with addVolumeListener listener. Something like this
componentDidMount() {
// listen the volume changing
this.volumeListener = SystemSetting.addVolumeListener(data => {
// your action here
});
}

You could create a native module as per FuzzyTree's comment however if you want something that's ready out of the box you could use https://github.com/IFours/react-native-volume-slider and make it hidden. The onValueChange callback is called upon the iOS device volume controls being changed.
Another idea could be to look into the aforementioned module and just take out what you need to form a new module and publish it for the benefit of everyone.

Related

iOS 15 DualSense is opening App Library on PS button long press

On iOS 15 a long press on the PS Button of the DualSense controller is opening the App Library and I don't receive a callback via the valueChangedHandler function. The App library which will be opened looks like this
This is how I handle all controller inputs:
func handleController(controller: GCController) {
controller.extendedGamepad?.valueChangedHandler = { [weak self] (gamepad: GCExtendedGamepad, element: GCControllerElement) in
guard let self = self else {
return
}
// no feedback received when performing a long press on the PS button
}
Can the game library be suppressed somehow? Sony's PS Remote Play app somehow manages to suppress it, but I don't know how, nor can I find anything in Apple's official API documentation.
Edit: Seems this problem only occurs on iPads, on iPhones this problem doesn't exist. Is there some API or anything on iPads to suppress this behaviour? I assume the most majority of users don't want to open the App Library in the middle of the game.
If someone ever faces the same problem you can actually disable system gestures for the Home button.
In Swift all you have to add is this line (controller is a GCController object)
controller.physicalInputProfile.buttons[GCInputButtonHome]?.preferredSystemGestureState = .disabled
In ObjectiveC it would work like this
controller.physicalInputProfile.buttons[GCInputButtonHome].preferredSystemGestureState = GCSystemGestureStateDisabled;
Thanks to the Apple employee who helped me here
https://developer.apple.com/forums/thread/711905
Edit: on tvOS this isn't working as the PS button (menu button) of a controller always have to act as home event
https://developer.apple.com/forums/thread/715012

One Time Password On IOS App - Suggestion not appearing above keyboard

I'm looking to implement where a OTP is made a suggestion at the top of the keyboard for an OTP Entry in an IOS app.
The IOS version on the phone is 12.2.
THE ISO SDK Version of my App is 12.1.
Using Visual Studio (Windows) 2017 15.9.13
Now I have done the following......
Created an new control public class OTPEntry : Xamarin.Forms.Entry
Created a renderer for the control and in this I do Control.TextContentType = UITextContentType.OneTimeCode;
I then use this control on a ContentPage with the correct namespace etc.
SO when I am on the form with this control, I send a text to the phone with an OTP. On the phone if I click on the code it offers a "Copy Code" option so it is recognised as an OTP.
However, for the life of me, when I tap in the control, to bring up the keyboard, I do not see the code in the top of the keyboard as expected.
What could I possibly be missing?
It seems the steps to implement this are relatively straightforward but I cannot seem to get it working.
Any ideas, pointers would be very greatly appreciated.
Code below...
CONTROL - IN Xamarin Forms Project
namespace XXXX
{
public class OTPEntry : Xamarin.Forms.Entry
{
public OTPEntry()
{
}
}
}
RENDERER - IN IOS Project
namespace XXXX.YYYY.ZZZZ
{
public class OTPEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.TextContentType = UITextContentType.OneTimeCode;
}
...
...
}
}
}
USAGE - IN CONTENT PAGE IN Xamarin Forms Project
<XXXX:OTPEntry x:Name="txtToken" Keyboard="Numeric" Placeholder="Two Factor Code" HeightRequest="50" WidthRequest="300" TextColor="#2A295B" BackgroundColor="White" Margin="0"/>
Firstly,OneTimeCode is available after iOS 12.0.So I suggest add the following code in CustomRenderer
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
{
Control.TextContentType = UITextContentType.OneTimeCode;
}
What happens is that when an OTP message receives into the Message Inbox, iOS runs a simple text matching algorithm that determines if that message is a valid OTP message or not and based on that keep a track of it in the memory, then when the user clicks on the OTP AutoFill enabled text field in an app, iOS keyboard popup that OTP as a suggestion in the keyboard. So that your users can fill up the OTP into the app without leaving the app or going back into the Messaging app.
You need to check if the format of OTP is correct .One way to verify whether the text message captcha format is legal is to open [SMS] on the iPhone, click on the message captcha, if from the bottom of the call option copy captcha option, can indicate that it is possible;
And don't forget to open the Autofill Passwords in system setting ->account and password .
So - after verification that the code seemed to be OK and has worked for others I was beginning to think I was going crazy.
I then had a look through the phone settings and discovered "Autofill Passwords" which was turned off.
Once I turned it on, this seems to work as expected.

Determine if the widget is enabled

Is there any way to determine if my Today Widget is already added to Notification Centre by user? I need to know so I can change some Labels in host app accordingly.
There is no API for that, but you could have your today widget write something to the shared container that you can read from your app to determine if it's been displayed. The main problems with that are that it won't happen until the widget has been displayed at least once, and you can't relly tell if they've installed and then removed it.
func widgetHasRun() {
if let sharedContainer = NSUserDefaults(suiteName: "group.com.my.app") {
sharedContainer.setBool(true, forKey: "today widget installed")
sharedContainer.synchronize()
}
}
We use this technique to determine whether we should prompt new users to install our widget.

how make to make ios keyboard's return key submit input in unity?

I have a Unity UI's input field and a text box. When I use Input.GetKeyDown (KeyCode.Return), it only works on the OS X and PC build and not on the iOS build. iOS keyboard's Return key does nothing. I have tried the events, too, but it doesn't work even then.
Somebody please tell me the solution to this problem if there is any?
While I can't think of a way to harness the return key directly on iOS, there is a way to do so with the "Submit" key using the TouchScreenKeyboard class in Unity
Specifically, it has a variable TouchScreenKeyboard.done to indicate whether the user has pressed the "Submit" (or equivalent) button on any mobile device (iOS, Android WP)
You can also check the wasCanceled variable to see whether the user canceled the input.
Example
public class TouchKeyboardExample : Monobehaviour {
private TouchScreenKeyboard touchScreenKeyboard;
private string inputText = string.Empty;
void Start () {
touchScreenKeyboard = TouchScreenKeyboard.Open(inputText, TouchScreenKeyboardType.Default);
}
void Update () {
if(touchScreenKeyboard == null)
return;
inputText = touchScreenKeyboard.text;
if(touchScreenKeyboard.done)
Debug.Log("User typed in "+inputText);
if(touchScreenKeyboard.wasCanceled)
Debug.Log("User canceled input");
}
}
I've never tried this on IOS, so I'll just guess here.
Are you using the new Unity UI that was introduced in Unity4.6 / Unity5? If so, you might want to use the UI EventSystem, which you probably have somewhere in scene already (it is being added automatically when you add new Canvas object). If you don't have it in scene, add it via menu GameObject->UI->Event System.
In the EventSystem game object, there's a component called Standalone Input Module, where you can then define Submit Button property - which is mapped to Unity's Input Manager (Edit->Project Settings->Input).
On the individual UI element (i.e. InputField in your case), you can now add EventTrigger component, which can listen to Submit event and call a custom method, even pass it some data (e.g. itself, as InputField parameter of the method).
You can also listen to many more events this way (select, hover, drag, etc).
this works fine for me (PC/Mobile), try it out
this.yourInput.onSubmit.AddListener(delegate {
if (this.yourInput.text.Length > 0)
// do something here after enter (PC) or done (mobile)
});

How does phoneGap (Cordova) work internally, iOS specific

I have started developing html applications for mutliple platforms. I recently heard about Cordova 2.0(PhoneGap) and ever since I have been curious to know how the bridge works.
After lot of code walking, i saw that the Exec.js is the code where call from JS -> Native happens
execXhr = execXhr || new XMLHttpRequest();
// Changeing this to a GET will make the XHR reach the URIProtocol on 4.2.
// For some reason it still doesn't work though...
execXhr.open('HEAD', "file:///!gap_exec", true);
execXhr.setRequestHeader('vc', cordova.iOSVCAddr);
if (shouldBundleCommandJson()) {
execXhr.setRequestHeader('cmds', nativecomm());
}
execXhr.send(null);
} else {
execIframe = execIframe || createExecIframe();
execIframe.src = "gap://ready";
But want to understand how that works, what is the concept here, what does file:///!gap_exec or gap://ready do? and how does the call propgate to the lower layers (native code layers)
thanks a bunch in advance.
The trick is easy:
There is a webview. This displays your app. The webview will handle all navigation events.
If the browser navigates to:
file:///!gap_exec
or
gap://
the webview will cancel the navigation. Everything behind these strings is re-used as an identifier, to get the concrete plugin/plugin-method and parameter:
pseudo-url example:
gap://echoplugin/echothistext?Hello World
This will cause phonegap to look for an echoplugin and call the echothistext method to send the text "Hello World" to the (native) plugin.
update
The way back from native to javascript is (or may be) loading a javascript: url into the webview.
The concrete implementation is a little bit more complex, because the javascript has to send a callback-id to native code. There could be more than one native call are running at the same time. But in fact this is no magic at all. Just a number to get the correct JSON to the right javascript-callback.
There are different ways to communicate between the platform and javascript. For Android there are three or four different bridges.
I am trying to figure this out in more detail, too. Basically there are 2 Methods on the iOS side that can help ...
- webView:shouldStartLoadWithRequest:navigationType: and
- stringByEvaluatingJavaScriptFromString:script
From the sources it seems cordova sends a "READY" message using webView:shouldStartLoadWithRequest:... and then picks up results with the second message, but I am not sure.
Cordova Sources iOSExec
There is much to learn there.

Resources