简介:在iOS开发中,数据库操作尤为重要,尤其是存储用户数据或实现本地化功能时。本案例聚焦于使用FMDB库进行数据库查询操作,重点是实现一个省市选择器,利用弹出视图展示并交互。通过本项目,开发者将学习如何使用FMDB库的 FMDatabase
、 FMStatement
和 FMResultSet
核心类进行数据库的创建、数据插入和查询等操作。同时,还将涉及如何通过 UIAlertController
或自定义视图控制器创建弹出视图,并实现省份和城市数据的动态显示与交互。开发者将通过这一实践项目加深对SQLite数据库操作的理解,提升在iOS应用中处理数据库和用户界面交互的技能。
1. FMDB库简介和核心类使用
1.1 FMDB库简介
FMDB是Objective-C语言中SQLite数据库操作的一个封装库,它将底层的C API调用封装成简单易用的Objective-C接口。借助于FMDB,开发者可以以面向对象的方式操作SQLite数据库,从而避免了直接使用SQL语句带来的复杂性和风险。它是一个轻量级的数据库操作解决方案,特别适合iOS开发中使用。
1.2 核心类的使用
FMDB库中最核心的类包括FMDatabase、FMResultSet以及FMDatabaseQueue。 FMDatabase
类负责打开和管理数据库连接,执行SQL语句并返回结果集(FMResultSet)。 FMResultSet
类则用于遍历查询结果。当需要在多线程环境下执行数据库操作时, FMDatabaseQueue
类提供了线程安全的执行队列。
下面是一个使用FMDB进行数据库连接和简单的数据插入操作的示例代码:
// 创建并打开数据库
FMDatabase *db = [[FMDatabase alloc] initWithPath:@"your-database-path.sqlite"];
BOOL success = [db open];
if (!success) {
NSLog(@"数据库打开失败: %@", [db lastErrorMessage]);
return;
}
// 执行SQL语句插入数据
FMResultSet *set = [db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"John Doe", @30];
// 检查插入是否成功并关闭数据库
if ([set next]) {
NSLog(@"数据插入成功");
} else {
NSLog(@"数据插入失败: %@", [db lastErrorMessage]);
}
[db close];
在上述代码中,首先创建了一个 FMDatabase
实例并尝试打开数据库。如果数据库成功打开,则执行一个插入SQL语句,并使用 FMResultSet
来检查插入操作的结果。最后,关闭数据库连接以释放资源。
通过这种方式,FMDB简化了数据库操作流程,使得开发者能够更加专注于业务逻辑的实现。接下来的章节将深入探讨SQLite数据库操作的基础知识。
2. SQLite数据库操作基础
2.1 数据库的创建与连接
2.1.1 SQLite数据库简介
SQLite是一个轻量级的数据库引擎,它是嵌入式的,不需要一个单独的服务器进程来管理数据库。SQLite数据库通过其易于使用的API来实现高效、可靠的数据存储,因此它广泛用于移动应用开发中,尤其是在iOS平台。FMDB是一个流行的Objective-C封装库,简化了SQLite的使用。它为数据库操作提供了更加面向对象的接口,同时保持了SQLite的灵活性和功能。
2.1.2 创建数据库实例
使用FMDB时,首先需要创建一个FMDatabase对象来代表数据库实例。这个对象可以用来执行SQL语句。下面是一个简单的示例来展示如何创建一个FMDatabase实例,并打开一个数据库连接:
import FMDB
// 创建FMDatabase实例
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let databasePath = dbPath.appendingPathComponent("mydatabase.sqlite")
let db = FMDatabase(path: databasePath as String)
// 打开数据库连接
if db.open() {
// 在此处执行数据库操作
// ...
// 关闭数据库连接
db.close()
} else {
// 处理数据库打开失败的情况
print(db.lastErrorMessage())
}
上述代码创建了一个FMDatabase对象,并指定了数据库文件的路径。通过调用 open()
方法尝试打开数据库。如果成功,就可以执行相应的SQL语句了。在操作完成后,应该调用 close()
方法来关闭数据库连接。如果在打开数据库时出现错误,可以通过 lastErrorMessage()
方法来获取错误信息。
2.2 数据表的操作
2.2.1 创建和修改数据表
要创建一个新的数据表,首先需要写一个SQL CREATE TABLE
语句,然后用FMDB执行它。一旦表创建成功,可以使用 ALTER TABLE
来修改已存在的表结构,比如添加新的字段。
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
);
上述SQL语句创建了一个名为 users
的表,其中包含了三个字段: id
(主键,自增)、 name
(文本类型,非空)、 age
(整数类型,非空)。使用FMDB执行这个SQL语句的代码如下:
if db.open() {
let createTableSQL = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL)"
if !db.executeStatements(createTableSQL) {
print(db.lastErrorMessage())
}
db.close()
}
请注意,为了保持代码的可读性,数据库的创建和修改操作应该放在应用的初始化阶段,或者在首次安装应用时进行。
2.2.2 数据表的增删改查操作
一旦数据表创建完成,接下来就可以对表中的数据进行增删改查操作了。以下是使用FMDB执行这些操作的基本方法:
// 插入数据
if db.open() {
let insertSQL = "INSERT INTO users (name, age) VALUES (?, ?)"
if !db.executeUpdate(insertSQL, withArgumentsIn: ["John Doe", 30]) {
print(db.lastErrorMessage())
}
db.close()
}
// 更新数据
if db.open() {
let updateSQL = "UPDATE users SET age = ? WHERE name = ?"
if !db.executeUpdate(updateSQL, withArgumentsIn: [31, "John Doe"]) {
print(db.lastErrorMessage())
}
db.close()
}
// 删除数据
if db.open() {
let deleteSQL = "DELETE FROM users WHERE age < ?"
if !db.executeUpdate(deleteSQL, withArgumentsIn: [25]) {
print(db.lastErrorMessage())
}
db.close()
}
// 查询数据
if db.open() {
let selectSQL = "SELECT * FROM users"
if let resultSet = db.executeQuery(selectSQL) {
while resultSet.next() {
let name = resultSet.stringForColumn("name")
let age = resultSet.intForColumn("age")
print("Name: \(name), Age: \(age)")
}
} else {
print(db.lastErrorMessage())
}
db.close()
}
在上述代码中,我们使用了不同的方法来执行插入、更新、删除和查询操作。对于插入和更新,使用了 executeUpdate
方法。对于删除和查询,则使用了 executeQuery
方法,并通过结果集 resultSet
来遍历和访问查询到的数据。
对于查询操作,可以使用更复杂的选择条件来获取所需的数据。例如,你可以使用 LIKE
子句来实现模糊查询,或者使用 ORDER BY
来对结果进行排序。这些操作提供了丰富的方法来满足各种数据检索需求。
以上示例代码和解释应能为读者提供一个关于如何在使用FMDB进行SQLite数据库操作时开始的基础,并为进一步深入学习和实践打下坚实的基础。
3. 创建省市数据库表
3.1 设计省市信息数据模型
在开始创建数据库之前,设计一个合理的数据模型是至关重要的。在本节中,我们将探讨如何确定省市数据的结构,并设计合理的数据类型和约束。
3.1.1 确定省市数据结构
省市信息通常包括几个基本信息,如省/市名称、邮政编码、所属国家等。为了方便数据的管理和查询,我们还需要添加一个唯一标识(ID)作为主键。以下是一个可能的省市级别的数据结构设计:
-
id
(整型, 主键, 唯一标识) -
name
(字符串, 省/市名称) -
postal_code
(字符串, 邮政编码) -
country
(字符串, 所属国家)
3.1.2 设计合理的数据类型和约束
设计好数据结构后,接下来需要确定每个字段的数据类型和约束条件。这将确保数据的一致性和完整性。
CREATE TABLE IF NOT EXISTS province (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
postal_code TEXT,
country TEXT NOT NULL
);
在这个例子中, id
字段被设置为自增的整数,作为主键。 name
和 country
字段是文本类型,用于存储省/市名称和所属国家,这里将 name
和 country
字段设置为非空( NOT NULL
),以确保每个条目都必须提供这些信息。 postal_code
字段被设置为文本类型,对于这个字段,我们不强制非空约束,因为某些地区可能没有邮政编码。
3.2 实现省市数据表的创建
创建数据模型后,接下来是实际创建数据库表的过程。这包括编写SQL语句以及使用FMDB库来执行这些语句。
3.2.1 编写创建表的SQL语句
一旦确定了数据模型,下一步就是编写相应的SQL语句来创建表:
CREATE TABLE IF NOT EXISTS city (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
postal_code TEXT,
province_id INTEGER NOT NULL,
country TEXT NOT NULL,
FOREIGN KEY(province_id) REFERENCES province(id)
);
在这个城市表的创建语句中, id
依然是自增主键。我们添加了一个新的字段 province_id
,它是一个整数类型,用于存储与省份表的关联。这里还添加了一个外键约束,以确保 province_id
对应的记录存在于省份表中。 country
字段表示城市所属的国家,这里同样设置了非空约束。
3.2.2 使用FMDB执行表创建
FMDB库提供了一个简单的接口来执行SQL语句。首先,确保你已经有了一个FMDB实例。
let db = FMDatabaseQueue(path: databasePath)
db.inDatabase { db in
if !db.open {
// Handle the case where the database could not be opened
return
}
let createProvinceTable = "CREATE TABLE IF NOT EXISTS province..."
let createCityTable = "CREATE TABLE IF NOT EXISTS city..."
if !db.executeStatements(createProvinceTable) {
// Handle the case where the table creation failed
}
if !db.executeStatements(createCityTable) {
// Handle the case where the table creation failed
}
}
在Swift代码中, FMDatabaseQueue
的 inDatabase
方法被用来执行一段代码,这段代码在数据库操作完成后会自动关闭数据库连接。 executeStatements
方法用于执行一个或多个SQL语句,如果创建表的语句执行失败,可以根据需要进行错误处理。
在执行表创建操作时,要确保已经正确地处理了任何可能发生的错误,例如数据库连接问题或执行语句时的错误。正确的错误处理有助于避免运行时错误,同时确保数据库的完整性和一致性。
以上就是创建省市信息数据库表的详细过程,包括设计数据模型、编写SQL语句以及使用FMDB库在iOS应用中执行这些语句。接下来,我们将介绍如何使用FMDB执行数据插入和查询操作。
4. 使用FMDB执行数据插入和查询
在深入探讨数据操作的高级特性之前,我们需要了解如何使用FMDB这个轻量级封装库来执行基础的数据插入和查询操作。FMDB将SQLite的复杂性隐藏在面向对象的接口后面,使得开发者可以使用Objective-C编写更加直观的代码。
4.1 数据的增删改操作
4.1.1 插入数据的方法和示例
FMDB提供了一套简单而直接的方法来执行数据库的插入操作。开发者可以使用 -executeUpdate:withArgArray:
或者 -executeUpdate:withObjects:
方法来插入数据。
下面的代码片段展示了如何插入一条记录到名为 cities
的表中:
// 创建FMDatabase对象
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
BOOL success = [db open];
// 插入数据的SQL语句
NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO cities (name, population) VALUES (?, ?)"];
// 执行SQL插入操作
NSArray *args = @[ @"Beijing", @*** ];
[db executeUpdate:insertSQL withObjects:args];
if(success) {
NSLog(@"插入成功");
} else {
NSLog(@"插入失败: %@", [db lastErrorMessage]);
}
[db close];
在这个例子中, executeUpdate:withObjects:
方法会安全地处理所有参数,防止SQL注入攻击。 args
数组包含了要插入的数据,其中 ?
占位符在SQL语句中用作参数的占位。
4.1.2 更新和删除数据的技巧
更新和删除操作也遵循相同的模式。使用 -executeUpdate:withArgArray:
或 -executeUpdate:withObjects:
方法。
举个例子,要更新 cities
表中 population
字段的值,可以使用以下代码:
NSString *updateSQL = [NSString stringWithFormat:@"UPDATE cities SET population = ? WHERE name = ?"];
[db executeUpdate:updateSQL withObjects:@[ @***, @"Shanghai" ]];
删除记录的示例代码如下:
NSString *deleteSQL = [NSString stringWithFormat:@"DELETE FROM cities WHERE name = ?"];
[db executeUpdate:deleteSQL withObjects:@[ @"Guangzhou" ]];
4.2 高级查询操作
4.2.1 基础查询的实现
基础的查询操作通常包含选择、从表中检索记录等。可以使用 -executeQuery:withArgArray:
或者 -executeQuery:withObjects:
方法执行。
以下是如何执行基础查询的示例:
NSString *selectSQL = [NSString stringWithFormat:@"SELECT * FROM cities"];
FMResultSet *result = [db executeQuery:selectSQL withObjects:nil];
// 获取结果集中的所有数据
while ([result next]) {
NSString *name = [result stringForColumn:@"name"];
NSNumber *population = [result numberForColumn:@"population"];
NSLog(@"%@: %@", name, population);
}
在上述代码中, executeQuery:withObjects:
方法返回一个 FMResultSet
对象,这个对象允许我们遍历查询结果。
4.2.2 复杂查询的应用场景
当需要处理更复杂的查询场景时,如数据分组、排序、条件过滤等,可以利用SQL的高级特性。
例如,按人口数量降序排列城市的查询:
NSString *advancedSelectSQL = [NSString stringWithFormat:@"SELECT * FROM cities ORDER BY population DESC"];
FMResultSet *result = [db executeQuery:advancedSelectSQL withObjects:nil];
对于包含多个条件的复杂查询,可以使用 IN
或 BETWEEN
等关键字:
NSString *complexSelectSQL = [NSString stringWithFormat:@"SELECT * FROM cities WHERE population BETWEEN ? AND ?"];
FMResultSet *result = [db executeQuery:complexSelectSQL withObjects:@[ @5000000, @*** ]];
通过FMDB执行的这些查询操作,可以极大提高开发人员对数据库操作的灵活性和效率。对于更加复杂的查询需求,还可以结合使用SQL函数和表达式,例如 SUM
、 AVG
等聚合函数,或是 GROUP BY
进行数据分组。
为了进一步展示,我们可以创建一个表格来对比不同查询类型在代码实现上的差异:
| 查询类型 | 示例SQL语句 | 代码实现示例 | |------------|----------------------------------------------------------|-----------------------------------------------------| | 基础查询 | SELECT * FROM cities | FMResultSet *result = [db executeQuery:selectSQL];
| | 排序查询 | SELECT * FROM cities ORDER BY population DESC | FMResultSet *result = [db executeQuery:advancedSelectSQL];
| | 条件查询 | SELECT * FROM cities WHERE population BETWEEN ? AND ? | FMResultSet *result = [db executeQuery:complexSelectSQL withObjects:@[ @5000000, @*** ]];
| | 聚合查询 | SELECT SUM(population) FROM cities | FMResultSet *result = [db executeQuery:sumQuerySQL];
|
使用表格可以方便地比较不同类型的查询操作的实现方式和特点。每个查询的代码实现都对应到特定的SQL语句,并在FMDB中以不同方式调用。
这些查询操作的执行,通过FMDB封装库,变得直观易懂,让数据库操作不再是困扰开发者的难题。对于更加复杂的场景,开发者需要深入了解SQLite提供的丰富功能,并合理利用FMDB提供的API进行高效的编程实践。
5. 弹出视图的创建和交互实现
在移动应用开发中,弹出视图是一种常见的用户界面元素,它允许开发者在当前视图之上展示一个临时的视图层。这通常用于展示额外的信息、执行特定操作或确认用户行为。本章节将深入探讨如何在使用FMDB时集成弹出视图,以及如何实现用户交互功能。
5.1 视图控制器的集成与配置
5.1.1 视图控制器的作用和初始化
在iOS应用开发中,视图控制器(UIViewController)是管理视图层次结构的核心组件。通过继承UIViewController类,可以创建自定义的视图控制器来管理特定的视图。
视图控制器负责加载视图(通过其view属性),处理用户的交互事件,并且响应这些事件以更新视图。它还管理着视图的生命周期,例如当视图出现或消失时进行初始化或清理资源。
初始化视图控制器的代码通常如下:
import UIKit
class PopViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
在Swift中,通过 viewDidLoad
方法可以初始化视图控制器的视图。 viewDidLoad
在视图加载完成之后被调用,是进行视图设置的合适位置。
5.1.2 视图的布局和样式设计
在 viewDidLoad
方法中,可以对视图进行布局和样式的设计。视图的布局通常通过AutoLayout完成,这允许开发者定义视图间的关系,从而适应不同尺寸的屏幕。
例如,可以使用约束(constraints)来定义一个按钮的中心位置和尺寸:
@IBOutlet weak var myButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let views = ["myButton": myButton]
myButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
myButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
myButton.widthAnchor.constraint(equalToConstant: 200),
myButton.heightAnchor.constraint(equalToConstant: 100),
])
}
在上述代码中,我们首先将按钮的自动转换为约束( translatesAutoresizingMaskIntoConstraints
属性设置为 false
),然后创建并激活约束,使得按钮在父视图中水平和垂直居中,并具有特定的宽度和高度。
5.2 视图与用户交互的实现
5.2.1 触摸事件的响应处理
视图控制器可以响应不同的触摸事件,如点击、长按、拖动等。在Swift中,可以通过重写以下方法来处理这些事件:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// 处理触摸开始事件
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
// 处理触摸移动事件
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
// 处理触摸结束事件
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
// 处理触摸取消事件
}
通过这些方法,开发者可以编写处理触摸事件的逻辑,例如,响应按钮点击:
@IBAction func onMyButtonTap(_ sender: UIButton) {
// 处理按钮点击事件
}
在用户界面上, @IBAction
表示这个方法是一个动作,它将与按钮的点击事件关联。
5.2.2 界面元素的动态展示
界面元素的动态展示是弹出视图交互的核心。开发者需要根据用户的行为来更新或替换界面内容。例如,可以使用动画效果来展示或隐藏视图。
UIView.animate(withDuration: 0.5, animations: {
// 动画的起始状态
myButton.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
}) { _ in
// 动画完成后的状态
myButton.transform = .identity
}
此代码段使用 UIView.animate
方法来对按钮执行缩放动画。动画的持续时间为0.5秒,缩放比例为原始尺寸的0.5倍。当动画完成时,回调块会被执行,按钮恢复到原始尺寸。
小结
通过本章节的介绍,我们了解了在使用FMDB库进行数据管理时,如何整合弹出视图和用户交互到iOS应用中。首先,我们探讨了视图控制器的作用及其初始化过程,然后讨论了如何进行视图布局和样式设计。接着,我们研究了如何处理触摸事件以及如何通过动画实现界面元素的动态展示。
理解视图控制器及其生命周期,掌握视图布局和样式设计,以及触摸事件的响应处理,是在iOS开发中实现良好用户交互体验的基础。我们将在后续章节中探索如何将这些基础知识与FMDB库结合,以提升应用的数据处理能力及交互质量。
6. Swift或Objective-C语言实践
6.1 Swift与Objective-C语言对比
6.1.1 两种语言的简介和特点
在讨论如何在FMDB中使用Swift或Objective-C之前,了解这两种语言的基本情况和特点是非常重要的。
Objective-C: Objective-C是苹果公司在20世纪80年代末推出的一种面向对象的编程语言。它的语法基于C语言,并添加了Smalltalk风格的消息传递机制。Objective-C是苹果早期应用开发的主要语言,支持类的动态扩展,拥有成熟的开发者社区和大量的开发工具。
Swift: Swift是苹果公司在2014年推出的一种全新的编程语言,设计宗旨是提供安全、高效且易学的编程环境。Swift的语法简洁,减少了传统Objective-C代码中常见的冗余部分,同时引入了现代编程语言的一些特性,比如类型推断、元组等。
Swift与Objective-C在语言特性和开发体验上都有较大差异,但两者都可以在Xcode中使用,并且能调用Apple的API以及通过FMDB操作SQLite数据库。
6.1.2 在FMDB中选择合适语言的优势
选择在FMDB中使用Swift还是Objective-C,应考虑项目需求、团队技能和未来发展。
Swift的优势: - 安全特性: Swift的语法设计让编译器能够捕捉更多编程错误,例如强制解包。 - 性能优化: Swift代码通常有较快的执行速度。 - 开发体验: Swift的现代特性提供了更简洁的代码风格,提升了开发效率。 - 生态系统: Swift是苹果公司推荐的开发语言,未来的iOS开发更可能以Swift为主。
Objective-C的优势: - 成熟度: Objective-C经过多年的积累,拥有大量成熟的第三方库。 - 灵活性: Objective-C更灵活,特别是在动态消息传递方面。 - 社区支持: 历史悠久,社区资源丰富,拥有大量的教程和资料。
6.2 代码实现与性能优化
6.2.1 编写高效的数据操作代码
无论选择Swift还是Objective-C,编写高效的代码都涉及对FMDB库的深入理解和正确的数据操作实践。
Swift示例: 使用Swift在FMDB中插入数据。
// 初始化FMDB数据库实例
let db = FMDatabase(path: "your-database-path")
if db.open() {
let sql = "INSERT INTO provinces (name) VALUES (?)"
let stmt = ***pileInsertWithFormat(sql, arguments: ["省份名称"])
let result = db.executeStatements(stmt)
if result {
print("数据插入成功")
} else {
print("数据插入失败")
}
db.close()
} else {
print("数据库打开失败")
}
Objective-C示例: 使用Objective-C在FMDB中插入数据。
// 初始化FMDB数据库实例
FMDatabase *db = [[FMDatabase alloc] initWithPath:@"your-database-path"];
if ([db open]) {
NSString *sql = @"INSERT INTO provinces (name) VALUES (?)";
FMResultSet *result = [db executeUpdate:sql, @"省份名称"];
if (result) {
NSLog(@"数据插入成功");
} else {
NSLog(@"数据插入失败");
}
[db close];
} else {
NSLog(@"数据库打开失败");
}
在以上示例中,我们展示了如何在FMDB中插入省份名称到数据库。对于数据查询、更新和删除操作,方法类似。
6.2.2 代码的调试和优化技巧
代码调试和性能优化是软件开发过程中必不可少的环节。针对FMDB库的使用,以下是一些关键的优化技巧:
- 避免频繁开启关闭数据库: 尽可能在需要大量数据操作时打开数据库,并在操作完成后再关闭。
- 批量插入数据: 当需要插入多条数据时,使用批量插入可以减少数据库操作次数,提高性能。
- 使用索引: 在可能影响查询性能的字段上建立索引,以加速查询速度。
- 事务处理: 在需要多个操作同时成功或失败时,使用事务处理,以保证数据的一致性。
- 调试工具: 使用Xcode的调试工具(如断点、控制台输出等)来监测程序运行状态,及时发现并修复问题。
在代码优化的过程中,合理地利用这些技巧,可以显著提升应用的性能和用户体验。记住,优化应当建立在实际的性能测试结果上,而不是基于主观猜测。
简介:在iOS开发中,数据库操作尤为重要,尤其是存储用户数据或实现本地化功能时。本案例聚焦于使用FMDB库进行数据库查询操作,重点是实现一个省市选择器,利用弹出视图展示并交互。通过本项目,开发者将学习如何使用FMDB库的 FMDatabase
、 FMStatement
和 FMResultSet
核心类进行数据库的创建、数据插入和查询等操作。同时,还将涉及如何通过 UIAlertController
或自定义视图控制器创建弹出视图,并实现省份和城市数据的动态显示与交互。开发者将通过这一实践项目加深对SQLite数据库操作的理解,提升在iOS应用中处理数据库和用户界面交互的技能。