You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWSS3TransferUtility上传音频至AWS S3 Bucket时遭遇Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=2错误

Troubleshooting AWSS3TransferUtility Error Code 2 & Audio Upload Fix

First, let's break down what that error means: Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=2 typically points to one of these issues: invalid request signing, insufficient permissions, misordered AWS service initialization, or mismatched resource configurations. Let's walk through fixing this step by step, including adapting your code for audio file uploads.

Step 1: Fix AWS Service Initialization Order

Your current code registers the TransferUtility before setting the global default service configuration. This causes the TransferUtility to use an outdated default config, which is a common source of Code 2 errors. Reorder your setup like this:

// First, initialize credentials and global configuration
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.USEast2, identityPoolId:"us-east-2:fe41c293-df49-49a4-886d-094f2cd8d0fd")
guard let configuration = AWSServiceConfiguration(region:.USEast2, credentialsProvider:credentialsProvider) else {
    print("Failed to create AWS service configuration")
    return
}
AWSServiceManager.default().defaultServiceConfiguration = configuration

// THEN register and retrieve the TransferUtility
let tuConf = AWSS3TransferUtilityConfiguration()
AWSS3TransferUtility.register(
    with: configuration, transferUtilityConfiguration: tuConf, forKey: "transfer-utility-audio-upload"
)
guard let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "transfer-utility-audio-upload") else {
    print("Failed to initialize TransferUtility")
    return
}

Step 2: Verify Cognito & S3 Permissions

Code 2 often pops up when your Cognito identity pool lacks the necessary S3 upload permissions.

  1. Go to the IAM Console and find the role linked to your Cognito identity pool (either authenticated or unauthenticated, depending on your app's flow).
  2. Attach a policy that allows uploads to your target bucket path:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::testingimageupload/private/Abhay/*"
        }
    ]
}
  1. Double-check that your S3 bucket's policy doesn't block access from this role (if you have a bucket policy configured).

Step 3: Adapt Code for Audio File Uploads

Your original code is built for images—here's a revised version tailored for audio, with key fixes:

func uploadAudioFile(fromFileURL fileURL: URL) {
    // 1. Initialize AWS config first (fixed order)
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.USEast2, identityPoolId:"us-east-2:fe41c293-df49-49a4-886d-094f2cd8d0fd")
    guard let configuration = AWSServiceConfiguration(region:.USEast2, credentialsProvider:credentialsProvider) else {
        print("Failed to create AWS configuration")
        return
    }
    AWSServiceManager.default().defaultServiceConfiguration = configuration
    
    // 2. Register TransferUtility
    let tuConf = AWSS3TransferUtilityConfiguration()
    AWSS3TransferUtility.register(
        with: configuration, transferUtilityConfiguration: tuConf, forKey: "transfer-utility-audio-upload"
    )
    guard let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "transfer-utility-audio-upload") else {
        print("Failed to get TransferUtility instance")
        return
    }
    
    // 3. Read audio file data (replace image-specific logic)
    guard let audioData = try? Data(contentsOf: fileURL) else {
        print("Failed to load audio file data")
        return
    }
    let fileExtension = fileURL.pathExtension.lowercased()
    let remoteName = generateRandomStringWithLength(length: 12) + "." + fileExtension
    let s3BucketName = "testingimageupload"
    let s3Key = "private/Abhay/" + remoteName
    
    // 4. Set correct Content-Type for audio (critical for S3 recognition)
    var contentType = "audio/mpeg" // Default for MP3
    switch fileExtension {
    case "wav":
        contentType = "audio/wav"
    case "aac":
        contentType = "audio/aac"
    case "m4a":
        contentType = "audio/mp4"
    default:
        break
    }
    
    // 5. Configure upload expression
    let expression = AWSS3TransferUtilityUploadExpression()
    expression.setValue("public-read", forRequestHeader: "x-amz-acl")
    expression.progressBlock = { (task, progress) in
        DispatchQueue.main.async {
            print("Upload progress: \(String(format: "%.1f", progress.fractionCompleted * 100))%")
            // Update your UI progress bar here
        }
    }
    
    // 6. Completion handler
    let completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock = { (task, error) in
        DispatchQueue.main.async {
            if let error = error {
                print("Upload failed: \(error.localizedDescription)")
                return
            }
            print("Audio upload succeeded!")
            // Get the public URL of the uploaded file
            if let baseURL = AWSS3.default().configuration.endpoint.url {
                let publicURL = baseURL.appendingPathComponent(s3BucketName).appendingPathComponent(s3Key)
                print("Audio URL: \(publicURL.absoluteString ?? "N/A")")
            }
        }
    }
    
    // 7. Execute upload
    transferUtility.uploadData(audioData, bucket: s3BucketName, key: s3Key, contentType: contentType, expression: expression, completionHandler: completionHandler)
        .continueWith { task in
            if let error = task.error {
                print("Transfer task error: \(error.localizedDescription)")
            }
            return nil
        }
}

// Keep your existing random string generator
func generateRandomStringWithLength(length: Int) -> String {
    let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    return String((0..<length).map{ _ in letters.randomElement()! })
}

Step 4: Final Checks

  • Confirm your S3 bucket is hosted in the us-east-2 region (match your code's regionType). If your bucket is in another region, update the region value accordingly.
  • Ensure your device has a stable internet connection (AWS SDK errors can sometimes mask network issues).
  • For iOS 14+, make sure your Info.plist doesn't block HTTPS requests to AWS (AWS uses HTTPS by default, so this should only be an issue if you're using a custom endpoint).

内容的提问来源于stack exchange,提问作者Mobile Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 10:22:31