Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage(swift): update swift storage with storage path #7142

Closed
wants to merge 9 commits into from
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Customization
## Customization (Deprecated)

### Customize Object Key Path

Expand Down
135 changes: 135 additions & 0 deletions src/fragments/lib/storage/ios/download.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,51 @@ There are three ways of getting data that was previously uploaded:

You can download to in-memory buffer [Data](https://developer.apple.com/documentation/foundation/data) object with `Amplify.Storage.downloadData`:

#### With StoragePath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a short blurb about how this is new in the latest version and we recommend customers to use this.

Copy link
Contributor Author

@phantumcode phantumcode Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a callout for each of the new API. I didn't specify a specific Amplify version, as this callout can be common and used across all native platforms.

<BlockSwitcher>

<Block name="Async/Await">

```swift
let downloadTask = Amplify.Storage.downloadData(path: .fromString("example/path"))
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
let data = try await downloadTask.value
print("Completed: \(data)")
```

</Block>

<Block name="Combine">

```swift
let downloadTask = Amplify.Storage.downloadData(path: .fromString("example/path"))
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}

let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: { data in
print("Completed: \(data)")
}
```

</Block>

</BlockSwitcher>

#### With Key (Deprecated)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add context that this has been deprecated from the latest version and we recommend using StoragePath above instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a callout at the top of the download page now.

<BlockSwitcher>

<Block name="Async/Await">
Expand Down Expand Up @@ -51,6 +96,69 @@ let resultSink = downloadTask

You can download to a file [URL](https://developer.apple.com/documentation/foundation/url) with `Amplify.Storage.downloadFile`:

#### With StoragePath
<BlockSwitcher>

<Block name="Async/Await">

```swift
let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")

let downloadTask = Amplify.Storage.downloadFile(
path: .fromString("example/path"),
local: downloadToFileName,
options: nil
)
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
try await downloadTask.value
print("Completed")
```

</Block>

<Block name="Combine">

```swift
let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")

let downloadTask = Amplify.Storage.downloadFile(
path: .fromString("example/path"),
local: downloadToFileName,
options: nil
)
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}

let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: {
print("Completed")
}
```

</Block>

</BlockSwitcher>

#### With Key (Deprecated)
<BlockSwitcher>

<Block name="Async/Await">
Expand Down Expand Up @@ -115,17 +223,42 @@ let resultSink = downloadTask
## Generate a download URL

You can also retrieve a URL for the object in storage:
<BlockSwitcher>
<Block name="With StoragePath">
```swift
let url = try await Amplify.Storage.getURL(path: .fromString("example/path"))
print("Completed: \(url)")
```
</Block>

<Block name="With Key (Deprecated)">
```swift
let url = try await Amplify.Storage.getURL(key: "ExampleKey")
print("Completed: \(url)")
```
</Block>
</BlockSwitcher>

When creating a downloadable URL, you can choose to check if the file exists by setting `validateObjectExistence` to
`true` in `AWSStorageGetURLOptions`. If the file is inaccessible or does not exist, a `StorageError` is thrown.
This allows you to check if an object exists during generating the presigned URL, which you can then use to download
that object.

<BlockSwitcher>
<Block name="With StoragePath">
```swift
let url = try await Amplify.Storage.getURL(
path: .fromString("example/path"),
options: .init(
pluginOptions: AWSStorageGetURLOptions(
validateObjectExistence: true
)
)
)
```
</Block>

<Block name="With Key (Deprecated)">
```swift
let url = try await Amplify.Storage.getURL(
key: "ExampleKey",
Expand All @@ -136,7 +269,9 @@ let url = try await Amplify.Storage.getURL(
)
)
```
</Block>

</BlockSwitcher>
## Cancel, Pause, Resume

Calls to `downloadData` or `downloadFile` return a reference to the task that is actually performing the download.
Expand Down
67 changes: 67 additions & 0 deletions src/fragments/lib/storage/ios/getting-started/40_upload.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,70 @@
#### With StoragePath
<BlockSwitcher>

<Block name="Async/Await">

```swift
func uploadData() async throws {
let dataString = "Example file contents"
let data = Data(dataString.utf8)
let uploadTask = Amplify.Storage.uploadData(
path: .fromString("example/path"),
data: data
)
Task {
for await progress in await uploadTask.progress {
print("Progress: \(progress)")
}
}
let value = try await uploadTask.value
print("Completed: \(value)")
}
```

</Block>

<Block name="Combine">

```swift
// In your type's instance variables
var resultSink: AnyCancellable?
var progressSink: AnyCancellable?

// ...

func uploadData() {
let dataString = "Example file contents"
let data = Data(dataString.utf8)
let uploadTask = Amplify.Storage.uploadData(
path: .fromString("example/path"),
data: data
)
progressSink = uploadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}

resultSink = uploadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: { data in
print("Completed: \(data)")
}
}
```

</Block>

</BlockSwitcher>



#### With Key (Deprecated)
<BlockSwitcher>

<Block name="Async/Await">
Expand Down
53 changes: 48 additions & 5 deletions src/fragments/lib/storage/ios/list.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
You can list all of the objects uploaded under a given prefix by setting the `pageSize`. If the `pageSize` is set lower than the total file size available, A single `Storage.list` call only returns a subset of all the files. To list all the files with multiple calls, the user can use the `nextToken` from the previous call response.

This will list all public files:
#### With StoragePath
<BlockSwitcher>

<Block name="Async/Await">

```swift
let options = StorageListRequest.Options(pageSize: 1000)
let listResult = try await Amplify.Storage.list(
path: .fromString("example/path"),
options: options
)
listResult.items.forEach { item in
print("Path: \(item.path)")
}
```

</Block>

<Block name="Combine">

```swift
let sink = Amplify.Publisher.create {
let options = StorageListRequest.Options(pageSize: 1000)
try await Amplify.Storage.list(
path: .fromString("example/path"),
options: options
)
}.sink {
if case let .failure(error) = $0 {
print("Failed: \(error)")
}
}
receiveValue: { listResult in
print("Completed")
listResult.items.forEach { item in
print("Path: \(item.path)")
}
}
```

</Block>

</BlockSwitcher>

#### With Key (Deprecated)
<BlockSwitcher>

<Block name="Async/Await">
Expand Down Expand Up @@ -39,7 +82,7 @@ receiveValue: { listResult in

</BlockSwitcher>

You can also list private or protected files by passing options. For example, to list all protected files owned by a user identified by the ID `otherUserID`:
You can also list private or protected files by passing options. For example, to list all protected files owned by a user identified by the ID `otherUserID` (This behavior is deprecated):

<BlockSwitcher>

Expand All @@ -49,7 +92,7 @@ You can also list private or protected files by passing options. For example, to
let options = StorageListRequest.Options(accessLevel: .protected, targetIdentityId: "otherUserID", pageSize: 1000)
let listResult = try await Amplify.Storage.list(options: options)
listResult.items.forEach { item in
print("Key: \(item.key)")
print("Path: \(item.path)")
}
```

Expand All @@ -69,7 +112,7 @@ let sink = Amplify.Publisher.create {
receiveValue: { listResult in
print("Completed")
listResult.items.forEach { item in
print("Key: \(item.key)")
print("Path: \(item.path)")
}
}
```
Expand All @@ -78,7 +121,7 @@ receiveValue: { listResult in

</BlockSwitcher>

If you like limit the response to keys that begin with the specified path provide the path options:
If you like limit the response to keys that begin with the specified path provide the path options (This behavior is deprecated):

<BlockSwitcher>

Expand Down
34 changes: 33 additions & 1 deletion src/fragments/lib/storage/ios/remove.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
Delete an object uploaded to S3 by using `Amplify.Storage.remove` and specify the key:
Delete an object uploaded to S3 by using `Amplify.Storage.remove`:

#### With StoragePath
<BlockSwitcher>

<Block name="Async/Await">

```swift
let removedObject = try await Amplify.Storage.remove(path: .fromString("example/path"))
print("Deleted \(removedObject)")
```

</Block>

<Block name="Combine">

```swift
let sink = Amplify.Publisher.create {
try await Amplify.Storage.remove(path: .fromString("example/path"))
}.sink {
if case let .failure(error) = $0 {
print("Failed: \(error)")
}
}
receiveValue: { removedObject in
print("Deleted \(removedObject)")
}
```

</Block>

</BlockSwitcher>

#### With Key (Deprecated)
<BlockSwitcher>

<Block name="Async/Await">
Expand Down
Loading
Loading