Phonegap enabling push notifications on device - ios

I'm having trouble getting my PhoneGap app to register iOS devices for push notifications. Meaning when someone downloads the app for the first time they aren't being prompted to allow push notifications. Does anyone know a solution for this?

Push notification plugin can be used from here :
In Config.xml :
<feature name="PushPlugin">
<param name="android-package" value="com.plugin.gcm.PushPlugin" />
</feature>
In index.html
<script type="text/javascript" charset="utf-8" src="PushNotification.js"></script>

Related

Cordova iOS crashes when targeting remote server

I have a cordova app built on Angular 1.6 and Ionic v1. I'm facing a terrible issue on iOS and I don't even know what's going wrong. I'll explain the problem and what I've tried so far, hopefully someone will shed some light on this.
The Problem
We have a screen which is a simple form, you fill in some text and add attachments if you like. For attachments, you can:
Take a picture from your camera
Shoot a video with you camera
Record audio
Choose from your library
Choose from your iCloud Drive (iOS) or the File System (Android)
You can then save the record, which stores everything on the file system. Or upload to server, which again stores the record on your device.
The issue is, when I choose a file from the library, or any other source, the app crashes unexpectedly shortly after. I can add attachments and save/upload but when I navigate away, the app crashes. This only happens on iOS. No errors, no warnings, no debuggable output, just crashes. I examined the crash logs on my iPhone and apparently the main thread is being blocked for over 5sec. Which causes a watchdog transgression exception to be thrown. Hard to tell what's causing this thread lock, no idea.
I'm using an iPhone 8 running iOS 12.1. It's worth mentioning that the app works fine on the simulator, no bugs or crashes there.
What I've Tried So Far
At first, I thought perhaps something's wrong with my code. So I reviewed every code file line by line, refactored my JS code and improved the code quality. Made sure promises work as intended, resolved JSLint/TSLint warnings etc.
I have updated all cordova plugins to their latest versions. Also removed both platforms and added the latest versions. None of them helped. So I thought maybe I'm missing a configuration quirk or something. Dug through github documentations and SO threads, couldn't find anything useful. Some other things that I've tried:
Disabled HTTPS on our production server, and sent everything through HTTP
Added NSAppTransportSecurity settings to the *.plist file, and white-listed our domain
Tinkered with the Content-Security-Policy, even removed it altogether
Privacy Descriptions are properly configured (NSCameraUsage etc.)
None of them worked. I've been struggling with this issue for two weeks now.
The Weird Part
What's confusing me, is that when I target my local dev machine, that is, when I set the base URL for my API calls to point to my local IIS, the apps works perfectly fine. No bugs/errors, no crashes.
But when I target our remote server, the app crashes when I try to work with attachments (camera, iCloud etc.). I have no idea what I'm missing here. There are no differences between my machine and our remote server. Both run the exact same software, same configuration, and the mobile app is the same build, running on the same device.
So what I can say for certain, is that this issue has nothing to do with my application code, or Cordova and its plugins. The same build works perfectly when targeting my local IIS.
My app is already in production and this needs to be fixed NOW. This is driving me mad, I've tried everything that I could possibly think of and still, no luck. Has anyone had a similar issue? Any help is appreciated.
I'm not authorized to share my code, and like I said, there's nothing wrong with the code, it works absolutely fine when targeting my local IIS. But for your reference, here's some information about my project.
Preferences in Config.xml
<preference name="SplashScreen" value="screen" />
<preference name="windows-target-version" value="10.0" />
<preference name="AndroidPersistentFileLocation" value="Internal" />
<preference name="iosPersistentFileLocation" value="Library" />
<preference name="webviewbounce" value="false" />
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="BackupWebStorage" value="local" />
Cordova Plugins
<plugin name="cordova-plugin-geolocation" spec="^2.4.3">
<variable name="GEOLOCATION_USAGE_DESCRIPTION" value="Location access allows you to capture your geolocation information on to your records." />
</plugin>
<plugin name="cordova-plugin-device" spec="^1.1.7" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.3" />
<plugin name="cordova-plugin-app-icon-changer" spec="^1.0.0" />
<plugin name="es6-promise-plugin" spec="^4.2.2" />
<plugin name="cordova-plugin-ios-camera-permissions" spec="^1.2.0">
<variable name="CAMERA_USAGE_DESCRIPTION" value="Camera access allows you to capture and attach photos that you take to your records." />
<variable name="MICROPHONE_USAGE_DESCRIPTION" value="Microphone access allows you to capture voice information to your records." />
<variable name="PHOTOLIBRARY_ADD_USAGE_DESCRIPTION" value="Photo library access allows you to upload your photos and media files to your records." />
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Photo library access allows you to upload your photos and media files to your records." />
</plugin>
<plugin name="cordova-plugin-android-fingerprint-auth" spec="^1.4.1" />
<plugin name="cordova-plugin-inappbrowser" spec="^3.0.0" />
<plugin name="cordova-plugin-filechooser" spec="1.1.0" />
<plugin name="cordova-plugin-crosswalk-webview" spec="2.4.0">
<variable name="XWALK_VERSION" value="23+" />
<variable name="XWALK_LITEVERSION" value="xwalk_core_library_canary:17+" />
<variable name="XWALK_COMMANDLINE" value="--disable-pull-to-refresh-effect" />
<variable name="XWALK_MODE" value="embedded" />
<variable name="XWALK_MULTIPLEAPK" value="true" />
</plugin>
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-add-swift-support" spec="1.7.2" />
<plugin name="cordova-plugin-touch-id" spec="3.4.0">
<variable name="FACEID_USAGE_DESCRIPTION" value="OnRecord would like to access your touch ID to let you log in securely." />
</plugin>
<plugin name="cordova-plugin-media-playback" spec="1.0.2-dev5" />
<plugin name="cordova-plugin-documentpicker" spec="1.0.0" />
<plugin name="cordova-plugin-file" spec="6.0.1" />
<plugin name="cordova-plugin-file-transfer" spec="1.7.1" />
<plugin name="cordova-plugin-media-capture" spec="3.0.2" />
<plugin name="cordova-plugin-camera" spec="4.0.3" />
Content-Security-Policy in index.html
<meta http-equiv="Content-Security-Policy" content="default-src 'self' gap://ready ms-appdata file://* *; img-src 'self' content: android-webview-video-poster: data: *; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://maps.googleapis.com https://maps.gstatic.com; media-src *; connect-src *">
App Transport Security Policies
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>your.domain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>1.0</string>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Privacy Descriptions (Permissions)
<key>NSFaceIDUsageDescription</key>
<string>This app would like to access your touch ID to let you log in securely.</string>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app would like to access your location to let you track your records.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs write-access to photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs read/write-access photo library access</string>
Let me know if you need more information or any further explanations. I've tried to describe the problem best as I can. To recap:
The app works flawlessly when targeting my local machine, but crashes when targeting our remote server. What's bugging me is, this shouldn't have anything to do with my app. The camera plugin, choosing files from different sources etc. happen locally on the device, what's it got to do with my base API address?! Very strange indeed.
Update: Clarification
After more test runs, I have figured out what's causing the app to crash. Although it's still not clear, from a UX perspective, this is what happens on iOS:
As soon as I use the Camera plugin (cordova-camera), the app crashes shortly after. It doesn't matter if I choose a file from the camera roll/library, or take a picture etc. I just open the camera or library, cancel and navigate away. The app crashes. So clearly it has something to do with the camera plugin.
What's bugging me is that, as I mentioned before, when I target my local IIS by changing the base URL address, the app works fine. I don't understand why this has anything to do with camera usage, because it happens locally on the device. What I'm speculating now is, perhaps something is causing the app to throw exceptions because the remote URL uses HTTPS. But I'm not getting any warnings/errors in Xcode, so who knows.
Certainly, the issue is not with cordova-ios, the camera plugin, my JS code, or any security configurations (App Transport Security, and Content-Security-Policy). Because the app works fine when targeting my IIS. I think I'm missing something here.
I finally found what's causing the iOS app to crash. The problem was in our code but still, it had something to do with Cordova as well, specifically the File and Camera plugins.
We had a TypeScript class in our project that was developed by someone else long ago. This class handled data access uinsg the File plugin and the native file system. We were using it to store JSON objects on the device, which was working fine, but only for small cases like saving a file or two. You fetch some data from the server, and for each record we create a JSON file on the file system and store it. The problem occured when we used this in a loop. Say you get a 100 records back from the server, and within a loop you call the save method to store the records.
This worked fine, but immediately after using the Camera plugin (or sometimes other plugins like the iCloud Document Picker) the app crashed silently. I'm guessing the File plugin or the write operations were causing memory leaks, or the app to go low on memory, subsequently accessing the Camera plugin crashed the app. I'm not quite sure why everything worked fine on Android, perhaps because the Cordova engine and the Android file system are different.
Nevertheless, there was no need to store JSON data on the file system. So I refactored the project to use LocalStorage instead. It's so much faster and it also resolved the issue. No crashes on iOS! It might be that the code for writing to the file system could be changed to fix the issue, but it wasn't necessary anyway.
I'm glad I have finally figured this out, but it's a bloody nightmare to debug Cordova plugins and spot memory leaks. The only thing left is to replace LocalStorage with something more reliable like SQLite. Because the OS can decide to clear out the data when low on memory/space and we have no control over it. For now, it's totally fine. I've been trying to use the Ionic Storage module because it uses SQLite and allows storing JSON or key/value pairs. But I haven't been able to use the module in Angular 1 which is a bummer because I can use other Ionic Native modules just fine. Case closed.

