2017-08-17 18:14:53 wuming_apie 阅读数 1754
  • ASP.NET 开发课程 MVC5 入门篇

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 主讲内容 第一讲 MVC5简介 第二讲 MVC 控制器 第三讲 视图 第四讲 模型 等课程

    13107 人正在学习 去看看 胡延亮

ActiveSQLite 更简单的Swift数据库方案。项目地址:https://github.com/KevinZhouRafael/ActiveSQLite

——————————————————————————————————

在做swift数据库的时候,选择并不多,有三种:CoreData,SQLite,Realm。很多喜欢用SQL的开发者在Objective-c中使用FMDB,而在swift中,star最多的SQLite框架就是SQLite.swift,其star数量也才4k+,但是没有更好的选择了。SQLite.swift功能很强大,但是有几点非常不方便:

1,要写Expression表达式。
2,不能自动包装成对象。

参考如下代码:

let users = Table("users")
let id = Expression("id")
let email = Expression("email")

for stmt in try! db.prepare(users.select(id, email)) {
    print("id: \(stmt[id]), email: \(stmt[email])")
}

1、在创建表,增删查改表都会用到Expression表达式,一般我们通常将表达式作为类的静态属性,这样统一管理。
2、读取stmt的数据只能显式的通过Expression表达式或者索引,这样在修改表的时候也是非常麻烦的,也很容易弄错。

为了让SQLite.swift更加好用,我写了一个框架ActiveSQLite,是对SQLite.swift的封装。主要特性:

1、自动创建表。

2、增删查改支持String和key-value的字典。

3、自动把查询结果包装为model。

4、更方便的事务和异步,模型与数据库表映射,日志,简便的数据库升级。

写的过程参考了MagicalRecordActiveRecord。易用性达到Realm的级别。

——————————————————————————————————————
具体介绍如下:

特性

  • 支持 SQLite.swift 的所有特性。
  • 自动创建表. 自动创建 id , created_at 和 updated_at 列。
  • 自动把SQL查询的数据赋值给数据库模型DBModel的属性。
  • 自定义表名和模型名之间的映射,列名和模型的属性名之间的映射。
  • 支持事务和异步。
  • 提供可扩展,链式,延迟执行的查询接口。
  • 通过属性名字符串,字典,或SQLite.swift的表达式Expression查询和修改数据。
  • 日志级别

例子

执行 ActiveSQLiteTests target.

用法

import ActiveSQLite

//定义model和table
class Product:DBModel{

    var name:String!
    var price:NSNumber!
    var desc:String?
    var publish_date:NSDate?

}

//保存
let product = Product()
product.name = "iPhone 7"
product.price = NSNumber(value:599)
try! product.save()

//查询
let p = Product.findFirst("name",value:"iPhone") as! Product

//or 
let name = Expression<String>("name")
let p = Product.findAll(name == "iPhone")!.first as! Product                    
//id = 1, name = iPhone 7, price = 599, desc = nil,  publish_date = nil, created_at = 1498616987587.237, updated_at = 1498616987587.237, 

//更新
p.name = "iPad"
try! p.update()

//删除
p.delete()

开始

在你的工程的target使用ActiveSQLite, 需要首先导入 ActiveSQLite 模块.

import ActiveSQLite

连接数据库

DBConfigration.dbPath = "..."

如果你没有设置dbPath,那么默认的数据库文件是在documents目录下的ActiveSQLite.db。

支持的数据类型

ActiveSQLite
Swift Type
SQLite.swift
Swift Type
SQLite
SQLite Type
NSNumber Int64 INTEGER
NSNumber Double REAL
String String TEXT
nil nil NULL
SQLite.Blob BLOB
NSDate Int64 INTEGER

NSNumber类型对应SQLite.swift的两种类型(Int64和Double)。NSNumber默认的映射类型是Int64。重写DBModel的doubleTypes()方法能标记属性为Double类型。

class Product:DBModel{

    var name:String!
    var price:NSNumber!
    var desc:String?
    var publish_date:NSDate?

  override func doubleTypes() -> [String]{
      return ["price"]
  }

}

ActiviteSQLite映射NSDate类型到SQLite.swift的Int64类型。 你可以通过查找SQLite.swift的文档Custom Types of Documentaion映射NSDate到String。

创建表

