AMAZON AWS How do i subscribe an endpoint to SNS topic? - ios

I'm implementing push notifications in an iOS app using Amazon SNS and Amazon Cognito services.
Cognito saves tokens successfully, my app gets notified, everything's working well, but there is a thing.
Now, when still in development, I need to manually add endpoints to an SNS topic, so all subscribers can get notifications. When i'll push an update to the App Store, there will be thousands of tokens to add.
I was studying Amazon AWS documentation, but there was no clue whether it's possible to make it happen without that additional effort.
My question: is it possible to automatically subscribe an endpoint to a topic with Amazon services only?

There is no way to automatically subscribe an endpoint to a topic, but you can accomplish all through code.
You can directly call the Subscribe API after you have created your endpoint. Unlike other kinds of subscription, no confirmation is necessary with SNS Mobile Push.
Here is some example Objective-C code that creates an endpoint and subscribes it to a topic:
AWSSNS *sns = [AWSSNS defaultSNS];
AWSSNSCreatePlatformEndpointInput *endpointRequest = [AWSSNSCreatePlatformEndpointInput new];
endpointRequest.platformApplicationArn = MY_PLATFORM_ARN;
endpointRequest.token = MY_TOKEN;
[[[sns createPlatformEndpoint:endpointRequest] continueWithSuccessBlock:^id(AWSTask *task) {
AWSSNSCreateEndpointResponse *response = task.result;
AWSSNSSubscribeInput *subscribeRequest = [AWSSNSSubscribeInput new];
subscribeRequest.endpoint = response.endpointArn;
subscribeRequest.protocols = #"application";
subscribeRequest.topicArn = MY_TOPIC_ARN;
return [sns subscribe:subscribeRequest];
}] continueWithBlock:^id(BFTask *task) {
if (task.cancelled) {
NSLog(#"Task cancelled");
}
else if (task.error) {
NSLog(#"Error occurred: [%#]", task.error);
}
else {
NSLog(#"Success");
}
return nil;
}];
Make sure you have granted access to sns:Subscribe in your Cognito roles to allow your application to make this call.
Update 2015-07-08: Updated to reflect AWS iOS SDK 2.2.0+

This is the original code to subscribe an endpoint to a topic in Swift3
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//Get Token ENDPOINT
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
//Create SNS Module
let sns = AWSSNS.default()
let request = AWSSNSCreatePlatformEndpointInput()
request?.token = deviceTokenString
//Send Request
request?.platformApplicationArn = Constants.SNSDEVApplicationARN
sns.createPlatformEndpoint(request!).continue({ (task: AWSTask!) -> AnyObject! in
if task.error != nil {
print("Error: \(task.error)")
} else {
let createEndpointResponse = task.result! as AWSSNSCreateEndpointResponse
print("endpointArn: \(createEndpointResponse.endpointArn)")
let subscription = Constants.SNSEndPoint //Use your own topic endpoint
//Create Subscription request
let subscriptionRequest = AWSSNSSubscribeInput()
subscriptionRequest?.protocols = "application"
subscriptionRequest?.topicArn = subscription
subscriptionRequest?.endpoint = createEndpointResponse.endpointArn
sns.subscribe(subscriptionRequest!).continue ({
(task:AWSTask) -> AnyObject! in
if task.error != nil
{
print("Error subscribing: \(task.error)")
return nil
}
print("Subscribed succesfully")
//Confirm subscription
let subscriptionConfirmInput = AWSSNSConfirmSubscriptionInput()
subscriptionConfirmInput?.token = createEndpointResponse.endpointArn
subscriptionConfirmInput?.topicArn = subscription
sns.confirmSubscription(subscriptionConfirmInput!).continue ({
(task:AWSTask) -> AnyObject! in
if task.error != nil
{
print("Error subscribing: \(task.error)")
}
return nil
})
return nil
})
}
return nil
})
}

If you want to use static credentials instead of using AWSCognito you will need to create those through Amazons IAM console.
Here is the code for initializing the Amazon in your App Delegate
// Sets up the AWS Mobile SDK for iOS
// Initialize the Amazon credentials provider
AWSStaticCredentialsProvider *credentialsProvider =[[AWSStaticCredentialsProvider alloc] initWithAccessKey:AWSAccessID secretKey:AWSSecretKey];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:DefaultServiceRegionType credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
Fissh

Related

swift:receive AWS id_token after sending facebook current token to AWS Cognito?

I want to send the facebook access token to the AWS Cognito and then receive an authorization token which can further be sent as an Authorization header in HTTP Put request.
However, I always get "unauthorized" response from the AWS end point.
When I try to print :
credentialsProvider.credentials().continueOnSuccessWith(executor: AWSExecutor.default()) { (task) -> Any? in
print(task.error)
return true
}
I get the following output:
Optional(Error Domain=com.amazonaws.AWSJSONBuilderErrorDomain Code=4 "serialized object is neither a valid json Object nor NSData object: {
IdentityPoolId = "******";
Logins = {
"graph.facebook.com" = "<FBSDKAccessToken: *******>";
};
}" UserInfo={NSLocalizedDescription=serialized object is neither a valid json Object nor NSData object: {
IdentityPoolId = "*****+*";
Logins = {
"graph.facebook.com" = "<FBSDKAccessToken: ******>";
};
}})
This is my code:
import AWSCognito
class FacebookProvider: NSObject, AWSIdentityProviderManager {
func logins() -> AWSTask<NSDictionary> {
if let token = FBSDKAccessToken.current() {
return AWSTask(result: [AWSIdentityProviderFacebook:token])
}
return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
}
}
class API {
..............
public func putOrder(when fbLogin: Bool, _ order: Order, onSuccess: #escaping(JSON) -> Void,
on Failure: #escaping(Error)-> Void) {
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .EUCentral1 ,
identityPoolId:"*****", identityProviderManager:FacebookProvider())
let configuration = AWSServiceConfiguration(region: AWSRegionType.EUCentral1, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let url = "\(serverURL)\(API.loginOrderPath)"
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: NSURL(string: url)! as URL)
urlRequest.httpMethod = API.apiMethodPut
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("\(credentialsProvider.credentials())", forHTTPHeaderField: "Authorization")
do {
var json: JSON
json = ["companyId": order.companyId, "drinks": order.drinksId, "payment": order.payment, "tip": order.tip]
urlRequest.httpBody = try json.rawData()
let task = URLSession.shared.dataTask(with: urlRequest as URLRequest, completionHandler: {data, response, error -> Void in
if error != nil {
Failure(error!)
} else {
if let response = try? JSON(data: data!) {
onSuccess(response)
} else {
}
}
})
task.resume()
} catch _ {
}
}
}
Expected Result: JSON response from the AWS Server
Actual Result : unauthorised
The reason why your are receiving an unauthorized response from API Gateway is double :
credentialsProvider.credentials() is not serialized to JSON and can not be "as is" for the authorization headers.
Looks like you are trying to manually call API Gateway, by managing your self the low level details of the URL Request. I don't see code to add a signature to the request. All authenticated API Gateway requests must be signed (see https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/) and the Authorization header must contain the credentials used to compute the signature.
Managing the low level details of AWS Signature is not trivial. You should not write code to do that but use the AWS iOS SDK instead. In particular, if you're trying to call API Gateway with Cognito User Pool authorisation, have a look at this example : https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk-ios-swift.html.
The API Gateway console will generate the client side code required to run this example (see https://docs.aws.amazon.com/apigateway/latest/developerguide/genearte-ios-sdk-of-an-api.html)
This should remove a lot of boiler plate from your code, making it easier to read and to maintain.
The flow posted in your comment above, the iOS SDK will take care of 2/ 3/ and 4/ steps for you - automatically.

AWS Cognito User Pool + Facebook Login iOS

I have started integrating AWS Cognito User Pools into my app and the signup + login works (I have followed this tutorial: https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-integrating-user-pools-ios.html)
Now I'm struggling to properly integrate a Facebook login. This is what I do:
After the user has successfully signed in with facebook (using the facebook SDK), I'm getting the token and calling this function:
func signInFacebook(){
let customProviderManager = CustomIdentityProvider(tokens: nil)
self.credentialsProvider = AWSCognitoCredentialsProvider(
regionType:CognitoIdentityUserPoolRegion,
identityPoolId: CognitoIdentityPoolId,
identityProviderManager: customProviderManager)
let configuration = AWSServiceConfiguration(region:CognitoIdentityUserPoolRegion, credentialsProvider: self.credentialsProvider!)
AWSServiceManager.default().defaultServiceConfiguration = configuration
}
My CustomIdentityProvider class looks like this:
class CustomIdentityProvider: NSObject, AWSIdentityProviderManager {
var tokens : NSDictionary?
init(tokens: NSDictionary?) {
self.tokens = tokens
}
func logins() -> AWSTask<NSDictionary> {
if let fbToken = AccessToken.current?.authenticationToken {
return AWSTask(result: [AWSIdentityProviderFacebook: fbToken])
} else if let googleToken = GIDSignIn.sharedInstance().currentUser.authentication.idToken {
return AWSTask(result: [AWSIdentityProviderGoogle: googleToken])
}
return AWSTask(error:NSError(domain: "Social login", code: -1 , userInfo: ["Social login" : "No current social access token"]))
}
}
After signInFacebook() is called, I also call
self.credentialsProvider?.credentials().continueOnSuccessWith { (task:AWSTask<AWSCredentials>) -> Any? in
print("credentials: \(task.result!)")
return nil
}
and it prints some data in the log which looks fine.
But for some reason it doesn't seem to link properly everything together.
When I'm calling my backend to fetch some data, I usually do it like this:
I call self.user?.getSession().continueOnSuccessWith (user is an instance of AWSCognitoIdentityUser) and inside the closure I build the request where I put the token in the header. But if there are no tokens, the SDK shows my login screen. And this is what happens all the time. I would expect the user object to be updated with the correct tokens after the social login with Facebook has succeeded. What am I doing wrong?

Passing LWA token to Cognito

I am working a an app which uses the Alexa Voice Service and maintains different users, so the users needs to login with Amazon (LWA). I have implemented it like it is written in the docs and it works flawlessly.
LWA docs: https://developer.amazon.com/de/docs/login-with-amazon/use-sdk-ios.html
AMZNAuthorizationManager.shared().authorize(request, withHandler: {(result : AMZNAuthorizeResult?, userDidCancel : Bool, error : Error?) -> () in
if error != nil {
// Handle errors from the SDK or authorization server.
}
else if userDidCancel {
// Handle errors caused when user cancels login.
}
else {
// Authentication was successful.
// Obtain the access token and user profile data.
self.accessToken = result!.token
self.user = result!.user!
}
})
Furthermore I need to retrieve information from DynamoDB, which uses Cognito for authentification. As stated in the docs, there should be a way pass the access token form LWA to Cognito, but I can't find the proper place to do it. They say LWA provides an AMZNAccessTokenDelegate, which it does not. The delegate method provides an API result which Cognito needs. The link in the Cognito docs below refers to the same exact link from the LWA docs I posted above.
Cognito docs: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon.html
func requestDidSucceed(apiResult: APIResult!) {
if apiResult.api == API.AuthorizeUser {
AIMobileLib.getAccessTokenForScopes(["profile"], withOverrideParams: nil, delegate: self)
} else if apiResult.api == API.GetAccessToken {
credentialsProvider.logins = [AWSCognitoLoginProviderKey.LoginWithAmazon.rawValue: apiResult.result]
}
}
What am I missing?
[EDIT]
I crawled through the LWA sources today until I finally found the correct delegate method.
Use AIAuthenticationDelegate instead of AMZNAccessTokenDelegate
But that lets me sit in front of the next two problems:
I.
Value of type 'AWSCognitoCredentialsProvider' has no member 'logins'
Maybe I have to use the following?
.setValue([AWSCognitoLoginProviderKey.LoginWithAmazon.rawValue: apiResult.result], forKey: "logins")
II.
Use of unresolved identifier 'AWSCognitoLoginProviderKey'
What do I put here? Maybe the API key I got from LWA?
[EDIT2]
I wanted to try it out, but requestDidSucceed never gets called, even through I successfully logged in.
class CustomIdentityProvider: NSObject, AWSIdentityProviderManager {
func logins() -> AWSTask<NSDictionary> {
return AWSTask(result: loginTokens)
}
var loginTokens : NSDictionary
init(tokens: [String : String]) {
self.loginTokens = tokens as NSDictionary
}
}
in the Authorization code at this below in successsful
AMZNAuthorizationManager.shared().authorize(request) { (result, userDidCancel, error) in
if ((error) != nil) {
// Handle errors from the SDK or authorization server.
} else if (userDidCancel) {
// Handle errors caused when user cancels login.
} else {
let logins = [IdentityProvider.amazon.rawValue: result!.token]
let customProviderManager = CustomIdentityProvider(tokens: logins)
guard let apiGatewayEndpoint = AWSEndpoint(url: URL(string: "APIGATEWAYURL")) else {
fatalError("Error creating API Gateway endpoint url")
}
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USWest2, identityPoolId: "IDENTITY_ID", identityProviderManager:customProviderManager)
let configuration = AWSServiceConfiguration(region: .USWest2, endpoint: apiGatewayEndpoint, credentialsProvider: credentialsProvider)
}

Using amazon AWS SNS service IOS

I am developing an app which uses amazon aws service and it is a messenger.
I would like to use IOS Push Notification service and the amazon SNS to achieve the communication between 2 users. I am able to send message from the SNS console by publishing a message to the destination called endpoint.
However, i am not able to send message from one mobile to another mobile by amazon SDK of IOS. Can i do it in that way by the API of Amazon?
I want to send the NSDictionary called messageDict to the destination endPoint. Can i achieve this without the use of server??
NSDictionary *messageDict = [[NSDictionary alloc]init];
messageDict = #{ #"Name" : #"HelloWrold" ,#"Id" :#"GoodBye",};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:messageDict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"Jsonstring %#",jsonString);
AWSSNS *publishCall = [AWSSNS new];
AWSSNSPublishInput *message = [AWSSNSPublishInput new];
message.subject = #"My First Message";
//This is the ending point
message.topicArn = #"arn:aws:sns:us-east-1:012345678912:endpoint/APNS_SANDBOX/appTesting/201sjad-XXXX-XXXX-XXXX-c34sdfdsf1d9c";
message.messageAttributes = messageDict;
message.messageStructure = jsonString;
[[publishCall publish:message]continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task){
if (task.error != nil) {
NSLog(#"Error %#",task.error);
}
else{
NSLog(#"Successful");
}
return nil;
}];
The hardest thing about sending an APN with SNS is getting the data structure correct. Here is how you you can publish to a topic using swift. Each platform needs to be an encoded string, if you mess this up SNS will only deliver your default message.
func publishPush() {
let sns = AWSSNS.defaultSNS()
let request = AWSSNSPublishInput()
request.messageStructure = "json"
var aps: NSMutableDictionary = NSMutableDictionary()
var dict = ["default": "The default message", "APNS_SANDBOX": "{\"aps\":{\"alert\": \"YOUR_MESSAGE\",\"sound\":\"default\", \"badge\":\"1\"} }"]
let jsonData = NSJSONSerialization.dataWithJSONObject(dict, options: nil, error: nil)
request.message = NSString(data: jsonData!, encoding: NSUTF8StringEncoding) as! String
request.targetArn = "blahblahblah:MyTopic"
sns.publish(request).continueWithBlock { (task) -> AnyObject! in
println("error \(task.error), result:; \(task.result)")
return nil
}
}
You can either send a push notification to a specific device (endpoint) or to a topic (list of multiple subscribers)
The API call is slightly different for both. Either you use message.topicArn or message.targetArn as describe in the API documentation here
http://docs.aws.amazon.com/sns/latest/api/API_Publish.html
(Objective-C class documentation is here : http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSSNSPublishInput.html)
Your ARN is an Endpoint ARN and your code assigns it to message.topicArn
I would change it to
message.targetArn = #"arn:aws:sns:us-east-1:123456789012:endpoint/APNS_SANDBOX/appTesting/201sjad-XXXX-XXXXXX-XXXX-c34sdfdsf1d9c";
(ARN edited to obfuscate your Account ID)
Also, please read and apply best practice from http://mobile.awsblog.com/post/Tx223MJB0XKV9RU/Mobile-token-management-with-Amazon-SNS to acquire and manage your device token.
Here is a code sample in Javascript, that you easily adapt to Objective-C.
var DEFAULT_SNS_REGION = 'eu-west-1';
var SNS_ENDPOINT_ARN = 'arn:aws:sns:eu-west-1:0123456789012:endpoint/APNS_SANDBOX/AmazonSNSPushDemo/95084b8f-XXXX-XXXX-XXXX-b3429d0fa528';
var SNS_TOPIC_ARN = 'arn:aws:sns:eu-west-1:012345678912:PushNotifications';
function sendNotification(msg, topicARN, endPointARN) {
var sns = new aws.SNS({
apiVersion: '2010-03-31',
region: DEFAULT_SNS_REGION
});
var params = {}
if (topicARN != '') {
params = {
Message: msg,
//MessageStructure: 'json',
TopicArn: topicARN
};
} else {
params = {
Message: msg,
//MessageStructure: 'json',
TargetArn: endPointARN
};
}
console.log(params);
var deferred = Q.defer();
sns.publish(params, function(err,data) {
if (err) {
console.log(err, err.stack); // an error occurred
deferred.reject(err);
} else {
console.log(data); // successful response
deferred.resolve(data);
}
});
return deferred.promise; }
The AWSSNS instance is not correctly instantiated.
AWSSNS *publishCall = [AWSSNS new];
needs to be changed to
AWSSNS *publishCall = [AWSSNS defaultSNS];
In general, however, I do not recommend sending push notifications from the client devices because anyone can grab the temporary credentials from the mobile device and spam your app users. Amazon SNS currently does not support fine-grain access control nor throttling the excessive send requests.
The better solution from the security point of view is to have a push notification server. You can take a look at some of the services that may help:
AWS Lambda
AWS Elastic Beanstalk

How to get user email address via Twitter API in iOS?

I have tried multiple SDK's but was unable to get an email ID from any of the resources. I have tried FHSTwitterEngine for this purpose but I didn't get the solution.
FHSTwitterEngine *twitterEngine = [FHSTwitterEngine sharedEngine];
NSString *username = [twitterEngine loggedInUsername]; //self.engine.loggedInUsername;
NSString *key = [twitterEngine accessToken].key;
NSString *secrete = [twitterEngine accessToken].secret;
if (username.length > 0)
{
NSDictionary *userProfile = [[FHSTwitterEngine sharedEngine] getProfileUsername:username];
NSLog(#"userProfile: %#", userProfile);
EDIT
After Twitter has updated APIs, Now user can get Email using TWTRShareEmailViewController class.
// Objective-C
if ([[Twitter sharedInstance] session]) {
TWTRShareEmailViewController* shareEmailViewController = [[TWTRShareEmailViewController alloc] initWithCompletion:^(NSString* email, NSError* error) {
NSLog(#"Email %#, Error: %#", email, error);
}];
[self presentViewController:shareEmailViewController animated:YES completion:nil];
} else {
// TODO: Handle user not signed in (e.g. attempt to log in or show an alert)
}
// Swift
if Twitter.sharedInstance().session {
let shareEmailViewController = TWTRShareEmailViewController() { email, error in
println("Email \(email), Error: \(error)")
}
self.presentViewController(shareEmailViewController, animated: true, completion: nil)
} else {
// TODO: Handle user not signed in (e.g. attempt to log in or show an alert)
}
NOTES:
Even if the user grants access to her email address, it is not guaranteed you will get an email address. For example, if someone signed up for Twitter with a phone number instead of an email address, the email field may be empty. When this happens, the completion block will pass an error because there is no email address available.
Twitter Dev Ref
PAST
There is NO way you can get email address of a twitter user.
The Twitter API does not provide the user's email address as part of the OAuth token negotiation process nor does it offer other means to obtain it.
Twitter Doc.
You will have to use Twitter framework. Twitter has provided a beautiful framework for that, you just have to integrate it in your app.
To get user email address, your application should be whitelisted. Here is the link. Go to use this form. You can either send mail to sdk-feedback#twitter.com with some details about your App like Consumer key, App Store link of an App, Link to privacy policy, Metadata, Instructions on how to log into our App etc..They will respond within 2-3 working days.
Here is the story how I got whitelisted by conversation with Twitter support team:
Send mail to sdk-feedback#twitter.com with some details about your App like Consumer key, App Store link of an App, Link to privacy policy, Metadata, Instructions on how to log into our App. Mention in mail that you want to access user email adress inside your App.
They will review your App and reply to you withing 2-3 business days.
Once they say that your App is whitelisted, update your App's settings in Twitter Developer portal. Sign in to apps.twitter.com and:
On the 'Settings' tab, add a terms of service and privacy policy URL
On the 'Permissions' tab, change your token's scope to request email. This option will only been seen, once your App gets whitelisted.
Put your hands on code
Use of Twitter framework:
Get user email address
-(void)requestUserEmail
{
if ([[Twitter sharedInstance] session]) {
TWTRShareEmailViewController *shareEmailViewController =
[[TWTRShareEmailViewController alloc]
initWithCompletion:^(NSString *email, NSError *error) {
NSLog(#"Email %# | Error: %#", email, error);
}];
[self presentViewController:shareEmailViewController
animated:YES
completion:nil];
} else {
// Handle user not signed in (e.g. attempt to log in or show an alert)
}
}
Get user profile
-(void)usersShow:(NSString *)userID
{
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/users/show.json";
NSDictionary *params = #{#"user_id": userID};
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance] APIClient]
URLRequestWithMethod:#"GET"
URL:statusesShowEndpoint
parameters:params
error:&clientError];
if (request) {
[[[Twitter sharedInstance] APIClient]
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
NSLog(#"%#",[json description]);
}
else {
NSLog(#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]);
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}
}
Hope it helps !!!
If you'd like a user's email address, you'll need to ask a user for it within the confines of your own application and service. The Twitter API does not provide the user's email address as part of the OAuth token negotiation process nor does it offer other means to obtain it.
In Swift 4.2 and Xcode 10.1
It's getting email also.
import TwitterKit
#IBAction func onClickTwitterSignin(_ sender: UIButton) {
TWTRTwitter.sharedInstance().logIn { (session, error) in
if (session != nil) {
let name = session?.userName ?? ""
print(name)
print(session?.userID ?? "")
print(session?.authToken ?? "")
print(session?.authTokenSecret ?? "")
let client = TWTRAPIClient.withCurrentUser()
client.requestEmail { email, error in
if (email != nil) {
let recivedEmailID = email ?? ""
print(recivedEmailID)
}else {
print("error--: \(String(describing: error?.localizedDescription))");
}
}
let storyboard = self.storyboard?.instantiateViewController(withIdentifier: "SVC") as! SecondViewController
self.navigationController?.pushViewController(storyboard, animated: true)
}else {
print("error: \(String(describing: error?.localizedDescription))");
}
}
}
Swift 3-4
#IBAction func btnTwitterAction(_ sender: Any) {
TWTRTwitter.sharedInstance().logIn(completion: { (session, error) in
if (session != nil) {
print("signed in as \(String(describing: session?.userName))");
if let mySession = session{
let client = TWTRAPIClient.withCurrentUser()
//To get User name and email
client.requestEmail { email, error in
if (email != nil) {
print("signed in as \(String(describing: session?.userName))");
let firstName = session?.userName ?? "" // received first name
let lastName = session?.userName ?? "" // received last name
let recivedEmailID = email ?? "" // received email
}else {
print("error: \(String(describing: error?.localizedDescription))");
}
}
//To get user profile picture
client.loadUser(withID: session?.userID, completion: { (userData, error) in
if (userData != nil) {
let fullName = userData.name //Full Name
let userProfileImage = userData.profileImageLargeURL //User Profile Image
let userTwitterProfileUrl = userData?.profileURL // User TwitterProfileUrl
}
})
}
} else {
print("error: \(error?.localizedDescription)");
}
})
}

Resources