I want to develop an app in Qt for iOS that contains a map. During the use, the screen lock of the phone should be disabled.
But I can't find any solution how to prevent the screen lock in iOS using Qt.
How can be done that?
You must use the native iOS api. You can compile ObjC++ code directly with the clang compiler in your Qt application.
So you can mix .cpp and .mm (ObjC++) files. QtCreator and qmake support this via the OBJECTIVE_SOURCES keyword.
In a yourclass.mm implementation:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
void YourClass::setTimerDisabled() {
[[UIApplication sharedApplication] setIdleTimerDisabled: YES]
}
yourclass.h:
class YourClass
{
public:
void setTimerDisabled()
}
Now you can call from anywhere in your Qt-app:
YourClass yc;
yc.setTimerDisbabled();
In your project file (.pro), if you only want this file on iOS:
ios {
OBJECTIVE_SOURCES += \
yourclass.mm \
}
And if you only want specified code on a single platform, use preprocessor commands in your source and header files like this:
#if defined(Q_OS_IOS)
// iOs stuff
#elsif defined(Q_OS_ANDROID)
//Android stuff ...
#else
//Other stuff ...
#endif
Related
I would like to get the iOS device name using Native Modules and without using an external library.
According to React Native's documentation, "React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events". However, the documentation also explains that you can export constants to JavaScript without doing a round-trip from JS to Objective-C.
Is there a way to export a constant from a native module with the device name/model as a value without having to use a callback?
You can create the header file as shown below:
// RCTDeviceInfo.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#interface RCTDeviceInfo : NSObject<RCTBridgeModule>
#end
Then to export it you can do :
//RCTDeviceInfo.m
#import "RCTDataLogger.h"
#implementation RCTDeviceInfo
RCT_EXPORT_MODULE(DeviceInfo);
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getName) {
return [[UIDevice currentDevice] name];
}
#end
Then synchronously on the Javascript side you can do the following:
import { NativeModules} from "react-native"
const DeviceInfo = NativeModules.DeviceInfo;
const deviceName = DeviceInfo.getName();
You can read more from the official docs here
I am new to the development of React Native, I know iOS.
Just want to know about few points:
Can we add iOS (swift or objective C) code in a React Native App?
Can we add React Native Views into the existing iOS app?
I have googled and got the examples which point to that 2nd one is quite possible and Instagram did it in edit profile screen.
But I cannot find examples where it's a React Native app and we introduces swift or Objective-C code in between.
Please if anyone knows of any links or examples available for Case 1, please do let me know about it.
2nd question:
When we integrate react native with iOS, it will be through a bridge. Let's say I create an app in Swift, to get react native views in it, we have to go through 2 bridges, one converting Swift to Objective-C and then bridge between Objective-C to React Native. Is that correct? If yes will it be as fast as the native app?
Yes. You can do both of them
1.
https://facebook.github.io/react-native/docs/platform-specific-code.html
2.
https://codeburst.io/integrate-react-native-into-an-existing-app-ios-87c947a16044
https://facebook.github.io/react-native/docs/integration-with-existing-apps.html
Can we add iOS (swift or objective C) code in a React Native App
Yes, I was able to do so:-
I created a React Native project, compiled it and run it in the simulator.
Go to the iOS folder in directory structure in the project and open the .xcodeproj in xcode.
Create an objective c file (MyObjcClass) and make functions which you want to use in React.
MyObjcClass.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#interface MyObjcClass : NSObject <RCTBridgeModule>
#end
MyObjcClass.m
#import "MyObjcClass.h"
#implementation MyObjcClass
// tells react bridge to bridge our created class
RCT_EXPORT_MODULE()
- (NSDictionary *)constantsToExport {
return #{#"CreatedBy": #"Type any number and get Square"};
}
RCT_EXPORT_METHOD(squareNumber:(int)number getCallback:(RCTResponseSenderBlock)callback) {
callback(#[[NSNull null], [NSNumber numberWithInt:(number*number)]]);
}
Now we can call these methods in JS.
Below I will show how to call objective c in React.
App.js
import React from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
// to import native code
import {NativeModules} from 'react-native';
var MyObjcClass = NativeModules.MyObjcClass;
export default class App extends React.Component {
state = {
number:0
};
squareMe(num) {
if (num == '') {
return;
}
MyObjcClass.squareNumber(parseInt(num), (error, number) => {
if (error) {
console.error(error);
} else {
this.setState({number: number});
}
})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.spaceBetween}>Objective C inclusion</Text>
<TextInput placeholder="type a number ...." style={styles.input} onChangeText={(text) => this.squareMe(text)}/>
<ListItem placeName={this.state.number}></ListItem>
</View>
);
}
}
yes we can do
import {Platform} from 'react-native';
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('Work around a change in behavior');
}
To bridge an iOS native module into React Native, you can follow along the official instructions: iOS Native Modules.
To paraphrase the important parts:
Open your .xcworkspace file in your ios folder to open XCode
Select File > New > File
Select header file
Name the header and select your project and its tests as the targets
// RCTCalendarModule.h
#import <React/RCTBridgeModule.h>
#interface RCTCalendarModule : NSObject <RCTBridgeModule>
#end
Select File > New > File
Select Objective-C file. Name it the same as the header but with .m instead of .h. Select your project and its tests and targets
// RCTCalendarModule.m
#import "RCTCalendarModule.h"
#implementation RCTCalendarModule
// To export a module named RCTCalendarModule
RCT_EXPORT_MODULE();
#end
In your React Native App or component, import NativeModules and use your new method
import {NativeModules, Button} from 'react-native';
const {CalendarModule} = NativeModules;
const onPress = () => {
CalendarModule.createCalendarEvent('testName', 'testLocation');
};
Note: You will need to keep rebuilding your ios app as you iterate (eg. run yarn ios after making a change to the .m or .h files)
For your second question, you can also add React Native into existing iOS apps. Follow these official instructions: Integration with Existing Apps.
I am tinkering with the sample project "SpatialAudio" from Google VR SDK for Unity, to implement it in iOS.
I built it in Unity using the latest GVR SDK, so I had to replace a few deprecated keywords (GvrAudioSource instead of CardboardAudioSource, etc.)
If I build it in Xcode just as Unity gives it to me, it runs fine in the physical device.
Then, I tried to edit the Unity-generated file 'main.mm' to change the default App Controller (UnityAppController) to a new one, let's call it NewAppController.
// main.mm
...
const char* AppControllerClassName = "UnityAppController";
...
//UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]); // old
UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:"NewAppController"]); // new
NewAppController is a class which inherits from UnityAppController and does not override any of its methods or properties, like this:
#interface NewAppController : UnityAppController
#end
#implementation NewAppController
#end
I thought that it should work exactly the same as before, but now I get the following warning in runtime:
"Audio effect GVR Audio Renderer could not be found. Check that the project contains the correct native audio plugin libraries and that the importer settings are set up correctly."
Everything else works just fine: I can see the video and even hear the sounds, but only they are not 'spatialized'.
I am using:
GVR SDK 1.1,
Unity 5.5.0f3,
iOS 10.1.1
I found the solution. I was missing two important things: First, messing with main.mm causes a lot of trouble. The correct approach for defining a custom App Controller is to create a subclass of UnityAppController and adding the macro IMPL_APP_CONTROLLER_SUBCLASS(name_of_the_class) at the bottom of its .mm file. Second, Unity automatically generates a custom app controller, called CardboardAppController, which is located in the build directory, under 'Libraries/Plugins/iOS'. One of its functions is registering the unity audio effect plugin. I was bypassing this file without knowing, causing the audio renderer to not initialize properly. So my solution was to comment out the macro at the end of the file CardboardAppController.mm (line 71):
//IMPL_APP_CONTROLLER_SUBCLASS(CardboardAppController)
And defining the new custom controller as a subclass of CardboardAppController:
#import "CardboardAppController.h"
#interface NewAppController : CardboardAppController
#end
#implementation NewAppController
#end
IMPL_APP_CONTROLLER_SUBCLASS(NewAppController)
Is it possible to write unity IOS plugin in Swift?
I already have a working swift framework and want to use it as a plugin in Unity
I saw some places which say it can only be done on Objective-c but is there a workaround for swift?
How to call Unity methods
Unity interface functions are defined in UnityInterface.h in Xcode project built by Unity. This header file is imported in UnitySwift-Bridging-Header.h, so you can call the functions directly in your Swift codes.
To call Unity methods, use UnitySendMessage function like below:
// Example.swift
import Foundation
class Example : NSObject {
static func callUnityMethod(_ message: String) {
// Call a method on a specified GameObject.
UnitySendMessage("CallbackTarget", "OnCallFromSwift", message)
}
}
How to access Swift classes from Unity
Step 1: Create your Swift classes.
// Example.swift
import Foundation
class Example : NSObject {
static func swiftMethod(_ message: String) {
print("\(#function) is called with message: \(message)")
}
}
Step 2: Include "unityswift-Swift.h" and define C functions to wrap Swift classes in .mm file (Objective-C++).
// Example.mm
#import <Foundation/Foundation.h>
#import "unityswift-Swift.h" // Required
// This header file is generated automatically when Xcode build runs.
extern "C" {
void _ex_callSwiftMethod(const char *message) {
// You can access Swift classes directly here.
[Example swiftMethod:[NSString stringWithUTF8String:message]];
}
}
Step 3: Create interface class to call exported C functions from C#.
// Example.cs
using System.Runtime.InteropServices;
public class Example {
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void _ex_callSwiftMethod(string message);
#endif
// Use this method to call Example.swiftMethod() in Example.swift
// from other C# classes.
public static void CallSwiftMethod(string message) {
#if UNITY_IOS && !UNITY_EDITOR
_ex_callSwiftMethod(message);
#endif
}
}
Step 4: Call the method from your C# code.
Example.CallSwiftMethod("Hello, Swift!");
The file names of UnitySwift-Bridging-Header.h and unityswift-Swift.h are defined in "Objective-C Bridging Header" entry and "Objective-C Generated Interface Header Name" entry in Build Settings. These settings and other settings about Swift compiler are set automatically by PostProcesser when the Unity build runs.
Requirements
iOS 7 or later
Compatibility
Unity 5.3.5f1 Xcode 7.3.1
As top-level Swift is simply not accessible from Unity, the "workaround" for Swift is to write an Objective-C wrapper class around it, and access that.
Depending on the amount and complexity of your Swift code that might still be the most optimal approach.
We are using the Facebook SDK for Unity (v6.0) and I'd like to now whether there's a way that I can check if the Facebook app is installed on the device.
The reason is an existing bug in the Facebook SDK (see here: bug)
I want to identify this scenario (occurs only when the FB app is installed), and react accordingly.
"In order to use a native plugin you firstly need to write functions
in a C-based language to access whatever features you need and compile
them into a library. In Unity, you will also need to create a C#
script which calls functions in the native library."
from http://docs.unity3d.com/Manual/NativePlugins.html
So, basically you need to write your code in Objective-C and provide the communication between the Unity and the Native Code.
The code that you need to implement for checking Facebook APP is;
(void) checkFacebookApp
{
if ([[UIApplication sharedApplication] canOpenURL:[NSURLURLWithString:#"fb://"]])
{
return true;
}
}
However you need some communication between the Unity and Xcode project. So;
class SomeScript : MonoBehaviour {
#if UNITY_IPHONE || UNITY_XBOX360
// On iOS and Xbox 360 plugins are statically linked into
// the executable, so we have to use __Internal as the
// library name.
[DllImport ("__Internal")]
#else
// Other platforms load plugins dynamically, so pass the name
// of the plugin's dynamic library.
[DllImport ("PluginName")]
#endif
private static extern float checkFacebookApp ();
void Awake () {
// Calls the FooPluginFunction inside the plugin
// And prints 5 to the console
bool check = checkFacebookApp ();
}
}