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