SqliteFlutter应用程序在Android模拟器上工作,但不在IOS模拟器上

5vf7fwbs  于 2023-05-02  发布在  iOS
关注(0)|答案(1)|浏览(132)

嗨,我已经遵循了YouTube教程,并提出了一个SQLite应用程序,在Android模拟器上完美工作,但当我尝试在iOS模拟器上运行时,我得到以下错误消息:
无法构建iOS应用程序错误(Xcode):文件未找到:/Applications/ www.example.com
错误(Xcode):链接器命令失败,退出代码为% 1(使用-v查看调用)
无法为模拟器生成应用程序。在iPhone 13上启动应用程序时出错。
我的数据库助手文件:

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart' as sql;

class SQLHelper {
  //method to create table
  static Future<void> createTables(sql.Database database) async {
    await database.execute("""CREATE TABLE sets(
      id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
      exercise_name TEXT,
      total_weight TEXT,
      total_reps TEXT,
      date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
      )
      """);
  }

//method to open the database called db
  static Future<sql.Database> db() async {
    return sql.openDatabase('dbsets.db', version: 1,
        onCreate: (sql.Database database, int version) async {
      print('Creating Table');
      await createTables(database); //calling that create table method above
    });
  }

//method to create an item to insert into the database table
  static Future<int> createItem(
    String exercise_name,
    String? total_weight,
    String? total_reps,
  ) async {
    final db = await SQLHelper.db(); //opening the database
    final data = {
      'exercise_name': exercise_name,
      'total_weight': total_weight,
      'total_reps': total_reps,
      'date': DateTime.now().toString()
    }; //making map to insert
    final id = await db.insert(
        //inserting that data map
        'sets',
        data, //items is table name and data is the map we made
        conflictAlgorithm: sql
            .ConflictAlgorithm.replace); //best practice to prevent duplicates
    return id;
  }

//this will return a list of maps
//gets called when app is launched and will get all our shit from the database
  static Future<List<Map<String, dynamic>>> getItems() async {
    //getItems will be a List
    final db = await SQLHelper.db(); //get connection
    return db.query('sets', orderBy: "id");
  }

//method for getting 1 item from the database based on id
  static Future<List<Map<String, dynamic>>> getItem(int id) async {
    final db = await SQLHelper.db();
    return db.query('sets',
        where: "id = ?", whereArgs: [id], limit: 1); //limit 1 means get only 1
  }

  //UPDATING AN ENTRY
  static Future<int> updateItem(
    int id,
    String exercise_name,
    String? total_weight,
    String? total_reps,
  ) async {
    final db = await SQLHelper.db();
    final data = {
      'exercise_name': exercise_name,
      'total_weight': total_weight,
      'total_reps': total_reps,
      'date': DateTime.now().toString()
    }; //

    final result =
        await db.update('sets', data, where: "id= ?", whereArgs: [id]);
    return result;
  }

  //Deleting an Entry
  static Future<void> deleteItem(int id) async {
    final db = await SQLHelper.db();
    try {
      await db.delete("sets", where: "id = ?", whereArgs: [id]);
    } catch (err) {
      debugPrint("Something went wrong when deleting an item: $err");
    }
  }
}

