I have a webapp and the iOS app built in Swift. The thing is I don't know Swift and I'm trying to modify the iOS app in order to add the authorization key to the PubNub client before subscribing/publishing to channels.
Link to PubNub docs
PRE:
Access Manager is enabled
my_auth_key is hardcoded and already enabled form the server for the corresponding channel I want to subscribe.
Here is the code
What's the correct way to set the auth key?
Thanks in advance
Polak, mentioned docs code snippet refer to previously created instance to get it's pre-configured PNConfiguration instance and change required field. This practice can be used in case if you need change something at run-time.
If you have data for authKey at the moment of client initialization, you can set it:
var pubnubClient: PubNub = {
let configuration = PNConfiguration(publishKey: UCConstants.PubNub.publishKey, subscribeKey: UCConstants.PubNub.subscribeKey)
configuration.authKey = "my_auth_key"
return PubNub.clientWithConfiguration(configuration)
}()
Also, I've tried exact your code and don't have any issues with setting of authKey, because I can see it with subscribe request.
If you still will have troubles with PAM and auth key usage, please contact us on support#pubnub.com
Looks like you can:
let configuration = PNConfiguration(
authKey: "super_secret",
publishKey: UCConstants.PubNub.publishKey,
subscribeKey: UCConstants.PubNub.subscribeKey
)
Based on the Obj-C code: https://github.com/pubnub/objective-c/blob/8c1f0876b5b34176f33681d22844e8d763019635/PubNub/Data/PNConfiguration.m#L174-L181
Related
I'm trying to implement Twilio swift quick start app, anyway I want to configure the app on both platforms iOS and Android,
I reached step 8 in the iOS tutorial
and I have a new PUSH_CREDENTIAL_SID for the iOS from the APN type, while the Android app is from the FCM type already have a PUSH_CREDENTIAL_SID that is being used in the config server file.
$ACCOUNT_SID = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
$API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
$API_KEY_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
$PUSH_CREDENTIAL_SID = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
$APP_SID = 'XXXXXXXXXXXXXXXXXXXXXXXXX';
How can I Add multiple PUSH_CREDENTIAL_SIDs for both apps ? or is there another way to figure this out ?
Thanks in advance
In your code you can have only 1 push_credential_sid.
In order to use the android AND ios at the same time, you should go into your project using this link: https://www.twilio.com/console/notify/services
Create a new service, and you will be able to create a service with the serviceID for android and IOS.
It will provide you a new serviceID to (SID) to use in your backend code.
And it should work for both platform :)
source : https://www.twilio.com/docs/notify/configure-ios-push-notifications#configure-your-twilio-service-to-use-your-apns-credentials
From the backend server, it only can config one push service id in 'PUSH_CREDENTIAL_SID', but if you check the backend code logic, then we can find it just use these information and create a JWT for the APP. So for the accessToken API, APP can pass one more parameter push_sid (the current parameter is identity), backend server will parse this push_sid from the APP request, but do not read from env config any more.
Android will pass the FCM push service id and iOS will pass the APN service id, so one server can support both Android and iOS.
You can control through IF/ELSE logic by passing DEVICE TYPE parameter.
public function createTwilioToken($deviceType = 'ANDROID')
{
$twilioAccountSid = config('app.TWILIO_ACCOUNT_SID');
$twilioApiKey = config('app.TWILIO_API_KEY_SID');
$twilioApiSecret = config('app.TWILIO_API_KEY_SECRET');
$conversationId = config('app.TWILIO_CONVERSATIONS_SERVICE_SID');
$androidPushCredentialSid = config('app.TWILIO_PUSH_ANDROID_CREDENTIAL_SID');
$iosPushCredentialSid = config('app.TWILIO_PUSH_IOS_CREDENTIAL_SID');
// choose a random username for the connecting user
$identity = 'USER-IDENTITY';
// Create access token, which we will serialize and send to the client
$token = new AccessToken(
$twilioAccountSid,
$twilioApiKey,
$twilioApiSecret,
86400,
$identity
);
// Create Chat grant
$grant = new ChatGrant();
$grant->setServiceSid($conversationId);
if ($deviceType == 'IOS')
{
$grant->setPushCredentialSid($iosPushCredentialSid);
}
else if ($deviceType == 'ANDROID')
{
$grant->setPushCredentialSid($androidPushCredentialSid);
}
// Add grant to token
$token->addGrant($grant);
return $token->toJWT();
}
as written in the title is it possible change username of a Amazon Cognito user? I can't find anything in documentation
It is possible to update the preferred_username of a Cognito User using the iOS SDK, using the updateAttributes API call. However, kindly note that you would not be able to modify the username of a user. Quoting the official AWS documentation,
The username value is a separate attribute and not the same as the
name attribute. A username is always required to register a user, and
it cannot be changed after a user is created.
But, the preferred_username value can indeed be changed, and a sample code to change the preferred username using the iOS SDK, as per the official documentation is stated as follows:
AWSCognitoIdentityUserAttributeType * attribute = [AWSCognitoIdentityUserAttributeType new];
attribute.name = #"preferred_username";
attribute.value = #"John User";
[[user updateAttributes:#[attribute]] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserUpdateAttributesResponse *> * _Nonnull task) {
//success
return nil;
}];
I would also like to state that the AWS API documentations for the iOS SDK are rather minimal, and I would recommend developers to go through the SDK source code whenever in doubt.
Just FYI I posted this question originally in the AWS AppSync forum (in case in the future AWS answers it).
I have been trying to make a simple Posts app like the one in the docs but I have found no documentation or guides that handle multiple subscriptions in one view controller.
Three mutations: onCreatePost, onUpdatePost, onDeletePost
(and of course three subscriptions to those mutations)
In Xcode, I have three functions called during viewDidLoad(): subscribeToNewPosts(), subscribeToUpdatedPosts(), subscribeToDeletedPosts()
Each subscription function works and creates a subscription with the correct functionality and updates the table view accordingly if used alone. But, if called one after the other, only the last subscription will actually receive data and update the table view. I put a breakpoint to check out topicSubscribersDictionary in AppSyncMQTTClient.swift after subscribing to all three mutations
func startNewSubscription(subscriptionInfo: AWSSubscriptionInfo) {
var topicQueue = [String]()
let mqttClient = MQTTClient<AnyObject, AnyObject>()
mqttClient.clientDelegate = self
for topic in subscriptionInfo.topics {
if topicSubscribersDictionary[topic] != nil {
// if the client wants subscriptions and is allowed we add it to list of subscribe
topicQueue.append(topic)
}
}
mqttClients.append(mqttClient)
mqttClientsWithTopics[mqttClient] = topicQueue
mqttClient.connect(withClientId: subscriptionInfo.clientId, toHost: subscriptionInfo.url, statusCallback: nil)
}
and all three subscriptions are in fact in the dictionary...
Do I need multiple instances of appSyncClient, one for each subscription? Is it a problem with the schema design?
schema.graphql
schema.json
mutations.graphql
queries.graphql
subscriptions.graphql
Example use case: simple chat app. New conversation started = OnCreatePostSubscription; new incoming message in that conversation = OnUpdatePostSubscription
Are you using API Key for authorization in AppSync? If you are using API Key only one subscription is supported by the SDK at this point. Could you switch to IAM (Cognito Identity) or Cognito UserPools based auth and see if multiple subscriptions work for you?
I managed to have several subscriptions working with API Key by replacing the call startSubscriptions to startNewSubscription inside AWSAppSyncSubscriptionWatcher
if let subscriptionInfo = subscriptionResult.subscrptionInfo {
self.subscriptionTopic = subscriptionResult.newTopics
self.client?.addWatcher(watcher: self, topics: subscriptionResult.newTopics!, identifier: self.uniqueIdentifier)
//self.client?.startSubscriptions(subscriptionInfo: subscriptionInfo)
subscriptionInfo.forEach { self.client?.startNewSubscription(subscriptionInfo: $0) }
}
Couldn't find any side effect with this approach yet, apart from requiring to fork the iOS SKD
I have a very simple question, I have a node.js/express server that will handle backend authentication part, it is using token not cookies, the server part is working correctly, whenever someone register/login it would return with a JSON web token.
For example:
{
"token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdW"
}
I'm using Alamofire to handle the HTTP request from iOS itself. The real question lies is how do I persist the token in the iOS/Swift itself?
What is the simplest way to do this?
You should use the iOS Keychain to save sensitive information.
You should not use NSUserDefaults to store an authentication token or any other potentially sensitive information. It's unencrypted and easily accessible on a rooted device.
How would you like someone getting your authentication token and making requests to your private API at will (e.g. on the command line using curl)?
I've used the KeychainAccess CocoaPod and its usage is simple:
static let keychain = Keychain(service: "com.example.myapp")
keychain["secret_code"] = secretCode // Save something
let secretCode = keychain["secret_code"] // Retrieve something
The simplest way is to store it in NSUserDefaults like this:
Writing:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Your Variable Value", forKey: "token")
Reading:
let defaults = NSUserDefaults.standardUserDefaults()
if let token = defaults.stringForKey("token") {
print(name)
}
The simplest way may be NSUserDefaults, but the most secure way would be to store the token in the iOS Keychain. Note there are several wrapper libraries (for example) available to make working with the keychain easier in Swift. The API can be a bit intimidating at times.
I'm having a play with the PayPal iOS SDK App which I downloaded from https://github.com/paypal/PayPal-iOS-SDK an it works beautifully in sandbox mode BUT I cannot find any property to set for the merchant email address. This is mind boggling to me, as the 'money' has to be sent to the merchant. So the question is, how is this even working?
I'm sure I'm overlooking something. Excuse the stupid question so bear with me.
Cheers.
Using the iOS SDK, the place for this information is in the PayPalConfiguration object -- it is passed as a parameter for all the PayPal provided view controllers.
So for example, in the PayPal demo app:
// Xcode 8.1, Swift 3.0
//MainViewController
//yadda yadda...
var payPalConfig = PayPalConfiguration()
// etc. etc.
override func viewDidLoad() {
super.viewDidLoad()
// Some other stuff
// Set up payPalConfig
payPalConfig.acceptCreditCards = false
payPalConfig.merchantName = "Awesome Shirts, Inc."
payPalConfig.merchantPrivacyPolicyURL = URL(string: "https://www.paypal.com/webapps/mpp/ua/privacy-full")
payPalConfig.merchantUserAgreementURL = URL(string: "https://www.paypal.com/webapps/mpp/ua/useragreement-full")
// blah blah blah
}
This config object is later passed in as:
PayPalPaymentViewController(payment: payment, configuration: payPalConfig, delegate: self)
EDIT: Correction - you're right, there is no property for the merchant's email address, even in the PayPalConfiguration object, just the merchant's name, and merchant's privacy/EULA urls.
However, it should not boggle the mind, as it were, since the merchant has a PayPal [Merchant/Business] account which will receive the money (and they certainly have the merchant's email address), and the merchant needn't expose an email address. The receiver, on the other hand, might not have a PayPal account (yet), so there are properties for the receiver's email address -- e.g., the defaultUserEmail in the configuration object, or the payeeEmail property of the PayPalPayment object (docs).
In IOS SDK, you need to update two files to reflect the environment and merchant client id.
A. ZZAppDelegate.m File
[PayPalMobile initializeWithClientIdsForEnvironments:#{PayPalEnvironmentProduction : #"YOUR_CLIENT_ID_FOR_PRODUCTION",PayPalEnvironmentSandbox : #"YOUR_CLIENT_ID_FOR_SANDBOX"}];
B. ZZMainViewController.m File
define kPayPalEnvironment PayPalEnvironmentNoNetwork
In IOS SDK, you don't need to input merchant's email address, you need to apply one client id in REST APP:https://developer.paypal.com/developer/applications, then place this clent id in above file.