ActiveSQLite自动创建表并且添加”id”, “created_at”和 “updated_at”字段。”id”字段是主键。 创建的代码类似于下面这样:

try db.run(products.create { t in      
    t.column(id, primaryKey: true)
    t.column(Expression<NSDate>("created_at"), defaultValue: NSDate(timeIntervalSince1970: 0))  
    t.column(Expression<NSDate>("updated_at"), defaultValue: NSDate(timeIntervalSince1970: 0))  
    t.column(...)  

})                             

// CREATE TABLE "Products" (
//      "id" INTEGER PRIMARY KEY NOT NULL,
//      created_at INTEGER DEFAULT (0),
//      created_at INTEGER DEFAULT (0),
//     ...
//  )

“created_at”和”updated_at”字段的单位是毫秒ms。

映射

你可以自定义表的名字, 列的名字,还可以设置瞬时属性不存在数据库中。

1. 映射表名

默认的表名和类名相同。

//设置表名为 "ProductTable"
override class var nameOfTable: String{
    return "ProductTable"
}

2. 映射列名

默认的列名和属性名相同。

//设置"product"属性映射的列名为"product_name"
//设置"price"属性映射的列名为"product_price"
override class func mapper() -> [String:String]{
    return ["name":"product_name","price":"product_price"];
}

3. 瞬时属性。

瞬时属性不会被存在数据库中。

override class func transientTypess() -> [String]{
    return ["isSelected"]
}

ActiveSQLite 仅仅保存三种属性类型 (String,NSNumber,NSDate)到数据库。 如果属性不是这三种类型,那么不会被存入数据库,它们被当做瞬时属性看待。

表约束

如果你要自定义列, 你仅需要实现CreateColumnsProtocol协议的createColumns方法,那么ActiveSQLite就不会自动创建列。写自己的建列语句,要注意列名和属性名必须一致,否则不能自动从查询sql封装数据库模型对象。


class Users:DBModel,CreateColumnsProtocol{
    var name:String!
    var email:String!
    var age:Int?

    func createColumns(t: TableBuilder) {
        t.column(Expression<NSNumber>("id"), primaryKey: true)
        t.column(Expression<String>("name"),defaultValue:"Anonymous")
        t.column(Expression<String>("email"), , check: email.like("%@%"))
    }
}

更多信息查考SQLite.swift的文档table constraints document

插入记录

有三个方法用来插入记录。

插入一条。

func insert()throws ;

插入多条。

class func insertBatch(models:[DBModel])throws ;

保存方法。

如果数据库模型对象的 id == nil,那么执行插入。如果id != nil那么执行更新语句。

func save() throws;

例如:

let u = Users()
u.name = "Kevin"
try! u.save()

var products = [Product]()
for i in 1 ..< 8 {
    let p = Product()
    p.name = "iPhone-\(i)"
    p.price = NSNumber(value:i)
    products.append(p)
}

try! Product.insertBatch(models: products)

更多信息可以看ActiveSQLite的源码和例子, 也可以查阅SQLite.swift的文档Inserting Rows document

更新记录

有三种更新策略。

1. 通过改属性值

首先修改属性的值,然后执行save() 或者 update() 或者 updateBatch()。

p.name = "zhoukai"
p.save()

2. 通过属性名字符串和属性值

//更新一条
u.update("name",value:"3ds")
u.update(["name":"3ds","price":NSNumber(value:199)])


//更新多条
Product.update(["name": "3ds","price":NSNumber(value:199)], where: ["id": NSNumber(1)])

2. 通过SQLite.swift的Setter

