tag:blogger.com,1999:blog-1266480015345788892.post8635070651020650554..comments2024-01-14T00:21:48.350-08:00Comments on Mastering Swift: Create a Data Access Layer with SQLite.swift and Swift 2Jonhttp://www.blogger.com/profile/15130741093149033106noreply@blogger.comBlogger41125tag:blogger.com,1999:blog-1266480015345788892.post-75203767568152754552017-06-15T01:09:44.549-07:002017-06-15T01:09:44.549-07:00Great article. I'd like to check how you'r...Great article. I'd like to check how you're going to do migration? Take your case as an example, I want to add a new field "logo" for the team. How are you going to do? Thanks.Bagusflyerhttps://www.blogger.com/profile/13854928652895456374noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-2500299227465121752016-09-30T05:43:40.629-07:002016-09-30T05:43:40.629-07:00No worries, i have already checked this documentat...No worries, i have already checked this documentation and added the limit query but still not working. it is working just like findAll so i'm stuck. Any way thank you for your time.R.AlAlihttps://www.blogger.com/profile/14983981367436379148noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-82078581120643220572016-09-29T13:58:29.583-07:002016-09-29T13:58:29.583-07:00Sorry I have been unable to answer, but between wo...Sorry I have been unable to answer, but between work/family/other commitments I am having trouble finding time. I have not has the opportunity to need to write a query like that with SQLite.swift but I did look through the documentation and found this example:<br /><br />let query = users.select(email) // SELECT "email" FROM "users"<br /> .filter(name != nil) // WHERE "name" IS NOT NULL<br /> .order(email.desc, name) // ORDER BY "email" DESC, "name"<br /> .limit(5, offset: 1) // LIMIT 5 OFFSET 1<br /><br />this is from the documentation here: https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#sqliteswift-documentation<br /><br />I have not tried it but it sure looks like it is what you need. Hope that helps you.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-19744752732176692172016-09-29T13:58:14.323-07:002016-09-29T13:58:14.323-07:00This comment has been removed by the author.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-1960426489895368332016-09-27T23:22:07.158-07:002016-09-27T23:22:07.158-07:00i would like to add paging so that when the user s...i would like to add paging so that when the user scroll to bottom more data will be loaded from the local database. i can only use the insert, delete, find and findAll queries. how can i add more queries so that i can retrieve data with page count (i.e get only 10 rows) <br />how can i use : users.limit(10, offset: 10) -> SELECT * FROM "users" LIMIT 10 OFFSET 10R.AlAlihttps://www.blogger.com/profile/14983981367436379148noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-62137779011938748512016-09-27T23:06:22.309-07:002016-09-27T23:06:22.309-07:00This comment has been removed by the author.R.AlAlihttps://www.blogger.com/profile/14983981367436379148noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-35219453665718146642016-09-27T07:15:43.925-07:002016-09-27T07:15:43.925-07:00This comment has been removed by the author.R.AlAlihttps://www.blogger.com/profile/14983981367436379148noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-10624160057748549392016-08-31T17:24:28.080-07:002016-08-31T17:24:28.080-07:00Great tutorial. Do you need to have a couple initi...Great tutorial. Do you need to have a couple initializers set up for the find and findAll functions?<br /><br />I keep getting an error saying it cannot invoke initializer for type Player with the argument list of types...@michaelofchanghttps://www.blogger.com/profile/06142401303705631931noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-27159773540165432842016-07-18T16:46:53.231-07:002016-07-18T16:46:53.231-07:00You are correct, SQLite will auto increment. In t...You are correct, SQLite will auto increment. In the definition for the table the teamId is set like this:<br /> -- t.column(teamId, primaryKey: true)<br />With the primaryKey set to true this id will auto increment which is why, in the insert() method of the TeamDataHelper we ignore the teamId. This is the line that sets the values for the insert:<br /> -- let insert = table.insert(city <- item.city!, nickName <- item.nickName!, abbreviation <- item.abbreviation!)<br />And you will notice we do not set the teamId which is why we do not bother to check to see if it is nil or not.<br />Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-7577490749991825642016-07-18T16:40:12.049-07:002016-07-18T16:40:12.049-07:00Hey great tutorial! No fat, all of it was informat...Hey great tutorial! No fat, all of it was informational.<br /><br />Is there a reason `teamId != nil` is not being checked in TeamDataHelper insert()?<br /><br />Also, on each of the Teams you add at the end ("Boston" and "Toronto") both teamId's are 0. Is that intentional? Does SQLite.swift autoincrement or is that just a typo?<br /><br /><br /><br />Akash Desaihttps://www.blogger.com/profile/09097155611263060937noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-92088003574946341472016-07-18T16:37:35.748-07:002016-07-18T16:37:35.748-07:00This comment has been removed by the author.Akash Desaihttps://www.blogger.com/profile/09097155611263060937noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-57134915498060835602016-05-03T06:24:56.513-07:002016-05-03T06:24:56.513-07:00Hi Jon, I'm implementing the bridge pattern yo...Hi Jon, I'm implementing the bridge pattern you've mentioned in the introduction of the tutorial and came up with something like this:<br /><br />The tuple (Dto in this case stands for "Data Transfer Object"):<br />typealias ProcedureDto = (<br /> procedureId: Int64?,<br /> name: String?,<br /> description: String?,<br /> estimatedTime: Double?<br />)<br /><br />And the struct to be used in the business logic:<br /><br />struct Procedure {<br /> init (procedureDto: ProcedureDto) {<br /> self.procedureDto = procedureDto<br /> }<br /> <br /> var procedureDto:ProcedureDto<br /> <br /> var procedureId: Int64 {<br /> get {<br /> return self.procedureDto.procedureId!<br /> }<br /> }<br /> <br /> var name: String {<br /> get {<br /> return self.procedureDto.name!<br /> }<br /> set {<br /> procedureDto.name = newValue<br /> }<br /> }<br /> <br /> var description: String {<br /> get {<br /> return self.procedureDto.description!<br /> }<br /> set {<br /> procedureDto.description = newValue<br /> }<br /> }<br /> <br /> var estimatedTime: Double {<br /> get {<br /> return self.procedureDto.estimatedTime!<br /> }<br /> set {<br /> procedureDto.estimatedTime = newValue<br /> }<br /> }<br />}<br /><br />Does it make sense to you? Would you do something different than that?<br /><br />Thanks in advance.Andre Sa https://www.blogger.com/profile/08073461718426949981noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-8389512124742515552016-05-02T14:57:28.720-07:002016-05-02T14:57:28.720-07:00Thanks, that makes sense.
I'll go buy your boo...Thanks, that makes sense.<br />I'll go buy your book!! Andre Sa https://www.blogger.com/profile/08073461718426949981noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-67815409250298252472016-05-02T13:55:06.637-07:002016-05-02T13:55:06.637-07:00I use tuples in the model layer because I want the...I use tuples in the model layer because I want the type to be a data storage type with no business logic. If you need you add logic (methods) to those types you could use a struct if you like but why would you want to add logic at that layer?<br />In the business logic layer I would recommend using structs however that is a personal preference. The key is to make all of the types either reference or value types for consistency.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-83546910196279700862016-05-02T13:54:44.423-07:002016-05-02T13:54:44.423-07:00This comment has been removed by the author.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-55989809697336699272016-05-02T06:22:41.684-07:002016-05-02T06:22:41.684-07:00Jon,
Great tutorial, very clear and helpful!!
Jus...Jon,<br /><br />Great tutorial, very clear and helpful!!<br />Just a quick question:<br />Why did you use typealias in the Model Layer? Could you have used structs instead?<br />And for the business logic, would you use structs or classes?<br /><br />Thanks.Andre Sa https://www.blogger.com/profile/08073461718426949981noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-45355379311105869892016-04-29T14:01:10.268-07:002016-04-29T14:01:10.268-07:00I am going to be updating this post for Swift 3 an...I am going to be updating this post for Swift 3 and I will put it in my list to include an update method. Thank you for the suggestion.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-67687341969712525852016-04-29T06:21:27.708-07:002016-04-29T06:21:27.708-07:00Is there any plans on adding an update method to t...Is there any plans on adding an update method to the DataHelper protocol? Would be nice to have a full/complete example on CRUD operations.Devhttps://www.blogger.com/profile/06925967012699198075noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-35885986804944024652016-04-29T06:20:37.799-07:002016-04-29T06:20:37.799-07:00This comment has been removed by the author.Devhttps://www.blogger.com/profile/06925967012699198075noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-34087168216243607432016-04-28T05:03:49.295-07:002016-04-28T05:03:49.295-07:00Thank you very much for your replies and this whol...Thank you very much for your replies and this whole tutorial. There really isn't much else out there about using SQLite.swift and the documentation is a little sparse.Suragchhttps://www.blogger.com/profile/02269888022687179507noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-54138462139257011462016-04-27T13:56:12.578-07:002016-04-27T13:56:12.578-07:00There is no threading solution that is right for a...There is no threading solution that is right for all situations however that is where I would start thinking about putting the threads. That solution may not work for you, as an example if you had say 50 tables it would be a pretty large effort to create delegates for each and every table. In that case maybe you want it in the business logic layer. The key is to have the ability to change how the data is stored and accessed (in the data access layer) without having to change your business logic layer.<br />I do not know anything about your data, how it is used, the amount of data or anything else about your application so I cannot really advise you how to use threads in you application, which is the reason my example does not include it. <br />If you have four or five very small tables, you may not need to access the data on a separate thread. If you have a 100 tables maybe you only want to use threads for four of five of the tables or maybe you need it for everything. I know some people say to always use threads but every situation is different and there are times you do not want the user to do anything until the data is displayed (think of a cover screen with an activity indicator). Where and how you use threads is very dependent on your application and your data. <br />Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-36825097565748908972016-04-26T21:55:01.093-07:002016-04-26T21:55:01.093-07:00Let me see if I have this right. In the general si...Let me see if I have this right. In the general situation, I would wrap the potentially time consuming database operations in a dispatch_async background task. This would be done for each of the methods in the DataHelper class layer. <br /><br />Example: http://stackoverflow.com/a/25070476<br /><br />When the background database task finishes, I would call a delegate method (that I create myself) to update the UI or whatever else I need to do.<br /><br />Is this correct?Suragchhttps://www.blogger.com/profile/02269888022687179507noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-18825674176303376162016-04-26T13:31:53.610-07:002016-04-26T13:31:53.610-07:00SQLite does not take care of the threading for you...SQLite does not take care of the threading for you, it is something that you need to do for yourself. I do not know your application or your application architecture but in general I would recommend putting the threading at the data access layer. You could then possibly use the delegation pattern to return results back. This may or may not work for you depending on your application. Think about how things like the UITableViewDelegate work.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-73194357588981992182016-04-26T13:31:23.418-07:002016-04-26T13:31:23.418-07:00This comment has been removed by the author.Jonhttps://www.blogger.com/profile/15130741093149033106noreply@blogger.comtag:blogger.com,1999:blog-1266480015345788892.post-81308514577591827272016-04-26T01:46:33.215-07:002016-04-26T01:46:33.215-07:00Thank you for your last reply about the business l...Thank you for your last reply about the business logic layer. That made sense.<br /><br />I notice in the various layers that nothing is done in a background thread. Does the SQLite.swift framework take care of that itself or is that something I should add to the business logic layer?Suragchhttps://www.blogger.com/profile/02269888022687179507noreply@blogger.com