Swift教程_零基础学习Swift完整实例(五)_swift完整实例(构建数据层)

简介:

3.构建数据层

按照官方sample,我们使用简单的plist来保存数据(当然使用内置数据库也ok)。该plist既是我们列表中需要显示的内容。

1.将化学元素的数据整理为Elements.plist,该plist的结构为Array<Dictionary>Java表示为ArrayList<Map<String,Object>>)。

dictionary中包含若干键值对,但一定要保证每个dictionary键值对的键和值的类型一致,这样我们才能够进行数据的解析。如图。


2. 在ElementDataModel目录下创建PKOElementDataModel类,作为化学元素的实体类,其中声明plist中所包含的键值对(由于部分属性没有使用,我这里就偷个懒省略了)。

由于我们的需求是要根据化学元素的状态种类来显示不同的底色,所以我们这里声明两个图片类型的属性,一个作为列表中行的左侧图标,另一个作为明细页面的展示用背景图,并重写他们的get方法,根据化学元素的状态种类来返回所需要的图片。

由于我们从plist仅能获得dictionary,所以我们需要进行转换,将从plist读出的dictionary转换为PKOElementDataModel对象,于是我们要写一个转换方法initWithDictionary(aDictionary : NSDictionary) ->PKOElementDataModel。

代码如下。

[objc]  view plain  copy
  1. import UIKit//swift部分包不需要import,但是ui还是要import进来才会生效  
  2.   
  3. class PKOElementDataModel {  
  4.       
  5.     var atomicNumber:Int = 0//前面说过,swift必须要对属性进行初始化,当然也可以用?来定义可选属性  
  6.     var name:String = ""//所有属性均使用swift类型,当然也可以使用NSString、NSNumber  
  7.     var symbol:String = ""  
  8.     var state:String = ""  
  9.     var atomicWeight:String = ""  
  10.     var discoveryYear:String = ""  
  11.     var group:Int = 0  
  12.     var period:Int = 0  
  13.       
  14.     var imageForDetailElementTileView:UIImage{  
  15.         get{  
  16.             return UIImage(named:self.state+"_256")  
  17.         }  
  18.     }  
  19.       
  20.     var imageForCellIconElementView:UIImage{  
  21.         get{  
  22.             return UIImage(named:self.state+"_37")  
  23.         }  
  24.     }  
  25.       
  26.     func initWithDictionary(aDictionary : NSDictionary) ->PKOElementDataModel{//个人并不认为这种方法是合理的,但是sample就是这么干的,照抄了  
  27.         self.atomicNumber = aDictionary["atomicNumber"] as Int  
  28.         self.atomicWeight = aDictionary["atomicWeight"] as String  
  29.         self.discoveryYear = aDictionary["discoveryYear"] as String  
  30.         self.name = aDictionary["name"] as String  
  31.         self.symbol = aDictionary["symbol"] as String  
  32.         self.state = aDictionary["state"] as String  
  33.         self.group = aDictionary["group"] as Int  
  34.         self.period = aDictionary["period"] as Int  
  35.         return self  
  36.     }  
  37. }  

3.构建好了实体类后,我们需要一个能够从plist读取数据的服务类PKOElementDataService,该类声明了我们展示列表需要的多种array及dictionary实体,并在类初始化时解析plist并组装对应的array及dictionary。

首先,我们需要一个单例的服务,所以需要创建一个单例对象sharedElementDataService,这里用了gcd技术,保证单例。
其次,由于需求要不同维度的数据,所以我们需要按照不同维度进行分类和排序。
代码如下。