//更新一条记录
p.update([Product.price <- NSNumber(value:199))

//更新多条
Product.update([Product.price <- NSNumber(value:199), where: Product.name == "3ds")

了解更多请看ActiveSQLite的源码和例子, 查看SQLite.swift的文档Updating Rows document , Setters document

查询记录

使用findFirst方法查询一条记录,使用findAll方法查询多条记录。

方法名前缀是”find”的是类方法,这种方法一次性查询出结果。

1.通过属性名字符串和属性值查询

let p = Product.findFirst("name",value:"iWatch") as! Product

let ps = Product.findAll("name",value:"iWatch",orders:["price",false]) as! [Product]

2.通过SQLite.swift的Expression查询

let id = Expression<NSNumber>("id")
let name = Expression<String>("name")

let arr = Product.findAll(name == "iWatch") as! Array<Product>

let ps = Product.findAll(id > NSNumber(value:100), orders: [Product.id.asc]) as! [Product]

链式查询

链式查询方法是属性方法。

let products = Product().where(Expression<NSNumber>("code") > 3)
                                .order(Product.code)
                                .limit(5)
                                .run() as! [Product]

不要忘记执行run()。

更多复杂的查询参考ActiveSQLite的源码和例子。和SQLite.swift的文档Building Complex Queries

表达式Expression

SQLite.swift再更新update和查询select操作中,使用表达式Expression转换成SQL的’where’判断,。更多复杂的表达式用法,参考文档filtering-rows

删除记录

//1. 删除一条
try? product.delete()

//2. 删除所有
try? Product.deleteAll()

//3. 通过表达式Expression链式删除。
try? Product().where(Expression<NSNumber>("code") > 3)
                                .runDelete()

事务

建议把所有的insert,update,delete操作和alter表的代码全部放在ActiveSQLite.save代码块中。一个块中的sql操作在同一个事务当中。

 ActiveSQLite.save({ 

                var products = [Product]()
                for i in 0 ..< 3 {
                    let p = Product()
                    p.name = "iPhone-\(i)"
                    p.price = NSNumber(value:i)
                    products.append(p)
                }
                try Product.insertBatch(models: products)


                let u = Users()
                u.name = "Kevin"
                try u.save()


            }, completion: { (error) in

                if error != nil {
                    debugPrint("transtion fails \(error)")
                }else{
                    debugPrint("transtion success")
                }

            })

异步

ActiveSQLite.saveAsync是一个异步的操作,当然代码块中的sql也在同一个事务当中。

 ActiveSQLite.saveAsync({ 
            .......

            }, completion: { (error) in
                ......
            })

改变表结构

重命名表和添加列

第1步. 用新的表名做映射,添加新的属性。

class Product{
    var name:String!

    var newColumn:String!
    override class var nameOfTable: String{
        return "newTableName"
    }

}

Step 2. 当数据库版本改变时候,执行修改表名和添加列sql,并放在同一个事务中。

let db = DBConnection.sharedConnection.db
            if db.userVersion == 0 {
                ActiveSQLite.saveAsync({
                    try Product.renameTable(oldName:"oldTableName",newName:"newTableName")
                    try Product.addColumn(["newColumn"])

                }, completion: { (error) in
                    if error == nil {

                        db.userVersion = 1
                    }
                })

            }             

更多SQLite.swift的修改表信息参看 Altering the Schema

索引

    let name = Expression<String>("name")
    Product.createIndex(name)
    Product.dropIndex(name)

更多信息查看 Indexes of SQLite.swift Document

删除表

Product.dropTable()

日志

有四种日志级别,分别是: debug,info,warn,error。
默认的日志级别是info。像这样来设置日志级别:

//1. 设置日志级别
DBConfigration.logLevel = .debug

//2. 设置数据库路径
DBConfigration.dbPath = "..."

保证首先设置日志级别,后设置数据库路径。

硬件需求

  • iOS 8.0+
  • Xcode 8.3.2
  • Swift 3

安装

Cocoapods

再Podfile文件中添加:

pod "ActiveSQLite"

作者

Rafael Zhou

License

ActiveSQLite is available under the MIT license. See the LICENSE file for more info.

2017-05-26 15:32:07 C_calary 阅读数 747
  • ASP.NET 开发课程 MVC5 入门篇

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 主讲内容 第一讲 MVC5简介 第二讲 MVC 控制器 第三讲 视图 第四讲 模型 等课程

    13107 人正在学习 去看看 胡延亮

前言

一个APP的诞生肯定少不了站在巨人的肩膀上,所以使用这些开源的库,可以让你的开发更加的顺利,快速。如果你想获得更好的阅读体验,请移步简书

网络请求

MVC(Model数据转模型相关)

  • ObjectMapper(Swift)
    Swift中Model数据转模型使用,是MVC架构中绑定数据很有用的框架
    使用方法参考

  • EZSwiftExtensions(OC)
    OC 中数据转模型使用框架,具体用法Github上也有详细的讲解

  • MJExtension(OC)
    转换速度快、使用简单方便的字典转模型框架

  • AlamofireObjectMapper
    配合* ObjectMapper*使用的网络请求扩展

  • MBNetWork
    基于 Alamofire 封装的网络请求库,可以更方便地在视图上展示请求状态。配合Alamofire,ObjectMapper,AlamofireObjectMapper使用

  • HandyJSON(Swift)
    HandyJSON是一个用于Swift语言中的JSON序列化/反序列化库。
    与其他流行的Swift JSON库相比,HandyJSON的特点是,它支持纯swift类,使用也简单。它反序列化时(把JSON转换为Model)不要求Model从NSObject继承(因为它不是基于KVC机制),也不要求你为Model定义一个Mapping函数。只要你定义好Model类,声明它服从HandyJSON协议,HandyJSON就能自行以各个属性的属性名为Key,从JSON串中解析值。

图片加载

界面

动画

刷新

  • MJRefresh(OC)
    上拉加载,下拉刷新,可以自定义实现多种样式

日期选择器

工具

  • TalkingData
    移动数据服务平台,可以对app进行多方面的监测,用于统计数据分析等。
  • 信鸽推送
    顾名思义,是移动App推送平台
  • ShareSDK
    提供社会化功能,集成了一些常用的类库和接口,缩短开发者的开发时间,还有社会化统计分析管理后台,支持包括QQ、微信、新浪微博、腾讯微博等国内外40多家的主流社交平台,帮助开发者轻松实现社会化分享、登录、关注、获得用户资料、获取好友列表等主流的社会化功能。
  • 腾讯Bugly
    腾讯Bugly,为移动开发者提供专业的异常上报,运营统计和内测分发解决方案,帮助开发者快速发现并解决异常,同时掌握产品运营动态,及时跟进用户反馈。

存储相关

  • SwiftyUserDefaults
    对UserDefaults做了进一步的封装,使用起来比较方便。

相机相册图片处理

其他

  • OCR(OC)
    身份证扫描,识别速度特别快,可以快速识别出身份证正反面所有的信息,但是使用了这个框架后就不能用模拟器进行运行程序了,会报错,具体解决办法我也没找到,如果你解决了请留言给我,谢谢。
  • card.io-iOS-SDK
    银行卡识别框架,具体使用参考
  • PPGetAddressBookSwift
    通讯录的处理,可以自己设置通讯录排列样式
  • EZSwiftExtensions
    swift中的各种Extensions,总有方便你使用的
  • KMCGeigerCounter(OC)
    监测app的卡顿情况,具体介绍参考
    注:使用时注意文章最后的PS,加在AppDelegate中会报错的,要加载viewController中
  • MLeaksFinder(OC)
    监测app有无内存泄漏情况,直接导入就可以,不用添加任何代码,在有内存泄露的界面就会弹出窗口提醒。

外链

2019-09-01 10:49:49 weixin_42433480 阅读数 42
  • ASP.NET 开发课程 MVC5 入门篇

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 主讲内容 第一讲 MVC5简介 第二讲 MVC 控制器 第三讲 视图 第四讲 模型 等课程

    13107 人正在学习 去看看 胡延亮

常用的Swift第三方库

  • 网络请求: https://github.com/Alamofire/Alamofire
  • 图片下载: https://github.com/onevcat/Kingfisher
  • JSON访问: https://github.com/SwiftyJSON/SwiftyJSON
  • JSON-Model转换:https://github.com/kakaopensource/KakaJSON

Kingfisher注意点

  • Kingfisher默认不支持WebP格式的图片,需要额外安装KingfisherWebP 
  • pod 'KingfisherWebP'


库的导入问题

  • 默认情况下,用到哪个库就要导入哪个库,无疑增加了很多重复的工作量
  • 如何办到全局导入库?
  1. 新建一个用于Swift调用OC的桥接文件: targetName-Bridging-Header.h 
  2. 导入系统库:#import <XX/XX.h>
  3. 导入第三方库(Framework形式):#import <XX/XX-Swift.h>

UNIT Test 单元测试

1. 创建工程时勾选Include Unit Tests 和Include UI Tests

2. 创建要测试的数据

3. 写测试用例

注意没运行成功时前面是灰色的菱形

4.运行测试用例

可以看到当测试用例正确时,会弹出Test Succeeded提示框,并且前面的菱形是绿色

但是当测试用例错误时,会弹出Test Failed提示框,并且前面的菱形是红色的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2016-04-07 01:13:46 luosai19910103 阅读数 793
  • ASP.NET 开发课程 MVC5 入门篇

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 主讲内容 第一讲 MVC5简介 第二讲 MVC 控制器 第三讲 视图 第四讲 模型 等课程

    13107 人正在学习 去看看 胡延亮

1、CoreData使用

创建一个swift语言项目  ,主要功能添加联系人,显示联系人列表,删除联系人。

1、创建数据模型 data Model ,此模型用来构建数据库表,映射到实体模型。
添加一个实体 add Entity. 编辑Entity 名字(对应的类名)编辑相关属性,数据类型。


2、创建管理对象模型
创建一个 NSManagerObject Subclass 选中对应的数据模型,选择swift语言,这样自动创建了实体类

3、CoreData 核心

     CoreData 通过 NSManagedObjectContext 管理对象上下文操作数据库,上下文拥有持久化存储器,存储器指向数据模型(即数据库)。

 创建一个类CoreDataManage用来管理获取 NSManagedObjectContext、NSPersistentStoreCoordinator、NSManagedObjectModel
代码:

<span style="font-size:18px;"></span>

import UIKit

import CoreData

class CoreDataManager: NSObject {

    static let coreDataManager :CoreDataManager = CoreDataManager()

    lazy var applicationDocumentsDirectory: NSURL = {

        // The directory the application uses to store the Core Data store file. This code uses a directory named "com.pixolity.ios.coredata" in the application's documents Application Support directory.

        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)

        

        print("\(urls[urls.count-1])")

        return urls[urls.count-1] as NSURL

    }()

    

   lazy var managedObjectModel: NSManagedObjectModel = {

        // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.

        let modelURL = NSBundle.mainBundle().URLForResource("Model", withExtension: "momd")!

        return NSManagedObjectModel(contentsOfURL: modelURL)!

    }()

    

   lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {

        // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.

        // Create the coordinator and store

        var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

        let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("swift_demo.sqlite")

        var error: NSError? = nil

        var failureReason = "There was an error creating or loading the application's saved data."

        do {

            try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)

        } catch var error1 as NSError {

            error = error1

            coordinator = nil

            // Report any error we got.

            var dict = [String: AnyObject]()

            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"

            dict[NSLocalizedFailureReasonErrorKey] = failureReason

            dict[NSUnderlyingErrorKey] = error

            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)

            // Replace this with code to handle the error appropriately.

            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

            NSLog("Unresolved error \(error), \(error!.userInfo)")

            abort()

        } catch {

            fatalError()

        }

        

        return coordinator

    }()

    

    lazy var managedObjectContext: NSManagedObjectContext = {

        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.

        let coordinator = self.persistentStoreCoordinator

        var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)

        managedObjectContext.persistentStoreCoordinator = coordinator

        return managedObjectContext

    }()

    

    // MARK: - Core Data Saving support

    

      func saveContext () {

        if managedObjectContext.hasChanges {

            do {

                try managedObjectContext.save()

            } catch {

                // Replace this implementation with code to handle the error appropriately.

                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                let nserror = error as NSError

                NSLog("Unresolved error \(nserror), \(nserror.userInfo)")

                abort()

            }

        }

    }


}


