How to achieve inline-reply with iOS platform in ionic? - ios

I am facing issue with push notification.
Actually i want to make inline-reply with ionic version 3. we are using phonegap-plugin-push (https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md). in Android it will work perfectly fine. but in iOS it has not giving the example with inline-reply.
I have also see same functionality with native iOS and there it is working fine. we need to set some behaviour property in that. but i can not set those property while defining the categories.
Can you please check how to achieve this things in iOS ?
Let'me know if you need any further information ?
I have tried with phonegap-plugin-push.
I have already asked this question in ionic forum and created issue in phonegap-plugin-push gitHub repository. below are the link for your reference.
https://forum.ionicframework.com/t/can-we-do-quick-reply-or-inline-reply-in-ios-using-push-notification/125347/5
https://github.com/phonegap/phonegap-plugin-push/issues/2823
i think we need to set property in below configuration in ionic
const options: PushOptions = {
      android: {
        icon: 'icon_small',
        clearNotifications: 'false',
        forceShow: 'false',
      },
      ios: {
        alert: 'true',
        badge: true,
        sound: 'false',
        categories: {
          reminder: {
            yes: {
              callback: 'confirmReminderCallback',
              title: 'CONFIRM',
              foreground: false,
              destructive: false,
//some where over here need to set the behaviour property
            },
            no: {
              callback: 'declineReminderCallback',
              title: 'DECLINE',
              foreground: false,
              destructive: false
            }
          }
        },
        
      },
      windows: {},
      browser: {
        pushServiceURL: 'http://push.api.phonegap.com/v1/push',
      },
    };

Related

runtime/cgo: could not obtain pthread_keys Simulator Error

I ran into this issue with Xcode 12.1 simulators running iOS 14.1. My code does compiles then I get the runtime error of
runtime/cgo: could not obtain pthread_keys
tried 0x118 0x119 0x11a 0x11b 0x11c 0x11d 0x11e 0x11f 0x120 0x121 0x122 0x123 0x124 0x125 0x126 0x127 0x128 0x129 0x12a 0x12b 0x12c 0x12d 0x12e 0x12f 0x130 0x131 0x132 0x133 0x134 0x135 0x136 0x137 0x138 0x139 0x13a 0x13b 0x13c 0x13d 0x13e 0x13f 0x140 0x141 0x142 0x143 0x144 0x145 0x146 0x147 0x148 0x149 0x14a 0x14b 0x14c 0x14d 0x14e 0x14f 0x150 0x151 0x152 0x153 0x154 0x155 0x156 0x157 0x158 0x159 0x15a 0x15b 0x15c 0x15d 0x15e 0x15f 0x160 0x161 0x162 0x163 0x164 0x165 0x166 0x167 0x168 0x169 0x16a 0x16b 0x16c 0x16d 0x16e 0x16f 0x170 0x171 0x172 0x173 0x174 0x175 0x176 0x177 0x178 0x179 0x17a 0x17b 0x17c 0x17d 0x17e 0x17f 0x180 0x181 0x182 0x183 0x184 0x185 0x186 0x187 0x188 0x189 0x18a 0x18b 0x18c 0x18d 0x18e 0x18f 0x190 0x191 0x192 0x193 0x194 0x195 0x196 0x197
The code runs fine on the iOS 13.5 simulators as well as on a physical device running iOS 14. I would like to have the simulators running and working. Does anyone have a solution for this issue to work on iOS 14 simulators? And if anyone might know if this issue would affect Apple Store submissions
I am assuming you are using a go library framework file with your iOS Project. We had a similar issue with our codebase. To answer your questions:
It won't affect Apple Store submissions/releases on the App Store - we have made few releases in the last few months and there have been no issues.
Regarding the issue itself, I assume this is because of the go version - you have not stated what go version you are using but this was prevalent if you were using an older version (1.10.x or previous).
Updating your go lib version to a newer release and building your framework file with that version should solve your problem
I haven't understood much on why the issue occurs but here's an answer that tries to explain something similar

MapBox Route Progress RouteStepProgress variables mostly return nil

