All Products
Search
Document Center

Object Storage Service:Download an object by using a signed URL (Swift SDK)

Last Updated:Nov 29, 2025

By default, objects in an Object Storage Service (OSS) bucket are private and can be accessed only by the object owner. This topic describes how to use the OSS Swift SDK to generate a signed URL for a GET request. This URL includes an expiration time and grants temporary download access to other users. The URL can be used multiple times before it expires. After the URL expires, you must generate a new one.

Notes

  • The code examples in this topic are for the China (Hangzhou) region (ID: cn-hangzhou) and use a public endpoint by default. If you want to access OSS from other Alibaba Cloud products in the same region, use an internal endpoint. For more information about the mappings between OSS-supported regions and endpoints, see Regions and Endpoints.

  • You do not need specific permissions to generate a presigned URL. However, to allow others to use the presigned URL to download an object, you must have the oss:GetObject permission. For more information, see Common examples of RAM policies.

Process

The following flowchart shows how to download an object by using a presigned URL.

image

Sample code

  1. The object owner generates a signed URL for a GET request.

    import AlibabaCloudOSS
    import Foundation
    
    @main
    struct Main {
        static func main() async {
    
            do {
                // Specify the region where the bucket is located. Example: China (Hangzhou) is cn-hangzhou.
                let region = "cn-hangzhou"
                // Optional. Specify the domain name used to access OSS. For the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
                let endpoint: String? = nil
                // Specify the bucket name.
                let bucket = "yourBucketName"
                // Specify the name of the object to download.
                let key = "yourObjectName"
    
                // Obtain access credentials from environment variables. Before running the sample code, make sure the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
                let credentialsProvider = EnvironmentCredentialsProvider()
    
                // Configure the OSS client parameters.
                let config = Configuration.default()
                    .withRegion(region)        // Set the region where the bucket is located.
                    .withCredentialsProvider(credentialsProvider)  // Set the access credentials.
                    
                // Set the endpoint.
                if let endpoint = endpoint {
                    config.withEndpoint(endpoint)
                }
                
                // Create an OSS client instance.
                let client = Client(config)
    
                // Generate the signed URL.
                let result = try await client.presign(
                    GetObjectRequest(
                        bucket: bucket,
                        key: key
                    )
                )
                // Print the result.
                print("result:\n\(result)")
                
            } catch {
                // Print the error.
                print("error: \(error)")
            }
        }
    }
  2. Other users download the object using the signed URL for the GET request.

    curl

    curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Java

    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class Demo {
        public static void main(String[] args) {
            // Specify the presigned URL that allows HTTP GET requests. 
            String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            // Specify the path in which the downloaded object is stored, including the object name and extension. 
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("Download completed!");
            } catch (IOException e) {
                System.err.println("Error during download: " + e.getMessage());
            }
        }
    
        private static void downloadFile(String fileURL, String savePath) throws IOException {
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
    
            // Specify the response code.
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // Configure the input stream.
                InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                // Configure the output stream.
                FileOutputStream outputStream = new FileOutputStream(savePath);
    
                byte[] buffer=new byte[4096]; // Specify the size of the buffer.
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
    
                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("No file to download. Server replied HTTP code: " + responseCode);
            }
            httpConn.disconnect();
        }
    }

    Node.js

    const https = require('https');
    const fs = require('fs');
    
    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt";
    
    https.get(fileURL, (response) => {
        if (response.statusCode === 200) {
            const fileStream = fs.createWriteStream(savePath);
            response.pipe(fileStream);
            
            fileStream.on('finish', () => {
                fileStream.close();
                console.log("Download completed!");
            });
        } else {
            console.error(`Download failed. Server responded with code: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("Error during download:", err.message);
    });

    Python

    import requests
    
    file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
    save_path = "C:/downloads/myfile.txt"
    
    try:
        response = requests.get(file_url, stream=True)
        if response.status_code == 200:
            with open(save_path, 'wb') as f:
                for chunk in response.iter_content(4096):
                    f.write(chunk)
            print("Download completed!")
        else:
            print(f"No file to download. Server replied HTTP code: {response.status_code}")
    except Exception as e:
        print("Error during download:", e)

    Go

    package main
    
    import (
        "io"
        "net/http"
        "os"
    )
    
    func main() {
        fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
        savePath := "C:/downloads/myfile.txt"
    
        response, err := http.Get(fileURL)
        if err != nil {
            panic(err)
        }
        defer response.Body.Close()
    
        if response.StatusCode == http.StatusOK {
            outFile, err := os.Create(savePath)
            if err != nil {
                panic(err)
            }
            defer outFile.Close()
    
            _, err = io.Copy(outFile, response.Body)
            if err != nil {
                panic(err)
            }
            println("Download completed!")
        } else {
            println("No file to download. Server replied HTTP code:", response.StatusCode)
        }
    }

    JavaScript

    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt"; // Specify the name of the downloaded object.
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`Server replied HTTP code: ${response.status}`);
            }
            return response.blob(); // Change the type of the response to blob.
        })
        .then(blob => {
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download=savePath; // Specify the name of the downloaded object.
            document.body.appendChild(link); // This step ensures that the presigned URL exists in the document.
            link.click(); // Click the presigned URL to simulate the object download.
            link.remove(); // Remove the presigned URL after the object is downloaded.
            console.log("Download completed!");
        })
        .catch(error => {
            console.error("Error during download:", error);
        });

    Android-Java

    import android.os.AsyncTask;
    import android.os.Environment;
    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class DownloadTask extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... params) {
            String fileURL = params[0];
            String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // Specify the path in which you want to store the downloaded object.
            try {
                URL url = new URL(fileURL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setRequestMethod("GET");
                int responseCode = httpConn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                    FileOutputStream outputStream = new FileOutputStream(savePath);
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    outputStream.close();
                    inputStream.close();
                    return "Download completed!";
                } else {
                    return "No file to download. Server replied HTTP code: " + responseCode;
                }
            } catch (Exception e) {
                return "Error during download: " + e.getMessage();
            }
        }
    }

    Objective-C

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // Specify the presigned URL and the path in which you want to store the object.
            NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // Replace your_username with your username.
            
            // Create a URL object.
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // Create an object download task.
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // Handle errors.
                if (error) {
                    NSLog(@"Error during download: %@", error.localizedDescription);
                    return;
                }
                
                // Check the data in the object.
                if (!data) {
                    NSLog(@"No data received.");
                    return;
                }
                
                // Save the object.
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"Download completed!");
                } else {
                    NSLog(@"Error saving file: %@", writeError.localizedDescription);
                }
            }];
            
            // Start the object download task.
            [task resume];
            
            // Continue to run the main thread to complete the asynchronous request.
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

Common scenarios

Download an object in the background using a signed URL

import AlibabaCloudOSS
import Foundation

@main
struct Main {
    static func main() async {

        do {
            // Specify the region where the bucket is located. Example: China (Hangzhou) is cn-hangzhou.
            let region = "cn-hangzhou"
            // Optional. Specify the domain name used to access OSS. For the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
            let endpoint: String? = nil
            // Specify the bucket name.
            let bucket = "yourBucketName"
            // Specify the name of the object to download.
            let key = "yourObjectName"

            // Obtain access credentials from environment variables. Before running the sample code, make sure the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
            let credentialsProvider = EnvironmentCredentialsProvider()

            // Configure the OSS client parameters.
            let config = Configuration.default()
                .withRegion(region)        // Set the region where the bucket is located.
                .withCredentialsProvider(credentialsProvider)  // Set the access credentials.
                
            // Set the endpoint.
            if let endpoint = endpoint {
                config.withEndpoint(endpoint)
            }
            
            // Create an OSS client instance.
            let client = Client(config)

            // Generate the signed URL.
            let result = try await client.presign(
                GetObjectRequest(
                    bucket: bucket,
                    key: key
                )
            )
            var urlRequest = URLRequest(url: URL(string: result.url)!)
            urlRequest.httpMethod = result.method
            for (key, value) in result.signedHeaders ?? [:] {
                urlRequest.addValue(value, forHTTPHeaderField: key)
            }
            // Normal download.
            // let (url, response) = try await URLSession.shared.download(for: urlRequest)
            
            // Background download.
            let sessionConfig = URLSessionConfiguration.background(withIdentifier: "background.session.id")
            let session = URLSession(configuration: sessionConfig,
                                     delegate: URLSessionDelegateImp(),
                                     delegateQueue: OperationQueue())
            session.downloadTask(with: urlRequest).resume()
        } catch {
            // Print the error.
            print("error: \(error)")
        }
    }
}

class URLSessionDelegateImp: NSObject, URLSessionTaskDelegate {
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: (any Error)?) {
        print("task complete")
        if let e = error {
            print("error: \(e)")
        }
    }
}

extension URLSessionDelegateImp: URLSessionDownloadDelegate {
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("url: \(location)")
    }
}