> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quickblox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Content

> Learn how to store and access files with QuickBlox file storage.

The content module allows storing rich chat attachments, app content, and settings without having to republish them. Using a web interface you or your clients can control and make instant changes to the apps.

Visit [Key Concepts](/docs/key-concepts) page to learn the most important QuickBlox concepts.

## Before you begin

1. Register a [QuickBlox account](https://admin.quickblox.com/signin). This is a matter of a few minutes and you will be able to use this account to build your apps.
2. Configure QuickBlox SDK for your app. Check out [Setup](/sdks/ios-setup) page for more details.
3. Create a user session to be able to use QuickBlox functionality. See [Authentication](/sdks/ios-authentication) page to learn how to do it.

## Retrieve files

Get a list of files for a current user using the code snippet below.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    let page = QBGeneralResponsePage(currentPage: 1, perPage: 20)
    QBRequest.blobs(for: page, successBlock: { (response, page, blobs) in

    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBGeneralResponsePage *page = [QBGeneralResponsePage responsePageWithCurrentPage:1 perPage:20];

    [QBRequest blobsForPage:page successBlock:^(QBResponse *response, QBGeneralResponsePage *page, NSArray *blobs) {

    } errorBlock:^(QBResponse *response) {

    }];
    ```
  </Tab>
</Tabs>

## Upload file

Upload a file to the cloud using the following code snippet.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    // your file - this is an image in our case
    guard let imageData = myImage?.pngData() else {
        return
    }
    QBRequest.tUploadFile(imageData, fileName: "myImage", contentType: "image/png", isPublic: true, successBlock: { (response, uploadedBlob) in

    }, statusBlock: { (request, status)  in
        // Update UI with upload progress
    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    // your file - this is an image in our case
    NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"arrow.png"]);

    [QBRequest TUploadFile:imageData fileName:@"arrow.png" contentType:@"image/png" isPublic:NO successBlock:^(QBResponse *response, QBCBlob *blob) {

    } statusBlock:^(QBRequest *request, QBRequestStatus *status) {
        // Update UI with upload progress
    } errorBlock:^(QBResponse *response) {

    }];
    ```
  </Tab>
</Tabs>

The maximum size of the uploaded file depends on the membership plan.

| Basic           | Startup | Growth | HIPAA | Enterprise |                                                                 |
| --------------- | ------- | ------ | ----- | ---------- | --------------------------------------------------------------- |
| File size limit | 10 Mb   | 25 Mb  | 50Mb  | 50Mb       | [Contact our sales team](https://quickblox.com/enterprise/#get) |

## Update file

Update a previously uploaded file in the cloud using the `tUpdateFile(with:file:)` method below. Set the `isNew` field as `true` if you want to update a file.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    // your new file - this is an image in our case
    guard let newImageData = myNewImage?.pngData() else {
        return
    }

    let existingBlob: QBCBlob = QBCBlob() // previously received Blob
    existingBlob.isNew = true // set as true if you want to update blob's file.

    QBRequest.tUpdateFile(with: newImageData, file: existingBlob, successBlock: { (response) in

    }, statusBlock: { (request, status)  in
        // update UI with upload progress
    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    // your new file - this is an image in our case
    NSData *newImageData = UIImagePNGRepresentation([UIImage imageNamed:@"arrow.png"]);

    QBCBlob * existingBlob = [[QBCBlob alloc] init]; // previously received Blob
    existingBlob.isNew = YES; // set as YES if you want to update blob's file

    [QBRequest TUpdateFileWithData:newImageData file:existingBlob successBlock:^(QBResponse * _Nonnull response) {

    } statusBlock:^(QBRequest *request, QBRequestStatus *status) {
        // update UI with upload progress
    } errorBlock:^(QBResponse *response) {

    }];
    ```
  </Tab>
</Tabs>

| Argument     | Required | Description                                                     |
| ------------ | -------- | --------------------------------------------------------------- |
| newImageData | Yes      | A new file in NSData format.                                    |
| existingBlob | Yes      | A previously obtained blob witha file that needs to be updated. |

## Download file by UID

If the file is public then it's possible to download it without a session token.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    let uid = "d816966db53640e68b304a3cd4e5c0c100"

    QBRequest.downloadFile(withUID: uid, successBlock: { (response, fileData)  in

    }, statusBlock: { (request, status) in
        let progress = CGFloat(status.percentOfCompletion)
    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    NSString *uid = @"d816966db53640e68b304a3cd4e5c0c100";

    [QBRequest downloadFileWithUID:uid successBlock:^(QBResponse *response, NSData *fileData) {

    } statusBlock:^(QBRequest *request, QBRequestStatus *status) {
        NSLog(@"download progress: %f", status.percentOfCompletion);
    } errorBlock:^(QBResponse *response) {

    }];
    ```
  </Tab>
</Tabs>

## Get file info

Get information about a file by ID using the method below. This method allows to load the file description model from the server, not the content of the file itself.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBRequest.blob(withID: 1441441, successBlock: { (response, blob) in
        // content type in mime format.
        let blobContentType = blob.contentType

        // file name.
        let blobName = blob.name;

        // status of the File.
        let blobStatus = blob.status;

        // date when the file upload has been completed.
        let blobCompletedAt = blob.completedAt;

        // the size of file in bytes, readonly
        let blobSize = blob.size;

        // file unique identifier.
        let blobUID = blob.uid;

        // last read file time.
        let blobLastReadAccessTs = blob.lastReadAccessTs;

        // an instance of BlobObjectAccess.
        let blobObjectAccess = blob.blobObjectAccess;

        // coma separated string with file's tags.
        let blobTags = blob.tags;

        // file's visibility.
        let blobIsPublic = blob.isPublic;

        // set as YES if you want to update blob's file.
        let blobIsNew = blob.isNew;

    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    [QBRequest blobWithID:1441441 successBlock:^(QBResponse * _Nonnull response, QBCBlob * _Nonnull blob) {

        // content type in mime format.
        NSString *blobContentType = blob.contentType;

        // file name.
        NSString *blobName = blob.name;

        // status of the File.
        QBCBlobStatus blobStatus = blob.status;

        // date when the file upload has been completed.
        NSDate *blobCompletedAt = blob.completedAt;

        // the size of file in bytes, readonly
        NSUInteger blobSize = blob.size;

        // file unique identifier.
        NSString *blobUID = blob.UID;

        // last read file time.
        NSDate *blobLastReadAccessTs = blob.lastReadAccessTs;

        // an instance of BlobObjectAccess.
        QBCBlobObjectAccess *blobObjectAccess = blob.blobObjectAccess;

        // coma separated string with file's tags.
        NSString *blobTags = blob.tags;

        // file's visibility.
        BOOL blobIsPublic = blob.isPublic;

        // set as YES if you want to update blob's file.
        BOOL blobIsNew = blob.isNew;

    } errorBlock:^(QBResponse *response) {

    }];
    ```
  </Tab>
</Tabs>

| Argument     | Required | Description                                                                                                                                  |
| ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| fileId       | yes      | ID of the file/blob.                                                                                                                         |
| successBlock | yes      | Specifies a response block that is called if the request is succeeded. As a result, the response will contain a blob/file description model. |
| errorBlock   | yes      | Specifies a response block that is called in case an error is occurred.                                                                      |

## Get file URL

There are two types of file URLs that can be obtained: private and public.

* **Public URL** allows anyone to access the file, no authorization token is needed.
* **Private URL** can be accessed only by QuickBlox user with a session token.

### Get public URL

To receive a public URL, use the code snippet below.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    let file: QBCBlob = ...
    let publicUrl = file.publicUrl()

    // or if you have only file UID
    let fileUID = "6221dd49a1bb46cfb61efe62c4526bd800"
    let publicUrl = QBCBlob.publicUrl(forFileUID: fileUID)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBCBlob *file = ...;
    NSString *publicUrl = [file publicUrl];

    // or if you have only file UID
    NSString *fileUID = @"6221dd49a1bb46cfb61efe62c4526bd800";
    NSString *publicUrl = [QBCBlob publicUrlForFileUID:fileUID];
    ```
  </Tab>
</Tabs>

| Argument | Required | Description                         |
| -------- | -------- | ----------------------------------- |
| fileUID  | yes      | File unique identifier. Type String |

### Get private URL

To get a private URL of the uploaded file, use the following code snippet.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    let file: QBCBlob = ...
    let privateUrl = file.privateUrl()

    // or if you have only file UID
    let fileUID = "6221dd49a1bb46cfb61efe62c4526bd800"
    let privateUrl = QBCBlob.privateUrl(forFileUID: fileUID)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    QBCBlob *file = ...;
    NSString *privateUrl = [file privateUrl];

    // or if you have only file UID
    NSString *fileUID = @"6221dd49a1bb46cfb61efe62c4526bd800";
    NSString *privateUrl = [QBCBlob privateUrlForFileUID:fileUID];
    ```
  </Tab>
</Tabs>

| Argument | Required | Description                         |
| -------- | -------- | ----------------------------------- |
| fileUID  | yes      | File unique identifier. Type String |

## Delete file

Delete a file by file ID using the `deleteBlob()` method.

<Tabs>
  <Tab title="Swift">
    ```Swift theme={null}
    QBRequest.deleteBlob(withID: 1441441, successBlock: { (response) in

    }, errorBlock: { (response) in

    })
    ```
  </Tab>

  <Tab title="Objective-C">
    ```Objective-C theme={null}
    `[QBRequest deleteBlobWithID:1441441 successBlock:^(QBResponse * _Nonnull response) {

    } errorBlock:^(QBResponse * _Nonnull response) {

    }];
    ```
  </Tab>
</Tabs>

| Argument     | Required | Description                                                             |
| ------------ | -------- | ----------------------------------------------------------------------- |
| fileId       | yes      | ID of the file/blob.                                                    |
| successBlock | yes      | Specifies a response block that is called if the request is succeeded.  |
| errorBlock   | yes      | Specifies a response block that is called in case an error is occurred. |
