21、iOS开发:Core Data操作与高级扩展功能实现

iOS开发:Core Data操作与高级扩展功能实现

1. Core Data数据库操作

在iOS开发中,Core Data是一个强大的框架,用于管理应用程序的数据模型。下面将介绍如何在Core Data数据库中进行数据删除和实体搜索操作。

1.1 删除数据库中的对象

要删除Core Data数据库中的对象,需要调用 CoreDataHelper.saveContext 方法来提交更改。以下是实现删除操作的代码:

override func tableView(tableView: UITableView,
    commitEditingStyle editingStyle: UITableViewCellEditingStyle,
    forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            let context = self.fetchedResultsController.managedObjectContext
            context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
            helper.saveContext()
        }
}

对象从数据库中移除后,需要更新表格视图。可以通过实现 NSFetchedResultsController controllerDidChangeContent 方法来重新加载表格视图:

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    // In the simplest, most efficient, case, reload the table view.
    self.tableView.reloadData()
}

将上述代码添加到 MasterViewController.swift 文件中,运行应用程序,向左滑动表格视图中的某一行,然后点击“删除”,该行将从表格视图中移除。

1.2 搜索Core Data数据库中的实体

若要搜索Core Data数据库中的对象集合,可以使用 NSPredicate 来定义搜索条件,然后设置 NSFetchedResults.predicate 属性。以下是一个示例,搜索所有服务人数超过两人的 Recipe 实体:

let statusPredicate = NSPredicate(format: "serves > %d", 2)
fetchRequest.predicate = statusPredicate

将上述代码添加到 MasterViewController.swift 文件的 fetchedResultsController 属性中,运行应用程序,结果将显示在表格视图中。可以尝试使用不同的比较和属性来创建更多的搜索。

2. iOS 8高级扩展功能

iOS 8为生态系统添加了许多高级功能,以下将介绍如何创建一些常见的扩展。

2.1 创建Today扩展

Today扩展允许用户在Today屏幕上显示应用程序的信息。创建Today扩展的步骤如下:
1. 创建一个Single View iOS应用程序,命名为 RecipeWidget
2. 在Xcode中,选择 File -> New -> Target ,选择 Application Extension 下的 Today Extension ,命名为 RandomRecipe
3. 运行应用程序,在模拟器中打开Today视图,点击“编辑”按钮,添加 RandomRecipe 小部件。
4. 打开 TodayViewController.swift 文件,添加以下代码来设置小部件的边距:

func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> (UIEdgeInsets) {
    return UIEdgeInsetsZero
}
  1. 在故事板中,将标签的文本对齐方式设置为左对齐,并将标签的前导空间约束的偏移量设置为40。
  2. 创建一个新的Swift文件 RecipeService.swift ,添加以下代码来提供随机食谱名称:
import Foundation
class RecipeService {
    var recipes = [
        "Grilled Fish",
        "Fajitas",
        "Chicken Stir Fry",
        "Hamburger",
        "Fried Chicken",
        "Miso Soup",
        "Lo Mein",
        "Tofu and Rice",
        "Spaghetti and Meatballs",
    ]
    func randomRecipe() -> String {
        return recipes[Int(arc4random_uniform(UInt32(recipes.count)))]
    }
}
  1. TodayViewController.swift 文件的 viewDidLoad 方法中,添加以下代码来显示随机食谱名称:
var service = RecipeService()
recipeName.text = service.randomRecipe()
2.2 创建自定义键盘扩展

iOS 8允许开发者创建自定义键盘。创建自定义键盘扩展的步骤如下:
1. 打开现有应用程序或创建一个新的Single View iOS应用程序。
2. 使用 File -> New -> Target ,选择 Custom Keyboard 扩展。
3. 打开 Info.plist 文件,设置一些有用的选项,如 PrefersRightToLeft RequestsOpenAccess
4. 编译并运行项目,在模拟器中打开 Settings -> General -> Keyboard -> Keyboards -> Add New Keyboard ,选择自定义键盘。
5. 创建一个新的XIB文件 CodeKeyboard.xib ,设计键盘布局。
6. 打开 KeyboardViewController.swift 文件,添加以下代码来加载XIB文件:

override func viewDidLoad() {
    super.viewDidLoad()
    var xib = NSBundle.mainBundle().loadNibNamed("CodeKeyboard", owner: self, options: nil)
    var keyboardView = xib[0] as! UIView
    keyboardView.setTranslatesAutoresizingMaskIntoConstraints(false)
    view.addSubview(keyboardView)
    nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
}
  1. 在XIB文件中添加按钮,并设置约束。
  2. 创建按钮的出口和动作,处理键盘输入。以下是处理换行、退格和字符输入的代码:
@IBAction func newLine (sender: AnyObject) {
    (textDocumentProxy as! UITextDocumentProxy).insertText("\n")
}
@IBAction func backspace(sender: AnyObject) {
    (textDocumentProxy as! UITextDocumentProxy).deleteBackward()
}
@IBAction func keyUp(sender: AnyObject) {
    var proxy = textDocumentProxy as! UITextDocumentProxy
    var button = sender as? UIButton
    if let input = button?.titleLabel?.text as String? {
        if input == "Space" {
            proxy.insertText(" ")
            return
        }
        proxy.insertText(input)
    }
}
2.3 创建共享扩展

共享扩展允许用户在iOS 8的全局共享表中使用自定义共享功能。创建共享扩展的步骤如下:
1. 创建一个Single View iOS应用程序。
2. 使用 File -> New -> Target ,选择 Share Extension ,命名为 ShareRecipe
3. 打开 ShareViewController.swift 文件,实现 isContentValid didSelectPost configurationItems 方法。

override func isContentValid() -> Bool {
    var messageLength = count(self.contentText)
    var charactersRemaining = 100 - messageLength;
    self.charactersRemaining = charactersRemaining;
    if charactersRemaining >= 0 {
        return true;
    }
    return false;
}
override func didSelectPost() {
    println("Message: \(self.contentText)")
    self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
}
override func configurationItems() -> [AnyObject]! {
    var userRating = SLComposeSheetConfigurationItem()
    userRating.title = "Rating"
    userRating.value = ""
    userRating.tapHandler = {
        SLComposeSheetConfigurationItemTapHandler in
        var starsSelection = UIViewController()
        var s1 = self.createStarButton(1)
        var s2 = self.createStarButton(2)
        var s3 = self.createStarButton(3)
        var s4 = self.createStarButton(4)
        var s5 = self.createStarButton(5)
        var views = ["s1":s1,"s2":s2,"s3":s3,"s4":s4,"s5":s5]
        starsSelection.view.addSubview(s1)
        starsSelection.view.addSubview(s2)
        starsSelection.view.addSubview(s3)
        starsSelection.view.addSubview(s4)
        starsSelection.view.addSubview(s5)
        starsSelection.view.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|-[s1(s2)]-[s2(s3)]-[s3(s4)]-[s4(s5)]-[s5]-|",
                options: NSLayoutFormatOptions(0), metrics: nil, views: views))
        starsSelection.view.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s1(30)]",
                options: NSLayoutFormatOptions(0), metrics: nil, views: views))
        // 其他垂直约束...
        self.pushConfigurationViewController(starsSelection)
    }
    return [userRating]
}
func createStarButton(value : Int ) -> UIButton {
    var button = UIButton()
    button.setTitle("\u{2605}", forState: UIControlState.Normal)
    button.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
    button.setTranslatesAutoresizingMaskIntoConstraints(false)
    button.tag = value
    return button
}

总结

通过以上步骤,我们学习了如何在Core Data数据库中进行数据删除和实体搜索操作,以及如何创建iOS 8的高级扩展功能,包括Today扩展、自定义键盘扩展和共享扩展。这些功能可以为应用程序增加更多的交互性和实用性。

流程图

graph TD;
    A[开始] --> B[创建Single View iOS应用程序];
    B --> C{选择扩展类型};
    C -->|Today扩展| D[添加Today扩展];
    C -->|自定义键盘扩展| E[添加自定义键盘扩展];
    C -->|共享扩展| F[添加共享扩展];
    D --> G[设置小部件边距和显示内容];
    E --> H[设计键盘布局和处理输入];
    F --> I[实现共享逻辑和配置项];
    G --> J[运行应用程序];
    H --> J;
    I --> J;
    J --> K[完成];

表格

扩展类型 创建步骤
Today扩展 1. 创建应用程序
2. 添加Today扩展
3. 设置边距和显示内容
4. 运行应用程序
自定义键盘扩展 1. 创建或打开应用程序
2. 添加自定义键盘扩展
3. 设计键盘布局
4. 处理键盘输入
5. 运行应用程序
共享扩展 1. 创建应用程序
2. 添加共享扩展
3. 实现共享逻辑和配置项
4. 运行应用程序

3. 代码与使用说明

为了更好地使用上述功能,下面详细介绍代码的使用方法和具体配置。

3.1 Core Data操作代码

在进行Core Data数据库的删除和搜索操作时,需要将相应代码添加到 MasterViewController.swift 文件中。

3.1.1 删除操作代码

以下是完整的删除操作代码,包括表格视图的编辑和内容更新:

// MARK: Enable Editing
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        let context = self.fetchedResultsController.managedObjectContext
        context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
        helper.saveContext()
    }
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
    // In the simplest, most efficient, case, reload the table view.
    self.tableView.reloadData()
}

操作步骤如下:
1. 打开 MasterViewController.swift 文件。
2. 将上述代码复制到文件中。
3. 运行应用程序,向左滑动表格视图中的某一行,点击“删除”,该行将从表格视图中移除。