[objc]  view plain  copy
  1. import UIKit  
  2.   
  3. class PKOElementDataService {//这里的“元素”均指业务上的化学元素,不要误会为技术词汇  
  4.     var elementDictionarys = [String:PKOElementDataModel]()//[元素名字:元素对象]  
  5.       
  6.     var symbolLetterArray = [String]()  
  7.     var stateArray = [String]()  
  8.       
  9.     var elementByNameArray = [PKOElementDataModel]()  
  10.     var elementByNumberArray = [PKOElementDataModel]()  
  11.     var elementSymbolDictionarys = [String:[PKOElementDataModel]]()//[元素简称首字母:元素对象集合]  
  12.     var elementStateDictionarys = [String:[PKOElementDataModel]]()//[元素状态:元素对象集合]  
  13.       
  14.     struct Inner {//单例模式的对象  
  15.         static var instance: PKOElementDataService?  
  16.         static var token: dispatch_once_t = 0  
  17.     }  
  18.       
  19.     class var sharedElementDataService: PKOElementDataService {//使用gcd技术保证线程安全  
  20.     dispatch_once(&Inner.token) {  
  21.         Inner.instance = PKOElementDataService()  
  22.         }  
  23.         return Inner.instance!  
  24.     }  
  25.       
  26.     init() {  
  27.         self.initElementArray()  
  28.     }  
  29.       
  30.     func initElementArray() {  
  31.         var thePath = NSBundle.mainBundle().pathForResource("Elements", ofType"plist")!  
  32.           
  33.         var elementArray = NSArray(contentsOfFile: thePath)//解析plist  
  34.           
  35.         self.elementDictionarys = [String:PKOElementDataModel]()  
  36.         self.elementStateDictionarys = [String:[PKOElementDataModel]]()  
  37.         self.elementSymbolDictionarys = [String:[PKOElementDataModel]]()  
  38.           
  39.         self.stateArray = [String]()  
  40.         self.symbolLetterArray = [String]()  
  41.           
  42.         for elementArrayDictionary in elementArray {  
  43.               
  44.             var elementDataModel = PKOElementDataModel().initWithDictionary(elementArrayDictionary as NSDictionary)  
  45.             self.elementDictionarys[elementDataModel.name] = elementDataModel  
  46.             if (self.elementStateDictionarys[elementDataModel.state] != nil) {  
  47.                 self.elementStateDictionarys[elementDataModel.state]?.append(elementDataModel)  
  48.             } else {  
  49.                 self.stateArray.append(elementDataModel.state)  
  50.                 self.elementStateDictionarys[elementDataModel.state] = [PKOElementDataModel]()  
  51.                 self.elementStateDictionarys[elementDataModel.state]?.append(elementDataModel)  
  52.             }  
  53.               
  54.             var symbolLetter = elementDataModel.symbol.substringToIndex(advance(elementDataModel.symbol.startIndex1))//获取首字母,需要用advance构建一个String.index,具体方法请看advance的官方文档  
  55.               
  56.             if (self.elementSymbolDictionarys[symbolLetter] != nil) {  
  57.                 self.elementSymbolDictionarys[symbolLetter]?.append(elementDataModel)  
  58.             } else {  
  59.                 self.symbolLetterArray.append(symbolLetter)  
  60.                   
  61.                 self.elementSymbolDictionarys[symbolLetter] = [PKOElementDataModel]()  
  62.                 self.elementSymbolDictionarys[symbolLetter]?.append(elementDataModel)  
  63.             }  
  64.         }  
  65.           
  66.         self.elementByNameArray = self.presortElementsByName()  
  67.           
  68.         self.elementByNumberArray = self.presortElementsByNumber()  
  69.           
  70.         self.symbolLetterArray = self.presortSymbolLetters()  
  71.         for letter in self.symbolLetterArray {  
  72.             self.presortElementsBySymbol(letter as String)  
  73.         }  
  74.           
  75.         self.stateArray = self.presortStates()  
  76.         for state in self.stateArray {  
  77.             self.presortElementsByState(state as NSString)  
  78.         }  
  79.     }  
  80.       
  81.     // sort the elementsSortedByName array  
  82.     func presortElementsByName() -> [PKOElementDataModel] {//下面多个方法分类别为元素集合排序  
  83.         var values = self.elementDictionarys.values  
  84.         var sortedElements = values.array.sorted({  
  85.             (s1, s2) -> Bool in  
  86.             return s2.name > s1.name  
  87.         })  
  88.         return sortedElements  
  89.     }  
  90.       
  91.     // sort the elementsSortedByNumber array  
  92.     func presortElementsByNumber() -> [PKOElementDataModel] {  
  93.         var values = self.elementDictionarys.values  
  94.         var sortedElements = values.array.sorted({  
  95.             (s1 , s2) -> Bool in  
  96.             return s1.atomicNumber > s2.atomicNumber  
  97.         })  
  98.         return sortedElements  
  99.     }  
  100.       
  101.     // sort the symbolLetter array  
  102.     func presortSymbolLetters() -> [String] {  
  103.         var keys = self.elementSymbolDictionarys.keys  
  104.         var sortedElement = keys.array.sorted({  
  105.             (s1 , s2) ->Bool in  
  106.             return s2 > s1  
  107.         })  
  108.         return sortedElement  
  109.     }  
  110.       
  111.     // sort the elementsSortedByName array  
  112.     func presortElementsBySymbol(letter : String) {  
  113.         self.elementSymbolDictionarys[letter]?.sort({  
  114.             (s1 , s2) ->Bool in  
  115.             return s1.name > s2.name  
  116.         })  
  117.     }  
  118.       
  119.     // sort the state array  
  120.     func presortStates () -> [String]{  
  121.         var keys = self.elementStateDictionarys.keys  
  122.         var sortedElements = keys.array.sorted({  
  123.             (s1 , s2) ->Bool in  
  124.             return s2 > s1  
  125.         })  
  126.         return sortedElements  
  127.     }  
  128.       
  129.     // sort the elementsSortedByName array  
  130.     func presortElementsByState (state : String) {  
  131.           
  132.         self.elementStateDictionarys[state]?.sort({  
  133.             (s1 , s2) ->Bool in  
  134.             return s2.name > s1.name  
  135.         })  
  136.     }  
  137. }  