<span style="font-size:18px;">
</span>


联系人列表:
viewDidLoad 获取数据:
 

 override func viewDidLoad() {

        super.viewDidLoad()


        

        let fetchRequst = NSFetchRequest(entityName: "Person")

        

        let ageSort = NSSortDescriptor(key: "age", ascending: true)

        

        let nameSort = NSSortDescriptor(key: "name", ascending: true)

        

        fetchRequst.sortDescriptors = [ageSort,nameSort]

        

        frc = NSFetchedResultsController(fetchRequest: fetchRequst, managedObjectContext: managerObjectContext!, sectionNameKeyPath: nil, cacheName: nil)

        

        

        frc.delegate = self

        

        do {

            try frc.performFetch()

        }catch let error as NSError{

            print("performFetch error :\(error)")

        }

        

        self.tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))


    }



实现NSFetchedResultsController代理方法

<span style="font-size:18px;"></span>

 func controllerWillChangeContent(controller: NSFetchedResultsController) {

        self.tableView.beginUpdates()

    }

    

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

        

        if(type == .Delete){

            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic)

        }else if type == .Insert{

            self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Automatic)

        }

    }

    

    func controllerDidChangeContent(controller: NSFetchedResultsController) {

        self.tableView.endUpdates()

    }


<span style="font-size:18px;"></span>