I used to use the userDistanceToManeuverLocation variable from the RouteStepProgress Class but this seems to just return nil recently.
Just in case I was doing something wrong I tried following the MapBox iOS nav tutorial (https://docs.mapbox.com/help/tutorials/ios-navigation-sdk/) but this had the same result.
Going by the MapBox tutorial I would do the following to get the variable:
let navigationViewController = NavigationViewController(for: directionsRoute!)
let distance = navigationViewController.navigationService.routeProgress.currentLegProgress.currentStepProgress.userDistanceToManeuverLocation
I don't seem to see any error messages or other concerns. I would get this variable on every tick of the users location but now just returns nil. Thanks for any help
So after some testing I figured out the issue is to do with the newer versions of MapBox Navigation (SDK MapboxNavigation). Anything from version 0.29.0 onwards causes issues. For now I'm sticking with version 0.28.0 and will have to report this to MapBox
Edit:
It looks like the latest version (MapboxNavigation 0.38.0 at the time of writing this edit) appears to provide a solution. I now use distanceRemaining found in the RouteProgress class which does the same thing.

ApplePay 'requiredShippingAddressFields' was deprecated in iOS 11.0

What is the latest way to set/activate email, phone, or postalAddress in IOS > 11?
I tried scrolling through the methods and attributes and came up with the following: paymentRequest.shippingType
Here is the old way:
paymentRequest.requiredShippingAddressFields = [.phone, .email, .postalAddress]
I would like to understand if there is a way to write the code that is easier than the old way and doesn't cause a warning.
It’s been replaced by requiredShippingContactFields.
https://developer.apple.com/documentation/passkit/pkpaymentrequest/2865927-requiredshippingcontactfields
requiredShippingAddressFields is deprecated, use requiredBillingContactFields instead.
For more info: documentation.

Writing a Cordova/Ionic Plugin in Swift

I followed the instructions from this site, http://moduscreate.com/writing-a-cordova-plugin-in-swift-for-ios/, for creating my own cordova plugins for iOS platform.
Firstly, I installed plugman and created a new plugin. This is my plugin.xml :
<?xml version='1.0' encoding='utf-8'?>
<plugin id="com-moduscreate-plugins-echoswift" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>ModusEchoSwift</name>
<js-module name="ModusEchoSwift" src="www/ModusEchoSwift.js">
<clobbers target="modusechoswift" />
</js-module>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="ModusEchoSwift">
<param name="ios-package" value="ModusEchoSwift" />
</feature>
</config-file>
<source-file src="src/ios/ModusEchoSwift.swift" />
</platform>
</plugin>
Here is my js file for the plugin, i.e. ModusEchoSwift.js:
var exec = require('cordova/exec');
exports.echo = function(arg0, success, error) {
exec(success, error, "ModusEchoSwift", "echo", [arg0]);
};
exports.echojs = function(arg0, success, error) {
if (arg0 && typeof(arg0) === 'string' && arg0.length > 0) {
success(arg0);
} else {
error('Empty message!');
}
};
And this is my native Swift class, i.e. ModusEchoSwift.swift:
#objc(ModusEchoSwift) class ModusEchoSwift : CDVPlugin {
func echo(command: CDVInvokedUrlCommand) {
var pluginResult = CDVPluginResult(
status: CDVCommandStatus_ERROR
)
let msg = command.arguments[0] as? String ?? ""
if msg.characters.count > 0 {
/* UIAlertController is iOS 8 or newer only. */
let toastController: UIAlertController =
UIAlertController(
title: "",
message: msg,
preferredStyle: .Alert
)
self.viewController?.presentViewController(
toastController,
animated: true,
completion: nil
)
let duration = Double(NSEC_PER_SEC) * 3.0
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(duration)
),
dispatch_get_main_queue(),
{
toastController.dismissViewControllerAnimated(
true,
completion: nil
)
}
)
pluginResult = CDVPluginResult(
status: CDVCommandStatus_OK,
messageAsString: msg
)
}
self.commandDelegate!.sendPluginResult(
pluginResult,
callbackId: command.callbackId
)
}
}
These are the files in my plugin. Now I am trying to show a simple alert using this plugin in my ionic project. I have a simple index.html right now,where I wanna display the alert, here it is:
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content>
<div ng-controller="myController">
Hello {{user}}
</div>
</ion-content>
</ion-pane>
And here is my controller :
.controller('myController', function($scope){
console.log("Ok");
$scope.user = "kAy";
ModusEchoSwift.echo('Plugin Ready!', function(msg) {
console.log("Success");
},
function(err) {
console.log("Error");
}
);
})
Here in this controller, I keep getting the error that ModusEchoSwift is not defined, which I do not understand! Can anyone tell me how to use the function of my plugin in my existing ionic project??
This does work correctly with ionic v2.2.1 & cordova v6.5.0, provided the steps outlined in Simon's blog post are followed, and with one minor change: Add this line of code in the App.component.ts file below the imports:
declare let modusechoswift;
The Bridging-Header.h file in the ionic app was under 'Other Sources' in my case. Simon's post refers to a different location, which initially put me off, but it was a non-issue. In fact, moving around that header file anywhere in my Xcode project did not appear to have any effect. I'm guessing XCode doesn't care where the file is as long as it's present.
I am the author of the blog that you're following, I've checked all of your code that you posted and it all looks correct. It may be that you haven't yet added the bridging header plugin to your Cordova app project that I refer to in my post (quoted below).
In short I think you need to add the plugin referenced below which will help deal with the Objective C to Swift bridging header needed. Also check you have the Modus plugin and the bridging one installed correctly, by doing
cordova plugin ls
In your app project's main folder (the one with config.xml in it). This should return both the ModusEchoSwift and the bridging header plugin in its output if both are correctly installed in the app project.
The Cordova plugin that we have been working on is implemented in
Swift, but the native parts of a Cordova iOS app are written in
Objective-C still. Normally, this isn’t code that we need to be
concerned with, as the Cordova CLI auto generates it for us along with
an Xcode project to compile and build it.
When using Swift to write a plugin however, we do need to modify the
Cordova app’s Xcode project settings to allow our Swift plugin code to
access the Cordova objects that it needs, which are written in
Objective-C. To do this, we make use of a bridging header file.
A bridging header file is an Objective-C header that contains imports
for each Objective-C header that we want to be able to access in our
Swift code. In our case, we need access to some of the Cordova
objects: CDVPlugin, CDVInvokedUrlCommand and CDVPluginResult for
example. This means that our bridging header just needs to contain:
#import <Cordova/CDV.h>
as our plugin won’t be using any other Objective-C references.
CDV.h contains declarations for all of these, and is part of every
Cordova app that the CLI generates.
Our bridging header needs to live in the folder
platforms/ios/ in our Cordova app (e.g. for our TestApp that
we’ll build next this would be platforms/ios/TestApp). It also needs
to be referenced in the Xcode project file so that Xcode knows that
this is a bridging header and that the Objective-C app project also
contains Swift code when compiling and linking the application.
In Cordova, the platforms folder should ideally be a build artifact –
generated entirely by executing Cordova CLI commands. We should not be
editing or adding files manually in this folder. However, we now find
ourselves needing to do so in order to insert the required bridging
header into the Xcode project. Thankfully, Cordova’s CLI supports
hooks that allow us to run scripts before or after certain CLI
commands are executed, precisely to deal with situations such as this.
Hook scripts can be bundled up and distributed with plugins, making
them easy to share and add to projects. GitHub user Alexis Kofman
wrote a handy plugin that installs a hook script to automatically
create the bridging header we need and configure the Xcode project to
use it. His plugin can be found here and we’ll use it when
configuring a test Cordova app to run our Swift plugin with.
For more information on mixing Objective C and Swift in the same
project, we would recommend referring to the Apple documentation
on the subject.
On further investigation it looks like you didn't add the bridging header plugin to your test app BEFORE adding the ios platform or the Swift plugin, this order of events is needed to get the bridging header plugin hook script to fire at the right time.
The following order of commands gets you to a working application from nothing, I just ran this on my local machine to triple check:
cordova create mytest
cd mytest
cordova plugin add cordova-plugin-add-swift-support --save
cordova platform add ios --save
cordova plugin add https://github.com/ModusCreateOrg/cordova-swift-plugin-example
cordova build ios
cordova emulate ios
Let emulator start.
Connect to emulator using Safari remote debugger.
Open JS console
In JS Console:
modusechoswift.echo('hello', undefined);
Observe a native 'toast' with 'hello' message appear from the plugin in the simulator then vanish soon after. Screenshot attached.
call controller 'modusechoswift' not 'ModusEchoSwift' and be sure platform is ready
$ionicPlatform.ready(function() {
modusechoswift.echo('Plugin Ready!', function(msg) {
console.log("Success");
},
function(err) {
console.log("Error");
}
);
});
Usually the "plugin not defined" error means you need to expose the ModusCreate plugin via an Angular service (Ionic is built on AngularJS). Cordova itself doesn't use Angular, which is why that works but Ionic doesn't. There are a couple ways to make the service - I'd look at ngCordova for examples. ngCordova is most likely how cordova-plugin-camera is getting exposed to Angular already.
Once you've done that, you'll need to inject that service into your controller (in much the same way that $scope is already getting injected). After that you should be good to go. Hope that helps.