IOS PhoneGap app rejected by App store becasue of cordova-plugin-geolocation

Apple App store has rejected my app & send this message We noticed that your app requests the user’s consent to access the location but does not clarify the use of this feature in the permission modal alert.
This app is developed using phonegap & we are accessing geolocation using a plugin named cordova-plugin-geolocation. They has also mentioned that apple can create problem & suggest to add following code
<edit-config target="NSLocationWhenInUseUsageDescription" file="*Info.plist" mode="merge">
<string>need location access to find things nearby</string>
</edit-config>
I have added it like this & resubmit it again.
<plugin name="cordova-plugin-geolocation" spec="2.4.2" />
<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
<string>need location access to find things nearby</string>
</edit-config>
But they have sent same feedback. Now what should I do to fix this issue?
The problem is you are using an old version of the plugin that still uses variables for the usage descriptions, and the variables are overwriting the edit-config tag values with an empty value (the default one)
You have two options:
Update the geolocation plugin to 3.0.0 or greater and use the edit-config tag as you are doing now.
Set the usage description for Phonegap Build.
To set the usage descriptions for Phonegap Build you have to do it like this:
<plugin name="cordova-plugin-geolocation" spec="2.4.2">
<param name="GEOLOCATION_USAGE_DESCRIPTION" value="I want to find stores nearby" />
</plugin>
This should work if you have <preference name='phonegap-version' value='cli-7.0.1' /> or newer (or if you don't have any phonegap-version set as it will use the latest as default)
Check in xcode projec generated by cordova if the NSLocationWhenInUseUsageDescription key really exists in Info.plist. Sometimes it happened that cordova build did not copy plugins config correctly and I had to write them by hand.
With PhoneGap Build this worked for me :
<gap:config-file overwrite="true" parent="NSLocationWhenInUseUsageDescription" platform="ios">
<string>Your usage description</string>
</gap:config-file>
Better Answer : Edit (20.04.2018)
A much better solution is to use a more recent PhoneGap version in Build :
<preference name="android-minSdkVersion" value="15" />
<preference name="phonegap-version" value="cli-7.1.0" />
Now the <edit-config/> tag will be recognized by Build.

Phonegap Build / geolocation on iOS

I am using phonegap build
- Phonegap CLI 7.0.1
<gap:plugin name="cordova-plugin-geolocation" source="npm"/>
<feature name="Geolocation">
<param name="ios-package" value="CDVLocation" />
</feature>
My problem is, when I start the app I don't have a dialog box prompting the user to allow geolocation.
and when I go to the app settings,
I only have notifications
Background App refresh
Cellular Data
How can I enable geolocation ?
Thanks
Unlike Android, which notifies of permissions on installation, iOS doesn't ask for permissions until the app attempts to access the feature. I just tested this, and iOS didn't ask for location permission until I called navigator.geolocation.getCurrentPosition (cli-7.0.1).
Note: you can simplify your plugin declaration to:
<plugin name="cordova-plugin-geolocation" />
The gap: is deprecated, and npm is the default (no harm in leaving it). Might be worth locking to a version though othewise it will upgrade to new releases without your knowledge. You don't need the feature tag, the geolocation plugin includes that for you.

ionic2 - embed youtube video play with no sound in iOS v10

I embed a youtube video in ionic2 app:
Page2.ts:
import {SafeResourceUrl, DomSanitizer} from '#angular/platform-browser';
export class Page2 {
url: SafeResourceUrl;
constructor(public navCtrl: NavController,
public navParams: NavParams,
sanitizer: DomSanitizer) {
this.url = sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/embed/XHCVWWsQmUs');
}
}
Page2.html:
<iframe height="190" onload="this.width=screen.width" [src]="url" frameborder="0" ></iframe>
And add some preferences for configurations:
config.xml:
<allow-navigation href="*://*.youtube.com/*" />
<allow-navigation href="*youtube*" />
<allow-navigation href="*ytimg*" />
<preference name="AllowInlineMediaPlayback" value="true" />
<preference name="MediaPlaybackRequiresUserAction" value="false" />
It works fine on android device but no sound in iOS. I am getting this error in XCode console:
2016-11-08 10:06:10.648528 app[1066:438304] ERROR Internal navigation
rejected - not set for url='about:blank'
Not sure if it is the issue affect the sound.
How can I resolve this? Could it be the bug from Ionic or Cordova?
I see that this is an older post but thought I'd try to revive it to see if anyone else might have a viable solution.
I have a similar issue with embedded YouTube video in an ionic v1 project. Note that I am using the AngularJS module to embed Youtube videos ng-youtube-embed found here:
https://github.com/ArunMichaelDsouza/ng-youtube-embed
Everything works as expected except for the audio on iOS. If the device is toggled to silent mode (with the hardware silent toggle button) the audio is muted. When the ringer is switched back on (hardware toggle) the audio plays back as expected. In researching this issue I keep coming across the that it is a problem with Cordova. That the audio is treated as a UI sound/sound effect and will not playback when the silent switch is on (the ringer off).
The only solution I have come across is half baked at best and have read some posts noting that their app was rejected by Apple because of the hackish solution (a plugin that forces a background audio sound). Otherwise it may be "That's just the way it is". :(

Phonegap Blackberry App Stuck on Splash Screen

I have successfully signed, built and deployed my blackberry app (using phonegap/cordova 2.7.0) to a device. The problem, however, is that it gets stuck on the splash screen. There are no apparent errors from the device logs. I am only targeting OS 7 and below at the moment.
Also, I should mention that I changed the default 'start screen' from index.html to another index page on my server.
Does anybody have an idea what the issue could be?
If you're running the app using a remote source, say from your WAMP/XAMP/MAMP server you need to make sure you've whitelisted that domain in your config.xml like so:
<!-- point to your source code -->
<content src="http://192.168.0.100/index.html"></content>
<!-- whitelist remote ip, and api's needed -->
<access uri="http://192.168.0.100" subdomains="true">
<feature id="blackberry.app"/>
<feature id="blackberry.invoke"/>
<feature id="blackberry.invoke.card"/>
</access>

Resources