数据源:

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        // #warning Incomplete implementation, return the number of rows

       let sectionInfo = frc.sections![section] as NSFetchedResultsSectionInfo

        return sectionInfo.numberOfObjects

    }

  

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        

        let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: TableViewConstants.cellIdentifier)

        let person = frc.objectAtIndexPath(indexPath) as! Person


        cell.textLabel!.text = "Name: \(person.name!)"

        cell.detailTextLabel!.text = "Phone:\(person.phoneNum!)"

        return cell

        

    }



4、添加联系人

核心部分:
1、通过NSEntityDescription.insertNewObjectForEntityForName 方法向上下文插入一个对象。并返回新建的对象。
2、给新建的对象属性赋值
3、 保存到数据库  managerObjectContext.save()

 func newPerson()->Bool{

        

        let managerObjectContext = CoreDataManager.coreDataManager.managedObjectContext

        

        let newPerson = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: managerObjectContext) as? Person

        

        if let person = newPerson {

            person.name = self.nameTextField.text

            if let phoneNum = Int(self.phoneTextfield.text!){

                person.phoneNum = phoneNum


            }

            

            if let age = Int(self.ageTextfield.text!){

                person.age = age

            }

            do{

                try  managerObjectContext.save()

                return true

            }catch let error as NSError{

                print("failed to save :\(error) ")

            }

        }else{

            print("failed to creat new person")

        }

        return false

    }