Using new features while supporting older iOS versions

I am developing an app using SDK 8.1, Apple LLVM 6.0 and Xcode 6.1.1. The deployment target is 6.0. I'm using NSOperationQueue and I want to use QoS whenever it's available.
The code I'm using is:
if ([self.operationQueue respondsToSelector:#selector(setQualityOfService:)]
&& (&NSOperationQualityOfServiceUserInitiated)) {
[self.operationQueue performSelector:#selector(setQualityOfService:) withObject: NSOperationQualityOfServiceUserInitiated];
} else {
//Other stuff not related to the scope of this question
}
The error I get is:
Use of undeclared identifier 'NSOperationQualityOfServiceUserInitiated'
I added the if (&NSOperationQualityOfServiceUserInitiated) part to check if this constant exists. This code worked with older versions of Xcode/Obj-C Compiler.
I am able to use selectors with performSelectorWithIdentifier but what about constants that do not have a defined value in the docs? The value of this constant is set by NSQualityOfServiceUserInitiated but there is no definition for this value that can be hardcoded.
How do I fix that?
There are several things wrong with the code.
NSOperationQualityOfServiceUserInitiated is a native type (NSInteger) so you can't use it the way that you are in either line.
The qualityOfService is a property of type NSQualityOfService. Your attempt to pass an argument to the qualityOfService method (getter method) makes no sense. If you are trying to set the quality of service, you need to call the setter but you can't use performSelector.
You want:
if ([self.operationQueue respondsToSelector:#selector(qualityOfService)]) {
self.operationQueue.qualityOfService = NSOperationQualityOfServiceUserInitiated;
} else {
//Other stuff not related to the scope of this question
}
This code will compile fine as long as your Base SDK is iOS 8.0 or later. The Deployment Target doesn't matter.
If you also want to build this code with Xcode 5 or earlier (a Base SDK of iOS 7 or earlier) then you need to wrap the code with the proper compiler directives to check for the Base SDK.

Resources