本文介绍如何使用 Microsoft Azure Blob 存储执行常见方案。 这些示例以 Objective-C 编写,并使用 适用于 iOS 的 Azure 存储客户端库。 涵盖的方案包括上传、列出、下载和删除 Blob 对象。 有关 Blob 的详细信息,请参阅 “后续步骤 ”部分。 还可以下载 示例应用 ,以便快速查看 iOS 应用程序中的 Azure 存储的使用。
若要详细了解 Blob 存储,请参阅 Azure Blob 存储简介。
创建 Azure 存储帐户
创建第一个 Azure 存储帐户的最简单方法是使用 Azure 门户。 若要了解详细信息,请参阅 “创建存储帐户”。
还可以使用 Azure PowerShell、 Azure CLI 或 用于 .NET 的 Azure 存储资源提供程序创建 Azure 存储帐户。
如果目前不想在 Azure 中创建存储帐户,也可以使用 Azurite 存储模拟器在本地环境中运行和测试代码。 有关详细信息,请参阅 使用 Azurite 模拟器进行本地 Azure 存储开发。
将 Azure 存储 iOS 库导入应用程序
可以使用 Azure Storage CocoaPod 或导入 框架 文件将 Azure 存储 iOS 库导入应用程序。 CocoaPod 是推荐的方法,因为它可以更轻松地集成库,但从框架文件中导入对现有项目的侵入性较低。
若要使用此库,需要满足以下条件:
- iOS 8+
- Xcode 7+
CocoaPod
如果尚未执行此作,请在计算机上打开终端窗口并运行以下命令,在计算机上安装 CocoaPods
sudo gem install cocoapods
接下来,在项目目录中(包含 .xcodeproj 文件的目录),创建名为 Podfile 的新文件(无文件扩展名)。 将以下内容添加到 Podfile 并保存。
platform :ios, '8.0' target 'TargetName' do pod 'AZSClient' end
在终端窗口中,导航到项目目录并运行以下命令
pod install
如果 .xcodeproj 在 Xcode 中打开,请将其关闭。 在项目目录中打开将具有 .xcworkspace 扩展名的新创建的项目文件。 这是你将要从现在开始使用的文件。
框架
使用库的另一种方法是手动生成框架:
- 首先,下载或克隆 azure-storage-ios 存储库。
- 进入 azure-storage-ios ->Lib ->Azure 存储客户端库,并在 Xcode 中打开
AZSClient.xcodeproj
。 - 在 Xcode 的左上角,将活动方案从“Azure 存储客户端库”更改为“Framework”。
- 生成项目(⌘+B)。 这将在桌面上创建文件
AZSClient.framework
。
然后,可以通过执行以下作将框架文件导入应用程序:
- 在 Xcode 中创建新项目或打开现有项目。
-
AZSClient.framework
拖放到 Xcode 项目导航器中。 - 根据需要选择“复制项”,然后单击“完成”。
- 在左侧导航中单击项目,然后单击项目编辑器顶部的“ 常规 ”选项卡。
- 在 “链接框架和库 ”部分下,单击“添加”按钮(+)。
- 在已提供的库列表中,搜索
libxml2.2.tbd
并将其添加到项目中。
导入库文件
// Include the following import statement to use blob APIs.
#import <AZSClient/AZSClient.h>
如果使用 Swift,则需要创建桥接标头并导入 <AZSClient/AZSClient.h> :
- 创建头文件
Bridging-Header.h
,并添加上述 import 语句。 - 转到 “生成设置” 选项卡,搜索 Objective-C 桥接标头。
- 双击 Objective-C 桥接标头 的字段,并将路径添加到头文件:
ProjectName/Bridging-Header.h
- 生成项目(⌘+B),以验证桥接标头是否已由 Xcode 选取。
- 直接在任何 Swift 文件中开始使用库,无需导入语句。
配置应用程序以访问 Azure 存储
可通过两种方法对应用程序进行身份验证以访问存储服务:
- 共享密钥:仅使用共享密钥进行测试
- 共享访问签名(SAS):将 SAS 用于生产应用程序
共享密钥
共享密钥身份验证意味着应用程序将使用帐户名称和帐户密钥来访问存储服务。 为了快速显示如何使用此库,我们将在此入门中使用共享密钥身份验证。
警告
仅用于测试目的的共享密钥身份验证! 帐户名称和帐户密钥(提供对关联存储帐户的完整读/写访问权限)将分发给下载应用的每一个人。 这 并非 一种好的做法,因为存在由不受信任的客户端泄露密钥的风险。
使用共享密钥身份验证时,将创建 连接字符串。 连接字符串包括:
- DefaultEndpointsProtocol - 可以选择 HTTP 或 HTTPS。 但是,强烈建议使用 HTTPS。
- 帐户名称 - 存储帐户的名称
- 帐户密钥 - 在 Azure 门户中,导航到存储帐户,然后单击“密钥”图标查找此信息。
- (可选) EndpointSuffix - 这用于具有不同终结点后缀的区域(例如 Azure 中国或 Azure 治理)中的存储服务。
下面是使用共享密钥身份验证的连接字符串示例:
"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here"
共享访问签名 (SAS)
对于移动应用程序,客户端针对 Azure 存储服务对请求进行身份验证的建议方法是使用共享访问签名(SAS)。 SAS 允许您在指定的时间内,使用特定的权限集授予客户端对资源的访问权限。 作为存储帐户所有者,您需要生成 SAS 以供移动客户端使用。 若要生成 SAS,可能需要编写一个单独的服务,用于生成要分发给客户端的 SAS。 出于测试目的,可以使用 Microsoft Azure 存储资源管理器 或 Azure 门户 生成 SAS。 创建 SAS 时,可以指定 SAS 有效的时间间隔,以及 SAS 授予给客户端的权限。
以下示例演示如何使用 Microsoft Azure 存储资源管理器生成 SAS。
连接到订阅
单击您的“存储帐户”,然后单击左下角的“操作”选项卡。 单击“获取共享访问签名”,为 SAS 生成“连接字符串”。
下面是 SAS 连接字符串的一个示例,该字符串在存储帐户的 Blob 服务的服务、容器和对象级别授予读取和写入权限。
"SharedAccessSignature=sv=2015-04-05&ss=b&srt=sco&sp=rw&se=2016-07-21T18%3A00%3A00Z&sig=3ABdLOJZosCp0o491T%2BqZGKIhafF1nlM3MzESDDD3Gg%3D;BlobEndpoint=https://youraccount.blob.core.windows.net"
正如你所看到的,使用 SAS 时,不会在应用程序中公开帐户密钥。 通过查看 共享访问签名:了解 SAS 模型,可以了解有关 SAS 的详细信息以及使用 SAS 的最佳做法。
异步作
注释
针对服务执行请求的所有方法都是异步操作。 在代码示例中,你会发现这些方法具有完成处理程序。 完成处理程序中的代码将在请求完成后运行。 完成处理程序后的代码将在发出请求 时 运行。
创建容器
Azure 存储中的每个 Blob 都必须驻留在容器中。 以下示例演示如何在存储帐户中创建名为 newcontainer 的容器(如果尚不存在)。 为容器选择名称时,请注意上述命名规则。
-(void)createContainer{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"newcontainer"];
// Create container in your Storage account if the container doesn't already exist
[blobContainer createContainerIfNotExistsWithCompletionHandler:^(NSError *error, BOOL exists) {
if (error){
NSLog(@"Error in creating container.");
}
}];
}
可以通过查看 azure 存储资源管理器Microsoft 并验证 newcontainer 是否位于存储帐户的容器列表中来确认这一点是否有效。
设置容器权限
默认情况下,容器的权限配置为 专用 访问。 但是,容器提供了几个不同的容器访问选项:
- 专用:只能由帐户所有者读取容器和 Blob 数据。
- Blob:可以通过匿名请求读取此容器中的 Blob 数据,但容器数据不可用。 客户端无法通过匿名请求枚举容器中的 Blob。
- 容器:可以通过匿名请求读取容器和 Blob 数据。 客户端可以通过匿名请求枚举容器中的 Blob,但无法枚举存储帐户中的容器。
以下示例演示如何创建具有 容器 访问权限的容器,这将允许 Internet 上所有用户进行公共只读访问:
-(void)createContainerWithPublicAccess{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
// Create container in your Storage account if the container doesn't already exist
[blobContainer createContainerIfNotExistsWithAccessType:AZSContainerPublicAccessTypeContainer requestOptions:nil operationContext:nil completionHandler:^(NSError *error, BOOL exists){
if (error){
NSLog(@"Error in creating container.");
}
}];
}
将数据块上传到容器
如 Blob 服务概念部分所述,Blob 存储提供三种不同类型的 Blob:块 Blob、追加 Blob 和页 Blob。 Azure 存储 iOS 库支持所有三种类型的 Blob。 在大多数情况下,建议使用区块 Blob 类型。
以下示例演示如何从 NSString 上传一个块 Blob。 如果此容器中已有同名的 blob 存在,则该 blob 的内容将被覆盖。
-(void)uploadBlobToContainer{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
[blobContainer createContainerIfNotExistsWithAccessType:AZSContainerPublicAccessTypeContainer requestOptions:nil operationContext:nil completionHandler:^(NSError *error, BOOL exists)
{
if (error){
NSLog(@"Error in creating container.");
}
else{
// Create a local blob object
AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob"];
// Upload blob to Storage
[blockBlob uploadFromText:@"This text will be uploaded to Blob Storage." completionHandler:^(NSError *error) {
if (error){
NSLog(@"Error in creating blob.");
}
}];
}
}];
}
可以通过查看 Microsoft Azure 存储资源管理器 并验证容器 (containerpublic)是否包含 blob sampleblob 来确认这一点是否有效。 在此示例中,我们使用了一个公共容器,因此还可以通过转到 Blob URI 来验证此应用程序是否正常工作:
https://nameofyourstorageaccount.blob.core.windows.net/containerpublic/sampleblob
除了从 NSString 上传块 Blob 之外,NSData、NSInputStream 或本地文件也存在类似的方法。
列出容器中的 Blob
以下示例演示如何列出容器中的所有 Blob。 执行此作时,请注意以下参数:
-
continuationToken - 延续标记表示列表作应启动的位置。 如果未提供令牌,它将从头开始列出 Blob。 可以列出任意数量的 blob,从零到设置的最大值。 即使此方法返回零个结果,如果
results.continuationToken
不是 nil,服务中也可能存在更多尚未列出的 blob。 - prefix - 可以指定要用于 Blob 列表的前缀。 仅列出以此前缀开头的 Blob。
- useFlatBlobListing - 如 “命名和引用容器和 Blob” 部分中所述,尽管 Blob 服务是平面存储方案,但可以通过命名包含路径信息的 Blob 来创建虚拟层次结构。 但是,目前不支持非平面列表。 此功能即将推出。 目前,此值应为 “是”。
-
blobListingDetails - 可以指定要在列出 Blob 时包含的项
- AZSBlobListingDetailsNone:仅列出提交的 blob,并且不返回 blob 元数据。
- AZSBlobListingDetailsSnapshots:列出提交的 Blob 和 Blob 快照。
- AZSBlobListingDetailsMetadata:检索列表中返回的每个 Blob 的元数据。
- AZSBlobListingDetailsUncommittedBlobs:列出已提交和未提交的 Blob 数据块。
- AZSBlobListingDetailsCopy:在列表中包括复制属性。
- AZSBlobListingDetailsAll:列出所有可用的已提交 blob、未提交的 Blob 和快照,并返回这些 Blob 的所有元数据和复制状态。
- maxResults - 此作返回的最大结果数。 使用 -1,不设置限制。
- completionHandler - 要与列出操作的结果一起执行的代码块。
在此示例中,帮助程序方法用于在每次返回延续令牌时以递归方式调用列表 blob 方法。
-(void)listBlobsInContainer{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
//List all blobs in container
[self listBlobsInContainerHelper:blobContainer continuationToken:nil prefix:nil blobListingDetails:AZSBlobListingDetailsAll maxResults:-1 completionHandler:^(NSError *error) {
if (error != nil){
NSLog(@"Error in creating container.");
}
}];
}
//List blobs helper method
-(void)listBlobsInContainerHelper:(AZSCloudBlobContainer *)container continuationToken:(AZSContinuationToken *)continuationToken prefix:(NSString *)prefix blobListingDetails:(AZSBlobListingDetails)blobListingDetails maxResults:(NSUInteger)maxResults completionHandler:(void (^)(NSError *))completionHandler
{
[container listBlobsSegmentedWithContinuationToken:continuationToken prefix:prefix useFlatBlobListing:YES blobListingDetails:blobListingDetails maxResults:maxResults completionHandler:^(NSError *error, AZSBlobResultSegment *results) {
if (error)
{
completionHandler(error);
}
else
{
for (int i = 0; i < results.blobs.count; i++) {
NSLog(@"%@",[(AZSCloudBlockBlob *)results.blobs[i] blobName]);
}
if (results.continuationToken)
{
[self listBlobsInContainerHelper:container continuationToken:results.continuationToken prefix:prefix blobListingDetails:blobListingDetails maxResults:maxResults completionHandler:completionHandler];
}
else
{
completionHandler(nil);
}
}
}];
}
下载数据块 (Blob)
以下示例演示如何将 Blob 下载到 NSString 对象。
-(void)downloadBlobToString{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
// Create a local blob object
AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob"];
// Download blob
[blockBlob downloadToTextWithCompletionHandler:^(NSError *error, NSString *text) {
if (error) {
NSLog(@"Error in downloading blob");
}
else{
NSLog(@"%@",text);
}
}];
}
删除 Blob
以下示例演示如何删除 Blob。
-(void)deleteBlob{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
// Create a local blob object
AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob1"];
// Delete blob
[blockBlob deleteWithCompletionHandler:^(NSError *error) {
if (error) {
NSLog(@"Error in deleting blob.");
}
}];
}
删除 Blob 容器
以下示例演示如何删除容器。
-(void)deleteContainer{
NSError *accountCreationError;
// Create a storage account object from a connection string.
AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];
if(accountCreationError){
NSLog(@"Error in creating account.");
}
// Create a blob service client object.
AZSCloudBlobClient *blobClient = [account getBlobClient];
// Create a local container object.
AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];
// Delete container
[blobContainer deleteContainerIfExistsWithCompletionHandler:^(NSError *error, BOOL success) {
if(error){
NSLog(@"Error in deleting container");
}
}];
}
后续步骤
了解如何从 iOS 使用 Blob 存储后,请按照以下链接了解有关 iOS 库和存储服务的详细信息。
如果对此库有疑问,请随时发布到 我们的Microsoft问答问题页 或 Stack Overflow。 如果有有关 Azure 存储的功能建议,请发布到 Azure 存储反馈。