2017-10-09 17:43:12 m0_38016385 阅读数 290
  • ASP.NET 开发课程 MVC5 入门篇

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 主讲内容 第一讲 MVC5简介 第二讲 MVC 控制器 第三讲 视图 第四讲 模型 等课程

    13107 人正在学习 去看看 胡延亮

Swift Core Data

首先需要创建一个模版,进去“file”->“new”->”file”->”Core Data”->”Data Model”。

然后点击右下角的“add entity”。
这里写图片描述

在Xcode里面这个Entity会变成一个NSMangedObject的一个实体。Xcode的数据库是基于SQL的,所以每一个entity会有属性、关系以及fetched properties(用于搜索?)。

可以通过NSMangedObject的两个函数来更改属性的值。

创建关系

进入视图显示模式,ctrldrag两个entity。然后修改两个relations的名字。
这里写图片描述

然后可以修改它们n对n的约束(type)。

这里写图片描述

这样子会把tweets这一个关系变成NSSet。

在代码中使用

在代码中使用这些数据库需要使用NSManagedObjectContext。

在创建开始的项目的时候,如果选择了“Use Core Data”,那么Xcode会自动帮我们创建一些方法(在AppDelegate)。当然也可以我们自己创建UIManagedDocument。

创建代码
首先为他们创建subclass。
这里写图片描述

记得要选择swift。

不过创建的时候出现了错误提示,要解决这个问题可以参考这里

插入行至数据库

NSEntityDescription.insertNewObjectForEntityForName("Tweet", inManagedObjectContext: moc)

这里写图片描述

访问某一行的属性(列)

func valueForKey(String) -> AnyObject?
func setValue(AnyObject?, forKey: String )

保存

context.save()

但是这个方法有一个问题,就是可能会抛出错误,我们必须学习一下swift中错误抛出的处理方式。

删除

mangedObjectContext.deleteObject(tweet)

搜索
使用NSFetchRequest来进行。你需要规定想抓取的Entity,以及抓取的规模和限制。

同时也需要规定返回的string的排序方式(使用NSSortDescripitor)。
这里写图片描述

NSPredicate则是规定我们需要什么,注意其中的%@有点像printf里的%f。
这里写图片描述

上面的图片返回的是joe在aDate后创建的tweets以及screenName是CS193p的tweeter。

例子
这里写图片描述
这里写图片描述

Thrown Errors

do {
    try context.save()
} catch let error {
    //里面会有NSError,它提供一些方法可以处理这些错误。 
}

UITableView和Core Data的交互

因为大量的数据非常适合使用Table View来展示,所以xcode直接提供了一个NSFetchedResultsController类来实现。它可以总是和数据库同步。
这里写图片描述
这里写图片描述

创建一个NSFetchedResultsController的方法:
这里写图片描述

Realm 数据库使用

阅读数 23

没有更多推荐了,返回首页