Flutter数据存储插件active_storage的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter数据存储插件active_storage的使用

在本教程中,我们将详细介绍如何在Flutter应用中使用active_storage插件来上传文件到Rails应用中的Active Storage。

获取开始

首先,你需要创建一个ActiveStorage对象,并传入你的Rails后端地址,该地址应包含ActiveStorage::DirectUploadsController(或你自定义的控制器)。

var activeStorage = ActiveStorage(
  directUploadURL: 'http://localhost:3000/rails/active_storage/direct_uploads',
);

然后,你可以调用upload()方法,传入文件名、文件类型和文件实例。例如:

DirectUploadResponse response = await activeStorage.upload(
  fileName: 'picture.jpg',
  fileMimeType: 'image/jpeg',
  file: File('my/picture.jpg'),
);

DirectUploadResponse对象提供了signedId属性。你应该将此值设置为API请求属性,以便你的Rails后端将其设置到由ActiveStorage支持的ActiveRecord模型属性(即带有has_one_attached注解的属性)上。

自定义头部

如果你的Rails后端的上传端点只对已认证用户开放,那么你需要传递一个Authorization头部。你可以通过在调用upload()方法之前,在ActiveStorage实例上调用addHeader()方法来实现这一点。例如:

activeStorage.addHeader(
  'Authorization',
  'Bearer ae38e518bfb4e2b11c2e5cefffe4581e66af07296cfec4b2299ab54a74ef3d8c',
);

你可能还希望在上传请求中添加User-Agent信息。

上传进度

在上传大文件时,向用户提供有关上传进度的反馈非常重要。为此,你可以在upload()方法中传递一个回调函数,该函数将在每次发送字节块到服务器时被调用,并且每次都会接收到一个表示上传进度百分比的double值。例如:

DirectUploadResponse response = await activeStorage.upload(
  fileName: 'large.jpg',
  fileMimeType: 'image/jpeg',
  file: File('pics/large.jpg'),
  onProgress: (percent) {
    print('Uploaded ${percent.toStringAsFixed(2)}%');
  },
);

完整示例

下面是一个完整的示例,展示了如何使用active_storage插件进行文件上传:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:active_storage/active_storage.dart';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Active Storage Demo')),
        body: Center(
          child: UploadButton(),
        ),
      ),
    );
  }
}

class UploadButton extends StatefulWidget {
  [@override](/user/override)
  _UploadButtonState createState() => _UploadButtonState();
}

class _UploadButtonState extends State<UploadButton> {
  String _status = '';

  void _uploadFile() async {
    var activeStorage = ActiveStorage(
      directUploadURL: 'http://localhost:3000/rails/active_storage/direct_uploads',
    );

    // 添加认证头
    activeStorage.addHeader(
      'Authorization',
      'Bearer ae38e518bfb4e2b11c2e5cefffe4581e66af07296cfec4b2299ab54a74ef3d8c',
    );

    try {
      DirectUploadResponse response = await activeStorage.upload(
        fileName: 'large.jpg',
        fileMimeType: 'image/jpeg',
        file: File('pics/large.jpg'),
        onProgress: (percent) {
          setState(() {
            _status = 'Uploaded ${percent.toStringAsFixed(2)}%';
          });
        },
      );
      setState(() {
        _status = 'Upload successful! Signed ID: ${response.signedId}';
      });
    } catch (e) {
      setState(() {
        _status = 'Upload failed: $e';
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: _uploadFile,
          child: Text('Upload File'),
        ),
        SizedBox(height: 20),
        Text(_status),
      ],
    );
  }
}

更多关于Flutter数据存储插件active_storage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据存储插件active_storage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,active_storage 并不是一个官方的或广泛认可的用于数据存储的插件。通常情况下,Flutter开发者会使用一些其他的插件来处理数据存储需求,比如 shared_preferencessqflitehive 等。

不过,如果你是在寻找一个与Rails中的Active Storage功能相似的Flutter插件来处理文件存储(比如图片、视频等),那么你可能需要自己实现这样的功能,或者寻找一个接近的第三方库。由于Flutter本身是一个跨平台框架,它并没有直接集成Rails的Active Storage功能。

以下是一个使用 path_providerfile_picker 插件在Flutter中实现简单文件存储和读取的例子。这两个插件可以帮助你访问设备的存储路径和选择文件。虽然这不是Active Storage的直接替代品,但它提供了一个基本的文件存储机制。

首先,确保在你的 pubspec.yaml 文件中添加这些依赖:

dependencies:
  flutter:
    sdk: flutter
  path_provider: ^2.0.0
  file_picker: ^4.0.0

然后,运行 flutter pub get 来获取这些依赖。

接下来,在你的 Dart 代码中,你可以使用这些插件来保存和读取文件:

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('File Storage Example'),
        ),
        body: FileStorageScreen(),
      ),
    );
  }
}

class FileStorageScreen extends StatefulWidget {
  @override
  _FileStorageScreenState createState() => _FileStorageScreenState();
}

class _FileStorageScreenState extends State<FileStorageScreen> {
  String? _filePath;

  Future<void> _pickFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.any,
    );

    if (result != null) {
      File file = File(result.files.single.path!);
      String appDocDir = (await getApplicationDocumentsDirectory()).path;
      String fileName = file.path.split('/').last;
      String newPath = '$appDocDir/$fileName';
      File newFile = File(newPath);

      await file.copy(newFile.path);

      setState(() {
        _filePath = newPath;
      });
    }
  }

  Future<void> _readFile() async {
    if (_filePath != null) {
      File file = File(_filePath!);
      String contents = await file.readAsString();
      print(contents);
      // 这里你可以根据需要处理文件内容,比如显示在UI上
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            onPressed: _pickFile,
            child: Text('Pick File'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _readFile,
            child: Text('Read File'),
          ),
          if (_filePath != null)
            Text('File Path: $_filePath'),
        ],
      ),
    );
  }
}

在这个例子中,_pickFile 方法允许用户从设备中选择一个文件,并将其复制到应用程序的文档目录中。_readFile 方法则读取并打印出文件的内容。注意,这个例子假设你正在读取一个文本文件;如果你需要读取二进制文件(如图片),你应该使用 readAsBytes 方法而不是 readAsString

这个示例只是一个起点,你可能需要根据自己的需求进一步定制和扩展文件存储和处理的功能。

回到顶部