2015-02-14 11 views
5

मुझे अपने सर्वर पहचान (एडब्ल्यूएस के माध्यम से) मेरे उदाहरण पहचान प्रदाता को प्रदान किए गए डेवलपर क्रेडेंशियल्स को वापस करने का तरीका समझने में कठिनाई हो रही है।एडब्ल्यूएस आईओएस एसडीके कॉग्निटो डेवलपर प्रमाणीकरण (स्विफ्ट)

ऐसा लगता है कि मुझे exampleIdentityProvider क्लास पर refresh विधि के भीतर यह समकालिक रूप से करने की आवश्यकता है। मैं अनुरोध करने के लिए AFNetworking का उपयोग कर रहा हूं, लेकिन यह एक async GET अनुरोध है। मैं अपने पहचान प्रदाता पर रीफ्रेश विधि के लिए यह सिंक्रनाइज़ कैसे कर सकता हूं?

निम्नलिखित स्विफ्ट में है:

class ExampleIdentityProvider: AWSAbstractIdentityProvider { 
    var newToken: String! 

    override var token: String { 
     get { 
      return newToken 
     } 
     set { 
      newToken = newValue 
     } 
    } 

    override func getIdentityId() -> BFTask! { 
     if self.identityId != nil { 
      return BFTask(result: self.identityId) 
     }else{ 
      return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in 
       if self.identityId == nil { 
        return self.refresh() 
       } 
       return BFTask(result: self.identityId) 
      }) 
     } 
    } 

    override func refresh() -> BFTask! { 
     return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in 
      let result = AFNETWORKING REQUEST FOR CREDENTIALS TO MY SERVER 
      self.identityId = result.identityId 
      self.token = result.token 

      return BFTask(result: self.identityId) 
     }) 
    } 
} 

उत्तर

11

मेरा मानना ​​है कि मैं यह पता लगा है। मुझे BFTask का उपयोग करने की आवश्यकता है जो पृष्ठभूमि कार्यों को पूरा करने के साथ संभालने के लिए बनाया गया है।

class ExampleAppIdentityProvider: AWSAbstractCognitoIdentityProvider { 
    var _token: String! 
    var _logins: [ NSObject : AnyObject ]! 

    // Header stuff you may not need but I use for auth with my server 
    let acceptHeader = "application/vnd.exampleapp-api+json;version=1;" 
    let authHeader = "Token token=" 
    let userDefaults = NSUserDefaults.standardUserDefaults() 
    let authToken = self.userDefaults.valueForKey("authentication_token") as String 

    // End point that my server gives amazon identityId and tokens to authorized users 
    let url = "https://api.myapp.com/api/amazon_id/" 

    override var token: String { 
     get { 
      return _token 
     } 
    } 

    override var logins: [ NSObject : AnyObject ]! { 
     get { 
      return _logins 
     } 
     set { 
      _logins = newValue 
     } 
    } 

    override func getIdentityId() -> BFTask! { 
     if self.identityId != nil { 
      return BFTask(result: self.identityId) 
     }else{ 
      return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in 
       if self.identityId == nil { 
        return self.refresh() 
       } 
       return BFTask(result: self.identityId) 
      }) 
     } 
    } 

    override func refresh() -> BFTask! { 
     let task = BFTaskCompletionSource() 
     let request = AFHTTPRequestOperationManager() 
     request.requestSerializer.setValue(self.acceptHeader, forHTTPHeaderField: "ACCEPT") 
     request.requestSerializer.setValue(self.authHeader+authToken, forHTTPHeaderField: "AUTHORIZATION") 
     request.GET(self.url, parameters: nil, success: { (request: AFHTTPRequestOperation!, response: AnyObject!) -> Void in 
      // The following 3 lines are required as referenced here: http://stackoverflow.com/a/26741208/535363 
      var tmp = NSMutableDictionary() 
      tmp.setObject("temp", forKey: "ExampleApp") 
      self.logins = tmp 

      // Get the properties from my server response 
      let properties: NSDictionary = response.objectForKey("properties") as NSDictionary 
      let amazonId = properties.objectForKey("amazon_identity") as String 
      let amazonToken = properties.objectForKey("token") as String 

      // Set the identityId and token for the ExampleAppIdentityProvider 
      self.identityId = amazonId 
      self._token = amazonToken 

      task.setResult(response) 
     }, failure: { (request: AFHTTPRequestOperation!, error: NSError!) -> Void in 
      task.setError(error) 
     }) 
     return task.task 
    } 
} 

और ऐसा करके ExampleAppIdentityProvider प्रारंभ:

let identityProvider = ExampleAppIdentityProvider() 
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityProvider: identityProvider, unauthRoleArn: GlobalVariables.cognitoUnauthRoleArn, authRoleArn: GlobalVariables.cognitoAuthRoleArn) 
    let defaultServiceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialsProvider) 
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration 

    let transferManager = AWSS3TransferManager.defaultS3TransferManager() 

    let uploadRequest = AWSS3TransferManagerUploadRequest() 
    uploadRequest.bucket = GlobalVariables.awsBucket 
    uploadRequest.key = "\(GlobalVariables.environment)/uploads/users/\(userId)/\(type)/\(timestamp)/original.jpg" 
    uploadRequest.ACL = .AuthenticatedRead 
    uploadRequest.body = tmpFileUrl 

    // Upload file 
    let task = transferManager.upload(uploadRequest) 