4.由于我们需要将组装好的数据应用于tableView,而tableView提供一种方便的做法,就是实现UITableViewDatasource类,并重写其中方法。

我们先来构建一个定义这4类数据集的协议PKOTableDataSourceProtocol: UITableViewDataSource,当然,其中应包含一个方法,即通过索引获取数据对象。

代码如下。

[objc]  view plain  copy
  1. import UIKit  
  2.   
  3. protocol PKOTableDataSourceProtocol: UITableViewDataSource{  
  4.       
  5.     var name: String{ get }//tabBarItem名称  
  6.     var navigationBarName: String{ get }//导航标题  
  7.     var tabBarImage: UIImage{ get }//tabBarItem图标  
  8.     var tableViewStyle: UITableViewStyle{ get }//table样式  
  9.       
  10.     func elementDataModelForIndexPath(indexPath: NSIndexPath) ->PKOElementDataModel//通过索引获取数据对象  
  11. }  

5.构造4个类,实现PKOTableDataSourceProtocol协议,实现UITableViewDataSource需要实现的tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell、tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int两个方法;以及PKOTableDataSourceProtocol需要实现的elementDataModelForIndexPath(indexPath: NSIndexPath) ->PKOElementDataModel方法;当然根据不同需求可以实现UITableViewDataSource中其他的方法。

代码如下。我只粘了2段具有代表性的,其他请下载源码

