AWS iOS SDK 开发指南:构建云端移动应用的完整解决方案

47 阅读4分钟

AWS iOS SDK for iOS 开发指南

项目概述

AWS iOS SDK 是一个功能完整的移动开发框架,让开发者能够轻松地将 AWS 云服务集成到 iOS 应用程序中。该 SDK 提供了对 AWS 核心服务的原生支持,包括身份认证、数据存储、API 调用、推送通知等功能,帮助开发者快速构建安全、可扩展的移动应用。

⚠️ 重要通知:AWS SDK for iOS 已于 2025 年 8 月 1 日进入维护阶段,建议新项目使用 AWS Amplify for Swift

功能特性

核心服务集成

  • 身份认证:支持 Amazon Cognito 用户池和身份池,提供完整的用户生命周期管理
  • 数据存储:与 Amazon S3、DynamoDB 无缝集成,实现安全的数据存储和同步
  • API 网关:简化 REST API 调用,支持自动签名和错误处理
  • 推送通知:通过 Amazon Pinpoint 实现精准的消息推送

第三方登录支持

  • Facebook 登录:集成 Facebook SDK,支持社交账号登录
  • Google 登录:提供 Google Sign-In 完整集成方案
  • Apple 登录:支持 Sign in with Apple,符合 App Store 审核要求
  • 自定义身份提供商:可扩展架构支持自定义认证流程

开发体验优化

  • Swift Package Manager 支持,简化依赖管理
  • 模块化设计,按需导入所需服务组件
  • 完整的类型定义,提供良好的代码提示和类型安全
  • 详细的错误处理,包含丰富的错误码和恢复建议

安装指南

Swift Package Manager 安装

  1. 在 Xcode 项目中,选择 File > Add Packages
  2. 输入仓库地址:https://github.com/aws-amplify/aws-sdk-ios-spm
  3. 选择需要集成的服务模块

基本依赖配置

// 在 Package.swift 中添加依赖
dependencies: [
    .package(url: "https://github.com/aws-amplify/aws-sdk-ios-spm", from: "2.41.0")
]

// 选择需要的目标模块
.target(
    name: "YourApp",
    dependencies: [
        .product(name: "AWSCore", package: "aws-sdk-ios-spm"),
        .product(name: "AWSS3", package: "aws-sdk-ios-spm"),
        .product(name: "AWSMobileClientXCF", package: "aws-sdk-ios-spm")
    ]
)

CocoaPods 安装

platform :ios, '11.0'

target 'YourApp' do
  use_frameworks!
  
  pod 'AWSCore'
  pod 'AWSS3'
  pod 'AWSMobileClient'
end

使用说明

初始化配置

import AWSMobileClient

// 应用启动时初始化
func application(_ application: UIApplication, 
                didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    // 初始化 AWS Mobile Client
    AWSMobileClient.default().initialize { (userState, error) in
        if let userState = userState {
            print("用户状态: \(userState.rawValue)")
        } else if let error = error {
            print("初始化错误: \(error.localizedDescription)")
        }
    }
    
    return true
}

用户认证示例

import AWSMobileClient

class AuthViewController: UIViewController {
    
    func signIn(username: String, password: String) {
        AWSMobileClient.default().signIn(username: username, 
                                        password: password) { (signInResult, error) in
            if let error = error {
                print("登录错误: \(error.localizedDescription)")
                return
            }
            
            guard let signInResult = signInResult else { return }
            
            switch signInResult.signInState {
            case .signedIn:
                print("用户登录成功")
                self.fetchUserAttributes()
            case .newPasswordRequired:
                print("需要设置新密码")
                self.showNewPasswordRequired()
            default:
                print("需要其他操作: \(signInResult.signInState.rawValue)")
            }
        }
    }
    
    private func fetchUserAttributes() {
        AWSMobileClient.default().getUserAttributes { (attributes, error) in
            if let error = error {
                print("获取用户属性错误: \(error.localizedDescription)")
                return
            }
            
            if let attributes = attributes {
                for attribute in attributes {
                    print("属性: \(attribute.key) - 值: \(attribute.value)")
                }
            }
        }
    }
}

S3 文件上传示例

import AWSS3

class FileUploader {
    
    func uploadImageToS3(imageData: Data, key: String) {
        let expression = AWSS3TransferUtilityUploadExpression()
        expression.progressBlock = { (task, progress) in
            DispatchQueue.main.async {
                print("上传进度: \(progress.fractionCompleted)")
            }
        }
        
        let transferUtility = AWSS3TransferUtility.default()
        transferUtility.uploadData(
            imageData,
            bucket: "your-bucket-name",
            key: key,
            contentType: "image/jpeg",
            expression: expression
        ) { (task, error) in
            if let error = error {
                print("上传错误: \(error.localizedDescription)")
                return
            }
            
            print("文件上传成功: \(key)")
        }
    }
}

API Gateway 调用示例

import AWSAPIGateway

class APIClient {
    