cognito के साथ डेवलपर प्रमाणन का एक स्विफ्ट कार्यान्वयन जो मेरे लिए एक समान सेटअप हो सकता है के साथ संघर्ष कर लोगों के लिए, यह मैं इसे कैसे पूरा किया है

मैं वैश्विक वातावरण चर कि bucket के लिए मान हो, unAuthRoleArn, authRoleArn, आदि के साथ एक struct नामित GlobalVariables बनाया हे एफ कोर्स आपको ऐसा करने की ज़रूरत नहीं है, लेकिन अगर कोई उलझन में है तो मैं इसका जिक्र कर रहा हूं।

+0

आप दिखा सकते हैं कि कैसे आप प्रदाता/विन्यास प्रारंभ एडब्ल्यूएस सामान इस का उपयोग करने के लिए ? – user871177

+0

@ user871177 उपरोक्त अद्यतन कोड देखें। उम्मीद है कि मददगार है। – Yavin4

+0

वाह, बहुत उपयोगी। –

0

क्या आप cognito प्रमाणीकरण

import AWSS3 
import AWSCore 
import Alamofire 

//This variable is store aws credential token 
var cachedLogin : NSDictionary? 
final class AmazonIdentityProvider : AWSCognitoCredentialsProviderHelper{ 

    // Handles getting the login 
    override func logins() -> AWSTask<NSDictionary> { 
     guard let cachedLoginObj = cachedLogin else { 
      return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSDictionary> in 
       guard let credential = credentialTask.result else { 
        return AWSTask(result: nil) 
       } 

       self.setCognitoTokenKey(credential: credential) 

       return AWSTask(result: cachedLogin) 
      }) as! AWSTask<NSDictionary> 
     } 
     return AWSTask(result: cachedLoginObj) 
    } 

    // Handles getting a token from the server 
    override func token() -> AWSTask<NSString> { 
     return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSString> in 
      guard let credential = credentialTask.result else { 
       return AWSTask(result: nil) 
      } 

      self.setCognitoTokenKey(credential: credential) 

      return AWSTask(result: credential.token as NSString) 
     }) as! AWSTask<NSString> 
    } 

    // Handles getting the identity id 
    override func getIdentityId() -> AWSTask<NSString> { 

     return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSString> in 
      guard let credential = credentialTask.result else { 
       return AWSTask(result: nil) 
      } 

      self.setCognitoTokenKey(credential: credential) 

      return AWSTask(result: credential.identityId as NSString) 
     }) as! AWSTask<NSString> 
    } 

    //This method is used to AWS Token set 
    func setCognitoTokenKey(credential : AmazonCognitoCredential){ 
     let login: NSDictionary = ["cognito-identity.amazonaws.com": credential.token] 
     cachedLogin = login 
     self.identityId = credential.identityId 
    } 

    // Gets credentials from server 
    func getCredentials() -> AWSTask<AmazonCognitoCredential> { 
     let tokenRequest = AWSTaskCompletionSource<AmazonCognitoCredential>() 
     getAwsToken { (isSuccess, error, credentials) in 
      if isSuccess 
      { 
       tokenRequest.set(result: credentials) 
      } 
      else 
      { 
       tokenRequest.set(error: error!) 
      } 
     } 
     return tokenRequest.task 
    } 
    typealias CompletionBlock = (_ success:Bool,_ errorMassage:Error?,_ responce:AmazonCognitoCredential?) -> Void 
    func getAwsToken(complitionBlock : @escaping CompletionBlock) { 
//Your server token code 
} 
/// AmazonCognito credential custom class 
final class AmazonCognitoCredential { 
    let token: String 
    let identityId: String 

    init(token: String, identityId: String) { 
     self.token = token 
     self.identityId = identityId 
    } 
} 

के लिए कस्टम वर्ग उत्पन्न कर सकते हैं और आप इस ऐप्लिकेशन प्रतिनिधि में उपयोग कर सकते हैं

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

    AWSDDLog.sharedInstance.logLevel = .all 
    let identityProvider = AmazonIdentityProvider() 
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, unauthRoleArn: CognitoRoleUnauth, authRoleArn: CognitoRoleAuth, identityProvider: identityProvider) 
    let configuration = AWSServiceConfiguration(region: .USWest2, credentialsProvider: credentialsProvider) 
    AWSServiceManager.default().defaultServiceConfiguration = configuration 

    let task = identityProvider.getIdentityId() 
    task.continueWith { (task:AWSTask) -> Any? in 
     if (task.error != nil) { 
      print("\(String(describing: task.error))") 
     } else { 
      print("Task result: \(String(describing: task.result))") 
     } 
     return nil 
    } 
    return true 
} 
संबंधित मुद्दे