[objc]  view plain  copy
  1. import UIKit  
  2.   
  3. class PKOTableByNameDataSource: NSObject, PKOTableDataSourceProtocol {  
  4.       
  5.     var name : String{  
  6.         get{  
  7.             return "Test1"  
  8.         }  
  9.     }  
  10.       
  11.     var navigationBarName : String{  
  12.         get{  
  13.             return "test1"  
  14.         }  
  15.     }  
  16.       
  17.     var tabBarImage : UIImage{  
  18.         get{  
  19.             return UIImage(named: "name_tab")  
  20.         }  
  21.     }  
  22.       
  23.     var tableViewStyle : UITableViewStyle{  
  24.         get{  
  25.             return UITableViewStyle.Plain//平铺格式,对应的Grouped可以去查一下什么效果。  
  26.         }  
  27.     }  
  28.       
  29.     func elementDataModelForIndexPath(indexPath: NSIndexPath) -> PKOElementDataModel {  
  30.         return PKOElementDataService.sharedElementDataService.elementByNameArray[indexPath.row]  
  31.     }  
  32.       
  33.     //Asks the data source for a cell to insert in a particular location of the table view.(required)  
  34.     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {  
  35.         var cell = tableView.dequeueReusableCellWithIdentifier("ElementTableViewCell", forIndexPath: indexPath) as PKOElementTableViewCell//根据标识获取我们自定义的TableViewCell  
  36.         var element = self.elementDataModelForIndexPath(indexPath)//根据索引获取对象  
  37.         cell.element = element  
  38.         return cell  
  39.     }  
  40.       
  41.     //Tells the data source to return the number of rows in a given section of a table view. (required)  
  42.     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  
  43.         return PKOElementDataService.sharedElementDataService.elementByNameArray.count//返回数据中对应分组的总数  
  44.     }  
  45.   
  46. }  
[objc]  view plain  copy
  1. import UIKit  
  2.   
  3. class PKOTableByStateDataSource: NSObject, PKOTableDataSourceProtocol {  
  4.       
  5.     var name : String{  
  6.         get{  
  7.             return "Test4"  
  8.         }  
  9.     }  
  10.       
  11.     var navigationBarName : String{  
  12.         get{  
  13.             return "test4"  
  14.         }  
  15.     }  
  16.       
  17.     var tabBarImage : UIImage{  
  18.         get{  
  19.             return UIImage(named: "state_tab")  
  20.         }  
  21.     }  
  22.       
  23.     var tableViewStyle : UITableViewStyle{  
  24.         get{  
  25.             return UITableViewStyle.Plain  
  26.         }  
  27.     }  
  28.       
  29.     func elementDataModelForIndexPath(indexPath: NSIndexPath) -> PKOElementDataModel {  
  30.         var state = PKOElementDataService.sharedElementDataService.stateArray[indexPath.section]  
  31.         return PKOElementDataService.sharedElementDataService.elementStateDictionarys[state]![indexPath.row]  
  32.     }  
  33.       
  34.     //Asks the data source for the title of the header of the specified section of the table view.  
  35.     func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {  
  36.         return PKOElementDataService.sharedElementDataService.stateArray[section]//根据组索引获取对应组名称  
  37.     }  
  38.       
  39.     //Asks the data source to return the titles for the sections for a table view.  
  40.     func sectionIndexTitlesForTableView(tableView: UITableView) -> [String] {  
  41.         return PKOElementDataService.sharedElementDataService.stateArray//获取组名称集合  
  42.     }  
  43.       
  44.     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {  
  45.         var cell = tableView.dequeueReusableCellWithIdentifier("ElementTableViewCell", forIndexPath: indexPath) as PKOElementTableViewCell  
  46.         var element = self.elementDataModelForIndexPath(indexPath)  
  47.         cell.element = element  
  48.         return cell  
  49.     }  
  50.       
  51.     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  
  52.         var state = PKOElementDataService.sharedElementDataService.stateArray[section]  
  53.         return PKOElementDataService.sharedElementDataService.elementStateDictionarys[state]!.count  
  54.     }  
  55.       
  56.     //Asks the data source to return the number of sections in the table view.  
  57.     func numberOfSectionsInTableView(tableView: UITableView) -> Int {  
  58.         return PKOElementDataService.sharedElementDataService.stateArray.count  
  59.     }  
  60.   
  61. }  

原文地址:http://blog.csdn.net/ooppookid/article/details/40373277