3.1.2 搜索操作代码

以下是包含 NSPredicate 搜索条件的 fetchedResultsController 属性代码:

var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {
        return _fetchedResultsController!
    }

    let fetchRequest = NSFetchRequest()
    let entity = NSEntityDescription.entityForName("Recipe", inManagedObjectContext: helper.managedObjectContext!)
    fetchRequest.entity = entity
    fetchRequest.fetchBatchSize = 20
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    let sortDescriptors = [sortDescriptor]
    fetchRequest.sortDescriptors = [sortDescriptor]
    let statusPredicate = NSPredicate(format: "serves < %d", 2)
    fetchRequest.predicate = statusPredicate
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: helper.managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController
    var error: NSError? = nil
    if !_fetchedResultsController!.performFetch(&error) {
        println("Unresolved error \(error), \(error?.userInfo)")
        abort()
    }
    return _fetchedResultsController!
}

操作步骤如下:
1. 打开 MasterViewController.swift 文件。
2. 找到 fetchedResultsController 属性,将上述代码替换原有的属性代码。
3. 运行应用程序,表格视图将显示符合搜索条件的结果。

3.2 iOS 8扩展代码

不同类型的iOS 8扩展有各自的代码实现和使用方法。

3.2.1 Today扩展代码

以下是 TodayViewController.swift RecipeService.swift 的完整代码:

// TodayViewController.swift
import UIKit
import NotificationCenter
class TodayViewController: UIViewController, NCWidgetProviding {
    @IBOutlet weak var recipeName: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        var service = RecipeService()
        recipeName.text = service.randomRecipe()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
        // Perform any setup necessary in order to update the view.
        // If an error is encountered, use NCUpdateResult.Failed
        // If there's no update required, use NCUpdateResult.NoData
        // If there's an update, use NCUpdateResult.NewData
        completionHandler(NCUpdateResult.NewData)
    }
    func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> (UIEdgeInsets) {
        return UIEdgeInsetsZero
    }
}
// RecipeService.swift
import Foundation
class RecipeService {
    var recipes = [
        "Grilled Fish",
        "Fajitas",
        "Chicken Stir Fry",
        "Hamburger",
        "Fried Chicken",
        "Miso Soup",
        "Lo Mein",
        "Tofu and Rice",
        "Spaghetti and Meatballs",
    ]
    func randomRecipe() -> String {
        return recipes[Int(arc4random_uniform(UInt32(recipes.count)))]
    }
}

操作步骤如下:
1. 创建一个Single View iOS应用程序,命名为 RecipeWidget
2. 添加 Today Extension ,命名为 RandomRecipe
3. 打开 TodayViewController.swift 文件,将上述 TodayViewController.swift 代码复制到该文件中。
4. 创建一个新的Swift文件 RecipeService.swift ,将上述 RecipeService.swift 代码复制到该文件中。
5. 在 TodayViewController.swift 文件中,确保 recipeName 标签的IBOutlet已正确连接。
6. 运行应用程序,在Today视图中添加 RandomRecipe 小部件,即可看到随机食谱名称。

3.2.2 自定义键盘扩展代码

以下是 KeyboardViewController.swift 的完整代码:

import UIKit
class KeyboardViewController: UIInputViewController {
    @IBOutlet var nextKeyboardButton: UIButton!
    @IBAction func newLine (sender: AnyObject) {
        (textDocumentProxy as! UITextDocumentProxy).insertText("\n")
    }
    @IBAction func backspace(sender: AnyObject) {
        (textDocumentProxy as! UITextDocumentProxy).deleteBackward()
    }
    @IBAction func keyUp(sender: AnyObject) {
        var proxy = textDocumentProxy as! UITextDocumentProxy
        var button = sender as? UIButton
        if let input = button?.titleLabel?.text as String? {
            if input == "Space" {
                proxy.insertText(" ")
                return
            }
            proxy.insertText(input)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        var xib = NSBundle.mainBundle().loadNibNamed("CodeKeyboard", owner: self, options: nil)
        var keyboardView = xib[0] as! UIView
        keyboardView.setTranslatesAutoresizingMaskIntoConstraints(false)
        view.addSubview(keyboardView)
        nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
    }
}

操作步骤如下:
1. 打开或创建一个Single View iOS应用程序。
2. 添加 Custom Keyboard 扩展。
3. 创建一个新的XIB文件 CodeKeyboard.xib ,设计键盘布局。
4. 打开 KeyboardViewController.swift 文件,将上述代码复制到该文件中。
5. 在XIB文件中,确保 nextKeyboardButton 的IBOutlet和 newLine backspace keyUp 的IBAction已正确连接。
6. 编译并运行项目,在模拟器中安装自定义键盘,即可使用。

3.2.3 共享扩展代码

以下是 ShareViewController.swift 的完整代码:

import UIKit
import Social
class ShareViewController: SLComposeServiceViewController {
    var userRating : SLComposeSheetConfigurationItem!
    let star : Character = "\u{2605}"
    override func isContentValid() -> Bool {
        var messageLength = count(self.contentText)
        var charactersRemaining = 100 - messageLength;
        self.charactersRemaining = charactersRemaining;
        if charactersRemaining >= 0 {
            return true;
        }
        return false;
    }
    override func didSelectPost() {
        println("Message: \(self.contentText)")
        self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
    }
    override func configurationItems() -> [AnyObject]! {
        userRating = SLComposeSheetConfigurationItem()
        userRating.title = "Rating"
        userRating.value = ""
        userRating.tapHandler = {
            SLComposeSheetConfigurationItemTapHandler in
            var starsSelection = UIViewController()
            var s1 = self.createStarButton(1)
            var s2 = self.createStarButton(2)
            var s3 = self.createStarButton(3)
            var s4 = self.createStarButton(4)
            var s5 = self.createStarButton(5)
            var views = ["s1":s1,"s2":s2,"s3":s3,"s4":s4,"s5":s5]
            starsSelection.view.addSubview(s1)
            starsSelection.view.addSubview(s2)
            starsSelection.view.addSubview(s3)
            starsSelection.view.addSubview(s4)
            starsSelection.view.addSubview(s5)
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat(
                    "H:|-[s1(s2)]-[s2(s3)]-[s3(s4)]-[s4(s5)]-[s5]-|",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s1(30)]",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s2(30)]",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s3(30)]",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s4(30)]",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            starsSelection.view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|-[s5(30)]",
                    options: NSLayoutFormatOptions(0), metrics: nil, views: views))
            self.pushConfigurationViewController(starsSelection)
        }
        return [userRating]
    }
    func createStarButton(value : Int ) -> UIButton {
        var button = UIButton()
        button.setTitle("\(star)", forState: UIControlState.Normal)
        button.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
        button.setTranslatesAutoresizingMaskIntoConstraints(false)
        button.tag = value
        return button
    }
}

操作步骤如下:
1. 创建一个Single View iOS应用程序。
2. 添加 Share Extension ,命名为 ShareRecipe
3. 打开 ShareViewController.swift 文件,将上述代码复制到该文件中。
4. 运行应用程序,在Safari中测试共享扩展,确保扩展已启用。

4. 总结与展望

通过上述内容,我们详细学习了Core Data数据库的操作方法,包括数据删除和实体搜索,以及iOS 8的多种高级扩展功能的创建过程,如Today扩展、自定义键盘扩展和共享扩展。这些功能可以极大地提升应用程序的交互性和实用性。

在实际开发中,可以根据具体需求对这些功能进行扩展和优化。例如,在Core Data搜索中,可以使用更复杂的 NSPredicate 条件;在iOS 8扩展中,可以添加更多的自定义功能和用户交互。未来,随着iOS系统的不断更新,可能会有更多的扩展类型和功能出现,开发者可以持续关注并将其应用到自己的项目中。

流程图

graph TD;
    A[开始] --> B[Core Data操作];
    A --> C[iOS 8扩展开发];
    B --> D[删除操作];
    B --> E[搜索操作];
    C --> F[Today扩展];
    C --> G[自定义键盘扩展];
    C --> H[共享扩展];
    D --> I[添加代码到MasterViewController.swift];
    E --> I;
    F --> J[创建应用和扩展];
    G --> K[创建或打开应用并添加扩展];
    H --> L[创建应用和扩展];
    J --> M[设置小部件和显示内容];
    K --> N[设计键盘布局和处理输入];
    L --> O[实现共享逻辑和配置项];
    I --> P[运行应用测试Core Data操作];
    M --> P;
    N --> P;
    O --> P;
    P --> Q[完成];

表格

功能类型 操作步骤 代码文件
Core Data删除操作 1. 打开 MasterViewController.swift
2. 添加删除代码
3. 运行应用测试
MasterViewController.swift
Core Data搜索操作 1. 打开 MasterViewController.swift
2. 替换 fetchedResultsController 属性代码
3. 运行应用测试
MasterViewController.swift
Today扩展 1. 创建应用和Today扩展
2. 添加 TodayViewController.swift RecipeService.swift 代码
3. 运行应用测试
TodayViewController.swift RecipeService.swift
自定义键盘扩展 1. 创建或打开应用并添加自定义键盘扩展
2. 创建 CodeKeyboard.xib 文件
3. 添加 KeyboardViewController.swift 代码
4. 运行应用测试
KeyboardViewController.swift CodeKeyboard.xib
共享扩展 1. 创建应用和共享扩展
2. 添加 ShareViewController.swift 代码
3. 运行应用测试
ShareViewController.swift
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值