Flutter推荐系统插件recco的使用

Flutter推荐系统插件recco的使用

概述

个性化且用户友好的健康与健身建议系统,基于用户的独特兴趣、动机和健康行为。无论是希望改善他们的健身水平、管理压力,还是简单地过上更充实的生活,Recco 都旨在帮助他们实现潜力。

了解更多关于Recco SDK:

使用

pubspec.yaml 文件中添加以下依赖:

dependencies:
  recco: 1.3.0

在Android上设置

GitHub Packages

此Flutter插件内部依赖于Recco Android SDK,该SDK通过GitHub Packages公开其组件。因此,需要配置GitHub Packages。请参阅个人访问令牌部分以获取有效的凭据。一旦拥有有效的GitHub PAT,请配置您的 gradle.properties 文件(位于 ~/.gradle/ 目录下)。

gprUser=your-github-user-here
gprKey=your-github-PAT-here

设置GitHub凭证后,在您的 app/build.gradle 文件中添加以下配置以便获取包:

repositories {
    mavenLocal()
    maven { url 'https://jitpack.io' }
    maven {
        name = "GithubPackages"
        url = "https://maven.pkg.github.com/SignificoHealth/recco-android-sdk"
        credentials {
            username = gprUser
            password = gprKey
        }
    }
}

检查Android Gradle插件版本和源兼容性

确保在根级 build.gradle 文件中Android Gradle插件版本至少为 7.4.0

buildscript {
    ext.kotlin_version = '1.9.0'
    ...
}    

同时,确保在您的应用 build.gradle 文件中提供了以下源兼容性配置:

android {
    //...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_17.toString()
    }
}

Hilt依赖

Recco Android SDK内部依赖于Hilt。如果您的Android应用尚未使用Hilt,则需要进行以下设置:

在根级 build.gradle 文件中,添加Hilt插件:

plugins {
    // ...
    id 'com.google.dagger.hilt.android' version "2.47" apply false
    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}

然后,在应用 build.gradle 文件中解析Kapt和Hilt插件,并添加Hilt依赖:

apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.dagger.hilt.android'

dependencies {
    implementation "com.google.dagger:hilt-android:2.47"
    kapt "com.google.dagger:hilt-android-compiler:2.47"
}

作为最后一步,装饰您的 Application 类以带有 @HiltAndroidApp 注解:

@HiltAndroidApp
class ShowcaseApp : FlutterApplication() {
}

并在 AndroidManifest.xml 中添加它:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:name=".ShowcaseApp"

您可以查看Flutter示例Android应用以获取更多详细信息。

在iOS上设置

此Flutter插件内部依赖于Recco iOS SDK,该SDK通过CocoaPods公开其组件。重要提示:请确保您的Cocoapods主仓库已更新。运行 pod repo update。之后,您需要将Recco pod添加到您的 Podfile 中:

pod 'ReccoUI'

注意:请确保在 Podfile 中定义了 platform :ios, '14.0' 或更高版本。

ReccoPlugin 新实例

final Recco _reccoPlugin = Recco();

初始化

在应用的 initState 中初始化Recco SDK:

Future<void> _initializeRecco(String clientSecret) async {
    try {
      _reccoPlugin.initialize(clientSecret, ReccoStyle.spring(
         androidFont: AndroidFont.poppins,
         iosFont: IOSFont.sfPro
      ));
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
  }

作为初始化的一部分,您需要提供一个 ReccoStyle 实例来配置一些定制入口点:

  • IOSFontAndroidFont:这些组件公开了每个平台可用的预定义字体集。
  • ReccoStyleColors:定义了可自定义的颜色调色板。有现成的调色板可供选择,如fresh或ocean。

登录

Future<String> _loginReccoSDK(String userId) async {
    try {
        _reccoPlugin.login(userId);
    } on PlatformException catch (e) {
        debugPrint("Error: '${e.message}'.");
    }
    return userId;
}

登出

Future<void> _logoutReccoSDK() async {
    try {
      _reccoPlugin.logout();
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
}

打开Recco UI

Future<void> _openReccoUI() async {
    try {
      _reccoPlugin.openReccoUI();
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
}

完整示例

以下是完整的示例代码,展示了如何使用Recco插件:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:recco/recco.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'login_content.dart';
import 'logout_content.dart';

enum ScreenState { loginForm, logout }

const String userIdPref = "userIdKey";

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Recco Showcase',
      theme: ThemeData(
          colorScheme: ColorScheme.fromSwatch().copyWith(
        primary: const Color(0xFF463738),
        onPrimary: const Color(0xFFF6F190),
        secondary: const Color(0xFFF6F190),
        onSecondary: const Color(0xFFEBEBEB),
        surface: const Color(0xFFEBEBEB),
      )),
      home: const MyHomePage(title: 'Recco - Flutter Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Recco _reccoPlugin = Recco();
  final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  late ScreenState _state;
  late Future<String> _userId;
  final TextEditingController _textUserIdController = TextEditingController();

  [@override](/user/override)
  void initState() {
    _initializeRecco(
        "99ItJU5LzZKmLggRvGJMWWxd9mEek7MKedmkZ4_3Wb4yKVJ17lm3K6Smh8eUp3GuFIPq0-w");

    super.initState();
    _userId = _prefs.then((SharedPreferences prefs) {
      final String userId = prefs.getString(userIdPref) ?? "";
      return userId;
    }).then((value) {
      _state = value.isEmpty ? ScreenState.loginForm : ScreenState.logout;
      _updateScreenState(_state);
      return value;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: FutureBuilder<String>(
            future: _userId,
            builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.waiting:
                  return const CircularProgressIndicator();
                case ConnectionState.active:
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text('Error: ${snapshot.error}');
                  } else {
                    final userId = snapshot.data!;
                    return _successContent(userId);
                  }
              }
            }));
  }

  Widget _successContent(String userId) {
    return Column(
      children: [
        Visibility(
            visible: _state == ScreenState.loginForm,
            child: LoginContent(
              textController: _textUserIdController,
              onLoginClick: () {
                _loginReccoSDK(_textUserIdController.text).then((value) {
                  return _updateUser(value);
                }).then((value) {
                  _updateScreenState(ScreenState.logout);
                });
              },
            )),
        Visibility(
            visible: _state == ScreenState.logout,
            child: LogoutContent(
              text: userId,
              onOpenSdkClick: () => _openReccoUI(),
              onLogoutClick: () {
                _logoutReccoSDK().then((value) {
                  return _updateUser("");
                }).then((value) {
                  _updateScreenState(ScreenState.loginForm);
                });
              },
            )),
      ],
    );
  }

  Future<String> _updateUser(String userId) async {
    final SharedPreferences prefs = await _prefs;
    _userId = prefs.setString(userIdPref, userId).then((bool success) {
      return userId;
    });
    return _userId;
  }

  void _updateScreenState(ScreenState state) {
    setState(() {
      _state = state;
    });
  }

  Future<void> _initializeRecco(String clientSecret) async {
    try {
      _reccoPlugin.initialize(
          clientSecret,
          ReccoStyle.spring(
              androidFont: AndroidFont.poppins, iosFont: IOSFont.sfPro));
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
  }

  Future<String> _loginReccoSDK(String userId) async {
    try {
      _reccoPlugin.login(userId);
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
    return userId;
  }

  Future<void> _logoutReccoSDK() async {
    try {
      _reccoPlugin.logout();
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
  }

  Future<void> _openReccoUI() async {
    try {
      _reccoPlugin.openReccoUI();
    } on PlatformException catch (e) {
      debugPrint("Error: '${e.message}'.");
    }
  }
}

更多关于Flutter推荐系统插件recco的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter推荐系统插件recco的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,实现推荐系统可能需要集成一些专门用于推荐算法的插件或库。虽然没有一个广泛认可的、名为“recco”的官方Flutter插件,但我们可以讨论一些常见的推荐系统实现方式以及如何在Flutter中集成这些功能。

通常,推荐系统会依赖于用户行为数据、内容元数据等来进行推荐。在Flutter应用中,你可以使用Dart语言结合一些机器学习库(如TensorFlow Lite)或调用后端服务(如使用Python编写的推荐引擎)来实现推荐功能。

以下是一个简化的例子,展示了如何在Flutter中集成一个假设的推荐服务。这里,我们假设有一个后端API提供了推荐功能,我们将使用http包来调用这个API。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加http依赖:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3  # 请检查最新版本

2. 创建推荐服务类

创建一个Dart文件(例如recommendation_service.dart),用于封装与推荐API的交互:

import 'dart:convert';
import 'package:http/http.dart' as http;

class RecommendationService {
  final String apiUrl = 'https://your-recommendation-api.com/recommend';

  Future<List<String>> getRecommendations(String userId) async {
    final response = await http.post(
      Uri.parse(apiUrl),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'user_id': userId,
      }),
    );

    if (response.statusCode == 200) {
      List<dynamic> body = jsonDecode(response.body);
      return body.map((dynamic item) => item as String).toList();
    } else {
      throw Exception('Failed to load recommendations');
    }
  }
}

3. 在Flutter应用中使用推荐服务

在你的Flutter组件中,你可以使用上述服务来获取并显示推荐内容:

import 'package:flutter/material.dart';
import 'recommendation_service.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Recommendation App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: RecommendationScreen(),
    );
  }
}

class RecommendationScreen extends StatefulWidget {
  @override
  _RecommendationScreenState createState() => _RecommendationScreenState();
}

class _RecommendationScreenState extends State<RecommendationScreen> {
  final RecommendationService _recommendationService = RecommendationService();
  List<String> _recommendations = [];

  @override
  void initState() {
    super.initState();
    _fetchRecommendations('user123');  // 假设用户ID为'user123'
  }

  Future<void> _fetchRecommendations(String userId) async {
    try {
      _recommendations = await _recommendationService.getRecommendations(userId);
    } catch (error) {
      print('Error fetching recommendations: $error');
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Recommendations'),
      ),
      body: Center(
        child: _recommendations.isEmpty
            ? CircularProgressIndicator()
            : ListView.builder(
                itemCount: _recommendations.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_recommendations[index]),
                  );
                },
              ),
      ),
    );
  }
}

注意事项

  1. 后端API:上面的例子假设你有一个后端API提供推荐服务。你需要根据自己的后端实现来调整API URL和请求格式。

  2. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,比如网络错误、API错误码处理等。

  3. 性能优化:如果推荐列表很大,你可能需要考虑分页加载或懒加载来优化性能。

  4. 安全性:确保你的API请求是安全的,特别是涉及到用户身份认证时。

  5. UI/UX:根据实际需求,你可能需要设计更复杂的UI来展示推荐内容,比如图片、评分、描述等。

这个简化的例子展示了如何在Flutter中集成一个外部推荐服务。根据你的具体需求,你可能需要实现更复杂的逻辑,比如本地缓存、用户行为追踪等。

回到顶部