相关文章
|
数据处理 Swift
Swift 中的运算符和表达式是构建程序逻辑的基础,包括算术、关系、逻辑、位运算符及赋值运算符,用于数值计算、条件判断、位操作、赋值与更新等
Swift 中的运算符和表达式是构建程序逻辑的基础,包括算术、关系、逻辑、位运算符及赋值运算符,用于数值计算、条件判断、位操作、赋值与更新等。掌握这些工具是编写高效代码的关键。
336 1
|
编译器 Swift iOS开发
Swift 教程
10月更文挑战第23天
188 1
|
Swift C++ 索引
Swift开发——简单函数实例
函数是编程的基础,用于封装特定功能的代码。它们有关键词func、函数名、参数列表(可为空)和返回类型。多返回值可通过元组、数组、inout参数或可选类型实现。例如,返回元组 `(value1, value2)`,数组 `[value1, value2]` 或使用可选数组 `[[Double]]?`。函数可以作为其他函数的参数,类似闭包或Lambda表达式。在Swift中,示例展示了通过元组、带索引的元组、数组和可选类型返回多个值的函数。还演示了如何使用inout参数交换变量值。
333 5
Swift开发——简单函数实例
|
人工智能 物联网 API
LLM 大模型学习必知必会系列(十三):基于SWIFT的VLLM推理加速与部署实战
LLM 大模型学习必知必会系列(十三):基于SWIFT的VLLM推理加速与部署实战
LLM 大模型学习必知必会系列(十三):基于SWIFT的VLLM推理加速与部署实战
|
安全 Swift Android开发
构建移动应用:Swift vs Kotlin —— 两大主流语言的对决
【5月更文挑战第11天】Swift与Kotlin在移动应用开发中各有优势。Swift是iOS开发的首选,以其简洁语法、高性能和类型安全著称;而Kotlin是Android的官方推荐语言,以其与Java的无缝互操作、空安全特性和简洁代码受到青睐。两者在语法简洁性、性能和社区支持上表现优秀,但平台兼容性不同。开发者应根据项目需求和目标平台选择合适的语言。
1548 1
|
机器学习/深度学习 数据采集 TensorFlow
【Swift开发专栏】Swift与机器学习:构建智能应用
【4月更文挑战第30天】本文探讨了使用Swift开发机器学习应用,分为三个部分:机器学习基础(定义、类型及应用),Swift在机器学习中的作用(Swift for TensorFlow、Core ML及性能优势),以及实践技巧(数据预处理、特征工程、模型训练与部署、性能优化和用户界面集成)。通过学习,开发者能掌握构建智能应用的技能,利用Swift的性能和安全性提升应用效率。随着深入学习,开发者可探索更多高级特性和技术,如深度学习和复杂数据分析。
495 2
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
760 1
|
监控 Swift iOS开发
局域网计算机监控软件中利用Swift构建iOS端的移动监控应用
在局域网计算机监控软件的开发中,构建iOS端的移动监控应用是一项关键任务。本文将介绍如何利用Swift语言实现这一目标,通过多个代码示例展示关键功能的实现。
447 1
|
安全 编译器 Swift
【Swift开发专栏】Swift的编译优化与构建配置
【4月更文挑战第30天】Swift编译优化与构建配置对开发效率和应用性能至关重要。编译优化包括不同级别的优化、函数内联、泛型特化、尾递归优化、死代码消除和链接时优化。在Xcode的&quot;Build Settings&quot;中可调整相关标志。构建配置涉及Debug与Release模式、自定义配置、条件编译、构建设置和脚本。开发时,应适时测试、选择适当优化级别、避免过度优化,并利用条件编译区分不同版本的代码。有效管理构建设置可提升开发质量和性能。
555 0
|
API 数据库 Swift
【Swift开发专栏】Swift中的数据持久化:Core Data与Realm
【4月更文挑战第30天】本文探讨了Swift中两种流行的数据持久化框架——Core Data和Realm。数据持久化是保持应用数据在不同运行周期间一致性的关键。Core Data,苹果的ORM系统,适合处理复杂数据关系,提供与iOS生态系统的无缝集成。使用Core Data涉及定义数据模型、生成NSManagedObject子类、配置持久化容器及执行数据操作。而 Realm,一个轻量级数据库,以其高性能、易于使用的API和实时数据同步适用于跨平台项目。在Swift中使用Realm,需定义数据模型、配置Realm实例、执行数据操作并观察数据变化。理解这两者能帮助开发者构建更高效、可靠的应用。
567 0