    func callBackendAPI() {
        // 创建 API 请求
        let request = AWSAPIGatewayRequest(
            httpMethod: "GET",
            urlString: "/items",
            queryParameters: nil,
            headerParameters: ["Content-Type": "application/json"],
            httpBody: nil
        )
        
        // 创建 API 客户端
        let client = AWSAPIGatewayClient()
        
        // 调用 API
        client.invoke(request).continueWith { (task) -> Any? in
            if let error = task.error {
                print("API 调用错误: \(error)")
                return nil
            }
            
            if let response = task.result {
                print("响应状态码: \(response.statusCode)")
                if let responseData = response.responseData {
                    // 处理响应数据
                    if let jsonString = String(data: responseData, encoding: .utf8) {
                        print("响应内容: \(jsonString)")
                    }
                }
            }
            
            return nil
        }
    }
}

核心代码解析

AWSMobileClient 初始化核心代码

// AWSMobileClient 初始化实现
public func initialize(completionHandler: @escaping (UserState?, Error?) -> Void) {
    // 检查现有的登录状态
    if let cachedLogins = self.cachedLogins {
        // 使用缓存的登录信息
        self.loadTokens(from: cachedLogins, completionHandler: completionHandler)
    } else {
        // 从 Keychain 加载凭据
        self.loadCredentialsFromKeychain(completionHandler: completionHandler)
    }
}

private func loadTokens(from logins: [String: String], 
                       completionHandler: @escaping (UserState?, Error?) -> Void) {
    // 使用登录信息获取 AWS 凭据
    self.getAWSCredentials(loginTokens: logins) { (credentials, error) in
        if let error = error {
            completionHandler(nil, error)
            return
        }
        
        // 更新用户状态
        self.updateUserState(with: credentials)
        completionHandler(self.currentUserState, nil)
    }
}

Cognito 身份验证流程

// Objective-C 实现的身份验证管理器
@implementation AWSCognitoAuth

- (void)getSession:(AWSCognitoAuthGetSessionCompletion)completion {
    // 检查现有的会话
    if ([self hasValidSession]) {
        [self refreshSessionIfNeededWithCompletion:completion];
        return;
    }
    
    // 启动新的认证流程
    [self startAuthenticationFlowWithCompletion:^(AWSCognitoAuthUserSession * _Nullable session, 
                                                 NSError * _Nullable error) {
        if (session) {
            // 缓存会话信息
            [self cacheSession:session];
            completion(session, nil);
        } else {
            completion(nil, error);
        }
    }];
}

- (BOOL)hasValidSession {
    // 检查访问令牌是否有效
    return [self.accessToken isValid] && ![self.accessToken isExpired];
}
@end

S3 传输工具实现

// S3 文件传输的核心实现
class AWSS3TransferUtility: NSObject {
    
    func uploadData(_ data: Data,
                   bucket: String,
                   key: String,
                   contentType: String,
                   expression: AWSS3TransferUtilityUploadExpression?,
                   completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?) -> AWSTask<AWSS3TransferUtilityUploadTask> {
        
        // 创建上传请求
        let request = AWSS3PutObjectRequest()
        request.bucket = bucket
        request.key = key
        request.body = data
        request.contentType = contentType
        
        // 配置请求头
        if let expression = expression {
            request.setValue(expression.contentMD5, forHTTPHeaderField: "Content-MD5")
        }
        
        // 执行上传
        return self.s3.putObject(request).continueWith { (task) -> Any? in
            if let error = task.error {
                completionHandler?(nil, error)
            } else {
                let uploadTask = AWSS3TransferUtilityUploadTask()
                completionHandler?(uploadTask, nil)
            }
            return nil
        }
    }
}

API Gateway 请求处理

// API Gateway 客户端核心实现
@implementation AWSAPIGatewayClient

- (AWSTask<AWSAPIGatewayResponse *> *)invoke:(AWSAPIGatewayRequest *)apiRequest {
    return [AWSTask taskWithResult:nil].continueWithBlock:^id(AWSTask *task) {
        // 构建完整的 URL
        NSURL *requestURL = [self requestURL:apiRequest.URLString 
                                       query:apiRequest.queryParameters];
        
        // 创建 URL 请求
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:requestURL];
        urlRequest.HTTPMethod = apiRequest.HTTPMethod;
        
        // 设置请求头
        NSDictionary *finalHeaders = [self finalizeRequestHeaders:apiRequest.headerParameters];
        for (NSString *header in finalHeaders) {
            [urlRequest setValue:finalHeaders[header] forHTTPHeaderField:header];
        }
        
        // 设置请求体
        if (apiRequest.HTTPBody) {
            urlRequest.HTTPBody = [self processHTTPBody:apiRequest.HTTPBody];
        }
        
        // 执行网络请求
        return [self executeRequest:urlRequest];
    }];
}

- (NSDictionary *)finalizeRequestHeaders:(NSDictionary *)requestHeaders {
    NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:requestHeaders];
    
    // 添加 API 密钥(如果配置了)
    if (self.APIKey) {
        headers[@"x-api-key"] = self.APIKey;
    }
    
    // 设置缓存控制
    if (!headers[@"Cache-Control"]) {
        headers[@"Cache-Control"] = @"no-store";
    }
    
    return headers;
}
@end

这些核心代码展示了 AWS iOS SDK 的关键实现细节,包括身份验证管理、文件上传处理和 API 调用等核心功能。通过模块化设计和完整的错误处理机制,SDK 为开发者提供了稳定可靠的云服务集成方案。