What does this mean: +[UAirship executeUnsafeTakeOff:]? - ios

I am trying to setup push notifications using Urban Airship and I believe I'm having a problem with the provisioning profiles or ssl certificates. The app is not prompting the user for Push Notifications permissions but I am not getting a 'no valid "aps-environment" entitlement string found for application' message, and I can see the aps-environment entitlement in the .mobileprovision.
I can't find any documentation on +[UAirship executeUnsafeTakeOff:] so I am wondering if anyone knows what that could mean?
Also, the device token is being returned as nil, as logged by Urban Airship:
[D] -[UAPush updateRegistrationForcefully:] [Line 544] Device token is
nil. Registration will be attempted at a later time
There is no Urban Airship code running prior to the [UAirship takeOff:config] call, and the app does not crash as a result of the error.

Without knowing much about Urban Airship I can offer a guess.
takeOff ensures that the actual implementation provided in executeUnsafeTakeoff only happens once. It makes sure that the current thread is the main thread and then ensures that it only happens once.
Therefore getting an executeUnsafeTakeoff error really only tells you that something went wrong, such as if the configfailed tovalidate` (see below).
You need to make sure that the app can receive push notifications, as you mentioned.
Here is takeOff:
+ (void)takeOff {
[UAirship takeOff:[UAConfig defaultConfig]];
}
+ (void)takeOff:(UAConfig *)config {
// takeOff needs to be run on the main thread
if (![[NSThread currentThread] isMainThread]) {
NSException *mainThreadException = [NSException exceptionWithName:UAirshipTakeOffBackgroundThreadException
reason:#"UAirship takeOff must be called on the main thread."
userInfo:nil];
[mainThreadException raise];
}
dispatch_once(&takeOffPred_, ^{
[UAirship executeUnsafeTakeOff:config];
});
}
Here is executeUnsafeTakeoff:
/*
* This is an unsafe version of takeOff - use takeOff: instead for dispatch_once
*/
+ (void)executeUnsafeTakeOff:(UAConfig *)config {
// Airships only take off once!
if (_sharedAirship) {
return;
}
[UAirship setLogLevel:config.logLevel];
_sharedAirship = [[UAirship alloc] init];
_sharedAirship.config = config;
// Ensure that app credentials have been passed in
if (![config validate]) {
UA_LERR(#"The AirshipConfig.plist file is missing and no application credentials were specified at runtime.");
// Bail now. Don't continue the takeOff sequence.
return;
}
UA_LINFO(#"App Key: %#", _sharedAirship.config.appKey);
UA_LINFO(#"App Secret: %#", _sharedAirship.config.appSecret);
UA_LINFO(#"Server: %#", _sharedAirship.config.deviceAPIURL);
if (config.automaticSetupEnabled) {
_sharedAirship.appDelegate = [[UAAppDelegateProxy alloc ]init];
//swap pointers with the initial app delegate
#synchronized ([UIApplication sharedApplication]) {
_sharedAirship.appDelegate.originalAppDelegate = [UIApplication sharedApplication].delegate;
_sharedAirship.appDelegate.airshipAppDelegate = [[UAAppDelegate alloc] init];
[UIApplication sharedApplication].delegate = _sharedAirship.appDelegate;
}
}
// Build a custom user agent with the app key and name
[_sharedAirship configureUserAgent];
// Set up analytics
_sharedAirship.analytics = [[UAAnalytics alloc] initWithConfig:_sharedAirship.config];
[_sharedAirship.analytics delayNextSend:UAAnalyticsFirstBatchUploadInterval];
/*
* Handle Debug Options
*/
//For testing, set this value in AirshipConfig to clear out
//the keychain credentials, as they will otherwise be persisted
//even when the application is uninstalled.
if (config.clearKeychain) {
UA_LDEBUG(#"Deleting the keychain credentials");
[UAKeychainUtils deleteKeychainValue:_sharedAirship.config.appKey];
UA_LDEBUG(#"Deleting the UA device ID");
[UAKeychainUtils deleteKeychainValue:kUAKeychainDeviceIDKey];
}
if (!config.inProduction) {
[_sharedAirship validate];
}
if (config.cacheDiskSizeInMB > 0) {
UA_LINFO("Registering UAURLProtocol");
[NSURLProtocol registerClass:[UAURLProtocol class]];
}
// The singleton is now ready for use!
_sharedAirship.ready = true;
//create/setup user (begin listening for device token changes)
[[UAUser defaultUser] initializeUser];
}

Related

React Native CallKeep isCallActive using CXCallObserver

I am using https://github.com/react-native-webrtc/react-native-callkeep to implement a VOIP app in React Native.
It has a built in method for checking if a Call is going by passing the uuid to method isCallActive, it didn't work correctly for me so i have implement my own native module to check using the same code with promise:
RCT_EXPORT_METHOD(isCallActive:
(NSString *)uuidString
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
CXCallObserver *callObserver = [[CXCallObserver alloc] init];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString];
BOOL _mybool = false;
for(CXCall *call in callObserver.calls){
NSLog(#"[RNCallKeep] isCallActive %# %d ?", call.UUID, [call.UUID isEqual:uuid]);
if([call.UUID isEqual:[[NSUUID alloc] initWithUUIDString:uuidString]] && !call.hasConnected){
_mybool = true;
resolve(#"true");
}
}
if(!_mybool){
reject(false, false, false);
}
}
The code is working and I am able to access it like this:
NativeModules?.CallManager?.isCallActive(uuid)
.then((value) => {
console.log('isCallActive then', value);
})
.catch((error) => {
console.log('isCallActive catch', error);
});
Now the problem here is that, if I receive a call, it displays CallKit UI then in my console i see it resolves the promise quickly even though i haven't accepted call yet and its ringing in the phone. I am unable to understand why is this happening.
EDIT:
How does hasConnected work? Even though i have accepted the call it always returns false? If I wait for my app to start completely behind callKit UI and then accept the call, it gives me true for hasConnected and I am assuming because the Twilio audio session is started at that point. But if i accept call early, i don't get true for hasConnected because audio session was not started. Is my understanding correct?

Unity3D iOS device token is always null

I am trying to get push notifications to work on iOS, but I can not get access to the device token!
My Unity version is 5.4.1f1.
I have enabled the Push Notifications capability in XCode and all the certificates are setup correctly:
In my script in the start method I call this:
UnityEngine.iOS.NotificationServices.RegisterForNotifications
(UnityEngine.iOS.NotificationType.Alert | UnityEngine.iOS.NotificationType.Badge
| UnityEngine.iOS.NotificationType.Sound, true);
Then from the update method I call this method:
private bool RegisterTokenWithPlayfab( System.Action successCallback,
System.Action<PlayFabError> errorCallback )
{
byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;
if(token != null)
{
// Registration on backend
}
else
{
string errorDescription = UnityEngine.iOS.NotificationServices.registrationError;
Debug.Log( "Push Notifications Registration failed with: " + errorDescription );
return false;
}
}
The token keeps being empty, so the else-branch is entered every call. Also, the registrationError keeps being empty.
Can someone point me in the right direction on this? What else can I try or how can I get more infos on what is going wrong??
Try this one
Go to your application target. Choose Capabilities and ensure that ‘Push Notifications’ is enabled there.
You need to check deviceToken in a Coroutine or Update.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using NotificationServices = UnityEngine.iOS.NotificationServices;
using NotificationType = UnityEngine.iOS.NotificationType;
public class NotificationRegistrationExample : MonoBehaviour
{
bool tokenSent;
void Start()
{
tokenSent = false;
NotificationServices.RegisterForNotifications(
NotificationType.Alert |
NotificationType.Badge |
NotificationType.Sound, true);
}
void Update()
{
if (!tokenSent)
{
byte[] token = NotificationServices.deviceToken;
if (token != null)
{
// send token to a provider
string token = System.BitConverter.ToString(token).Replace('-', '%');
Debug.Log(token)
tokenSent = true;
}
}
}
}
The implementation is horrible, but we don't have callbacks from Unity side so we need to keep listening that variable value.
Check the documentation:
https://docs.unity3d.com/ScriptReference/iOS.NotificationServices.RegisterForNotifications.html
Also seems to need internet. I guess there is an Apple service going on there.
Yes, registration error is empty even when user deniy permissions.
What i did is to use UniRX and set an Observable fron a Coroutine with a time out so it dont keep forever asking for it.
If you accepted and you do not received the token might be the internet conection. And i guess you are teying this on a real device.

Paypal sandbox account deduction not reflecting in account objective c

I am new to paypal integration with objective c.
Created the sanbox (buyer account) which have balance approx 100$
Had download code from : https://github.com/paypal/PayPal-iOS-SDK/tree/master/SampleApp/PayPal-iOS-SDK-Sample-App
ZZAppDelegate.m
[PayPalMobile initializeWithClientIdsForEnvironments:#{ PayPalEnvironmentSandbox : #"XXXXXXX"}];
Execute the project and able to login with buyer account credential.
Click buy button. console show paid successful :
Here is your proof of payment:
{
client =
{
environment = mock;
"paypal_sdk_version" = "2.16.3";
platform = iOS;
"product_name" = "PayPal iOS SDK";
};
response = {
"create_time" = "2017-04-05T05:49:16Z";
id = "PAY-NONETWORKPAYIDEXAMPLE123";
intent = sale;
state = approved;
};
"response_type" = payment;
}
But the problem is : I am not able to see this activity in my sandbox account on browser.
Do we need to add project APPID in sandbox account if yes ? Where do we need to do it?**
APPID :- means apple id (apple bundle identifier) ?
Or there is some different APPID ?
Please help me if there is any steps need to be integrated
If you have added PalPalSDK in application. You have to choose between Sandbox or Production. You have to create AppID for Palpal. You can check there it has sample code also available.
If Payment get successful it has delegate method where we can view with Payment successful.
- (void)sendCompletedPaymentToServer:(PayPalPayment *)completedPayment {
// TODO: Send completedPayment.confirmation to server
NSLog(#"Here is your proof of payment:\n\n%#\n\nSend this to your server for confirmation and fulfillment.", completedPayment.confirmation);
}
here you can get all the data after paypal payment
- (void)payPalPaymentViewController:(PayPalPaymentViewController *)paymentViewController didCompletePayment:(PayPalPayment *)completedPayment
{
NSLog(#"PayPal Payment Success!");
self.resultText = [completedPayment description];
[self sendCompletedPaymentToServer:completedPayment]; // Payment was processed successfully; send to server for verification and fulfillment
[self dismissViewControllerAnimated:YES completion:nil];
}

Communication between Tweak and Preference Bundle

I have some data saved with preference bundle controller class. I want to share it with its tweak file i.e. I want springboard to be able to communicate preference bundle in order to get some data from it and vice versa. I have tried to use Libobjcipc - as written in its documentation:
libobjcipc is a developer library that provides an inter-process communication (between app and SpringBoard) solution for jailbroken iOS. It handles the socket connections between SpringBoard and app processes...
I have tried to send message from tweak, but unable to figure it out how to receive incoming message in my preference bundle controller. I know the method [OBJCIPC registerIncomingMessageFromSpringBoardHandlerForMessageName:handler:] will be used for this purpose. But where do I use it? Hope for some positive response... Thanks..
EDIT:
I have tried using CFNotificationCenter after suggestion of #creker. I can send notification, but my tweak cannot receive it, and so callback method callBackNotification isn't executed. Here is changed code:
Tweak.xm
//at the end of tweak file
static void callBackNotification(CFNotificationCenterRef center,void *observer,CFStringRef name,const void *object,CFDictionaryRef userInfo)
{
NSLog(#"Notification received!");
}
%ctor
{
NSLog(#"Init cqlled!"); //this piece of code called successfully
//Register for the change notification
CFNotificationCenterRef r = CFNotificationCenterGetDarwinNotifyCenter();
CFNotificationCenterAddObserver(r, NULL, reloadPrefsNotification, CFSTR("ccom.identifier.message"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
}
Preference Bundle Controller
#interface SettingsListController: PSListController {
}
#end
#implementation SettingsListController
- (id)specifiers {
if(_specifiers == nil) {
_specifiers = [[self loadSpecifiersFromPlistName:#"JRLockerSettings" target:self] retain];
}
return _specifiers;
}
-(void) postNotification()
{
CFNotificationCenterRef center = CFNotificationCenterGetLocalCenter();
// post a notification
CFDictionaryKeyCallBacks keyCallbacks = {0, NULL, NULL, CFCopyDescription, CFEqual, NULL};
CFDictionaryValueCallBacks valueCallbacks = {0, NULL, NULL, CFCopyDescription, CFEqual};
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
&keyCallbacks, &valueCallbacks);
CFDictionaryAddValue(dictionary, CFSTR("identifier"), CFSTR("value"));
CFNotificationCenterPostNotification(center, CFSTR("com.identifier.message"), NULL, dictionary, TRUE);
CFRelease(dictionary);
}
#end

Unable to send iOS MDM Push Notification using Push Sharp

I am attempting to send the an MDM push notification to an iPad using the production APN server. However, Push Sharp says that the notification failed because the identifier is equal to 1. The following code from the PushSharp code base illustrates how it comes to that conclusion...
//We now expect apple to close the connection on us anyway, so let's try and close things
// up here as well to get a head start
//Hopefully this way we have less messages written to the stream that we have to requeue
try { stream.Close(); stream.Dispose(); }
catch { }
//Get the enhanced format response
// byte 0 is always '1', byte 1 is the status, bytes 2,3,4,5 are the identifier of the notification
var identifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(readBuffer, 2));
int failedNotificationIndex = -1;
SentNotification failedNotification = null;
//Try and find the failed notification in our sent list
for (int i = 0; i < sentNotifications.Count; i++)
{
var n = sentNotifications[i];
if (n.Identifier.Equals(identifier))
{
failedNotificationIndex = i;
failedNotification = n;
break;
}
}
Basically, after the writing the payload to the stream, it attempts to close the connection, during which it expects a response from the APN service, which I think it refers to as the notification identifier.
I have plugged the device into the iPhone Device Configuration utility, but nothing appears in the console, hence I assume that it never receives this notification.
My questions are...
What is this identifier that it is expecting ?
Is there anything that I am doing wrong ?
The device is running iOS 6. The structure of the payload is as follows...
{"aps":{},"mdm":"80369651-5802-40A2-A0AE-FCCF02F99589"}
The values in the returned byte[] of 6 bytes are as follows 8,8,0,0,0,1
No idea, I've never looked into the details how PushSharp deals with the APNS internals.
You shouldn't send the "aps":{} part in the notification payload, so maybe that's the reason the APNS fails the notification.
I'm sucessfully using PushSharp 1.0.17 with the following code for MDM notifications, so it definitely works in general.
var pushService = new PushService();
// attach event listeners
// override the production/development auto-detection as it doesn't
// work for MDM certificates
var cert = null; // load your push client certificate
var channel = new ApplePushChannelSettings(true, cert, true);
pushService.StartApplePushService(channel);
// create and send the notification
var notification = NotificationFactory
.Apple()
.ForDeviceToken("your-device-token-received-from-checkin")
.WithExpiry(DateTime.UtcNow.AddDays(1))
.WithCustomItem("mdm", "your-push-magic-received-in-checkin");
pushService.QueueNotification(notification);
For PushSharp v3.0+, you should be able to include directly in the Payload of the ApnsNotification.
public void SendIosMdm(string deviceToken, string pushMagic)
{
_apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = deviceToken,
Payload = JObject.FromObject(new {
mdm = pushMagic
})
});
}

Resources