我的主。 dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:labud_fit_concept/sql_helper.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  //creating a list of maps
  List<Map<String, dynamic>> _sets = [];

  bool _isLoading = true;

  //this method will store everything from out database in data
  void _refreshSets() async {
    final data = await SQLHelper.getItems(); //getItems returns a list of maps
    setState(() {
      _sets = data;
      _isLoading = false; //finished loading
    });
  }

  //now to call this refreshJournals method
  @override
  void initState() {
    // TODO: implement initState
    _refreshSets();
    print("number of sets: ${_sets.length}");
  }

  final TextEditingController _exercisenameController = TextEditingController();
  final TextEditingController _totalweightController = TextEditingController();
  final TextEditingController _totalrepsController = TextEditingController();

  void _showForm(int? id) async {
    if (id != null) {
      // id == null -> create new item
      // id != null -> update an existing item
      final existingSet = _sets.firstWhere((element) => element['id'] == id);
      _exercisenameController.text = existingSet['exercise_name'];
      _totalweightController.text = existingSet['total_weight'];
      _totalrepsController.text = existingSet['total_reps'];
    }
    showModalBottomSheet(
        context: context,
        elevation: 5,
        isScrollControlled: true,
        builder: (_) => Container(
              padding: EdgeInsets.only(
                top: 15,
                left: 15,
                right: 15,
                // this will prevent the soft keyboard from covering the text fields
                bottom: MediaQuery.of(context).viewInsets.bottom + 120,
              ),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  TextField(
                    controller: _exercisenameController,
                    decoration:
                        const InputDecoration(hintText: 'Exercise Name'),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  TextField(
                    controller: _totalweightController,
                    decoration: const InputDecoration(hintText: 'Weight'),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  TextField(
                    controller: _totalrepsController,
                    decoration: const InputDecoration(hintText: 'Reps'),
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  ElevatedButton(
                    //button to confirm entry
                    onPressed: () async {
                      // Save new journal
                      if (id == null) {
                        //if the item doesnt exist
                        await _addItem();
                      }

                      if (id != null) {
                        //if it exists update it instead
                        await _updateItem(id);
                      }

                      // Clear the text fields
                      _exercisenameController.text = '';
                      _totalweightController.text = '';
                      _totalrepsController.text = '';

                      //closing the popup
                      Navigator.of(context).pop();
                    },
                    //the text of the button change depending on if its new or updating an existing
                    child: Text(id == null ? 'Create New' : 'Update'),
                  )
                ],
              ),
            ));
  }

// Insert a new journal to the database
  Future<void> _addItem() async {
    await SQLHelper.createItem(_exercisenameController.text,
        _totalweightController.text, _totalrepsController.text);
    _refreshSets(); //getting all of our database calls again
    print("number of journals: ${_sets.length}");
  }

  // Update an existing journal
  Future<void> _updateItem(int id) async {
    await SQLHelper.updateItem(id, _exercisenameController.text,
        _totalweightController.text, _totalrepsController.text);
    _refreshSets();
  }

  // Delete an item
  void _deleteItem(int id) async {
    await SQLHelper.deleteItem(id);
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
      content: Text('Successfully deleted a Set!'),
    ));
    _refreshSets();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
          //so its a listview so we use our _journals list to build it
          itemCount: _sets.length,
          itemBuilder: (context, index) => Card(
                color: Color.fromARGB(255, 129, 142, 255),
                margin: const EdgeInsets.all(15),
                child: CupertinoListTile(
                  title: Text(_sets[index]['exercise_name']),
                  subtitle: Text(_sets[index]['total_weight']),
                  trailing: SizedBox(
                    width: 100,
                    child: Row(
                      children: [
                        IconButton(
                          onPressed: () => _showForm(_sets[index]['id']),
                          icon: Icon(Icons.edit),
                        ),
                        IconButton(
                          onPressed: () => _deleteItem(_sets[index]['id']),
                          icon: Icon(Icons.delete),
                        ),
                      ],
                    ),
                  ),
                ),
              )),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => _showForm(null),
      ),
    );
  }
}
7cwmlq89

7cwmlq891#

我不是iOS应用程序开发方面的Maven,但我会尝试提供一般故障排除:
1.清理和重建项目:与任何项目一样,有时缓存的数据或过时的生成可能会导致问题。尝试从iOS模拟器中手动删除应用程序,重新启动模拟器,然后通过运行flutter clean命令清理和重建项目,然后运行flutter build ios命令。
1.检查数据库路径:验证您使用的数据库文件的路径是否正确。在iOS中,应用的文件系统是沙箱化的,访问应用文件系统的文件路径与Android上的不同。请确保您使用的文件路径与运行应用的平台一致。
1.调试:如果上述步骤都不起作用,您可以使用Xcode的调试器来单步执行代码,并查看问题发生的位置。您可以在代码中设置断点,然后在调试模式下运行应用,以单步执行代码并查看错误发生的位置。

相关问题