Datenablage auf dem iPhone: pilist oder SQLite?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Datenablage auf dem iPhone: pilist oder SQLite?

    Hallo zusammen,

    darf ich fragen wie ihr eure Daten auf dem iPhone ablegt?
    Wenn ich mich nicht verlesen habe, gibt es ja kein CoreData, richtig?
    Jetzt habe ich aber Daten abzulegen, eigentlich sind es nur 2 Tabellen, und ich frage mich(keine Erfahrung :) ) was die bessere Wahl ist: plist oder SQLite.
    Kann man Relationen mit plist abbilden? Also wenn ein Datensatz in Tabelle2 gelöscht wird aber in Tabelle1 referenziert wird, sollte es eine Meldung geben.

    Könnt ihr mir einen kleinen Tip geben was besser geeignet ist? Bisher tendiere ich zu einer SQLite DB. Sollte der Zugriff aber viel einfacher auf eine plist seien, dann würde ich natürlich den einfacheren Weg bevorzugen.

    Gruß und Dank

    Dragi
  • RE: Datenablage auf dem iPhone: pilist oder SQLite?

    Ich mache das in der nächsten Ausgabe recht intensiv. Hier die Kurzfassung:

    Das Problem bei Plists ist, dass Zyklen, Mehrfachverweise und dergleichen zu einer Vervielfachung der verwiesenen Instanzen führen. Daher ist es erforderlich, das zu serialisieren. Hierfür dienen Die Subklassen von NSCoder.

    Lies dir also mal die Doku zu NSCoder durch.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Also plist's und SQL sind ja 2 komplett andere Schuhe.
    Beziehungen kannst Du zwar intern selbst
    abbilden (musst dich halt selbst drum kümmern) was aber meiner Meinung nach Quatsch ist, wenn
    es ne Datenbank gibt, die das bestimmt schneller und besser kann. Deshalb mein Tipp nimm ne DB und spar dir den Rest.
  • Auf dem iPhone? Ich würde immer noch einen Coder nehmen. Immerhin haben wir damit bis .4 (aka Pre-Core-Data) gut gelebt.

    Auch bei einer Datenbank hast du das Problem der Serialisierung. Die nimmt dir die DB ja nicht ab.
    +++
    cocoading.de/webspace/Cocoa_Kap4.pdf
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von Tom9811
    Auch bei einer Datenbank hast du das Problem der Serialisierung. Die nimmt dir die DB ja nicht ab.

    Das kommt doch drauf an was er speichern will. Wenn's nur einfache Datentypen sind, kann er sich das doch sparen
  • Na ja, du hast mindestens zwei Entitäten und eine Beziehung dazwischen. Wenn das easy-goibng ist von Format her, kann er auch einfach Property-Lists-Serialization nehmen. Das erspart mindestens die spätere "Neuindizierung" im RAM.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ich hab für meine App (noch nicht freigeschaltet) SQLite gewählt. Ist ein einfaches Datenbankmodell, eine Kategorientabelle, einen Linker und die Daten. Und ich muss sagen SQLite finde ich schon was geiles, er lädt die Liste von 1'600 Objekten (NSInteger und NSString) in wenigen hundert Millisekunden und das Handling ist - wenn man schon mehr mit SQL gemacht hat - sehr vertraut.

    Ich kann SQLite empfehlen - olles C-gekrame, aber mit Apple liefert mit dem SQBooks (oder so) ein gutes Beispiel mit. Obs Sinn macht, SQLite zu benutzen, keine Ahnung. :D
    Widgetschmie.de • Life is too short for gadgets
  • Ganz empfehlenswert ist Gus Muellers Wrapper FMDatabase. Alles schön in ObjC und trotzdem sehr leichtgewichtig.

    Ich habe die Erfahrung gemacht, dass einfache Serialisierung in vielen Fällen auf dem iPhone erheblich schneller war als SQLite und nutze jetzt eine Mischung aus beidem. Das mag allerdings auch teilweise an meinen eher rudimentären Datenbank-Kenntnissen liegen. Möglicherweise kann man da einiges optimieren.
  • Hallo,

    ich habe nochmals über meine Anforderugen nachgedacht und ich glaube das ich den Overhead einer DB nicht benötige. Es werden allerhöchstens 10Datensätze gespeichert mit jeweils nur einem einzigen String, und ich denke das ich da vielleicht besser mit einer plist arbeiten sollte.

    Nun habe ich aber folgendes Problem:

    Ich habe eine Plist courselist.plist in XCode unter Ressources angelegt. Darin habe ich den Typ auf Array gesetzt und einen String eingefügt.
    Nun möchte ich in meinem Programm ein NSMutableArray aus dieser plist erzeugen aber das Array ist leer:

    Quellcode

    1. (void)viewWillAppear:(BOOL)animated {
    2. [super viewWillAppear:animated];
    3. courseList = [[NSMutableArray alloc] init];
    4. [courseList initWithContentsOfFile:@"courselist.plist"];
    5. }


    courseList ist eine property aus meinem Header mit @synthesize bekanntgemacht.

    Ist irgendwas an diesem Code falsch? Könnt ihr mir helfen?

    Vielen Dank

    Dragi
  • Vorweg: Das iPhone SDK steht wohl nach wie vor unter NDA. Ich hab hier selbst schon Sachen gepostet, die in der Hinsicht vielleicht etwas unvorsichtig waren... Wird nicht wieder vorkommen.
    Da das zugrundeliegende Problem aber völlig unabhängig vom SDK ist und auf dem Mac genauso aufträte, werde ich hier mal trotzdem nochmal antworten.

    Erstens: wozu initialisierst du den Array zweimal?
    Zweitens: Du musst den ganzen Pfad zur Datei angeben. Z.B. so:

    Quellcode

    1. [[NSBundle mainBundle] pathForResource:@"courselist" ofType:@"plist"]
  • @omz

    Habe das Bild nur gepostet damit man sieht, das es kein Array zur Laufzeit gibt, dachte das wäre OK und hab dann den Code vergessen zu posten. :(

    Noch schreibe ich gar nicht :)
    Da ich noch nie mit plist gearbeitet habe, habe ich die plist in XCode mit einem String gefüllt und wollte nun als erstes das auslesen und anzeigen implementieren.

    Hier mal der komplette Code:

    CourseViewManagementController.h

    Quellcode

    1. #import <UIKit/UIKit.h>
    2. @interface CourseManagementViewController : UITableViewController {
    3. NSMutableArray *courseList;
    4. }
    5. @property (nonatomic, retain) NSMutableArray *courseList;
    6. @end


    CourseViewManagementController.m

    Quellcode

    1. #import "CourseManagementViewController.h"
    2. @implementation CourseManagementViewController
    3. @synthesize courseList;
    4. - (id)initWithStyle:(UITableViewStyle)style {
    5. if (self = [super initWithStyle:style]) {
    6. }
    7. return self;
    8. }
    9. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    10. return 1;
    11. }
    12. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    13. return [courseList count];
    14. }
    15. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    16. static NSString *MyIdentifier = @"MyIdentifier";
    17. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    18. if (cell == nil) {
    19. cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
    20. }
    21. // Configure the cell
    22. cell.text = [courseList objectAtIndex:indexPath.row];
    23. return cell;
    24. }
    25. /*
    26. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    27. }
    28. */
    29. /*
    30. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    31. if (editingStyle == UITableViewCellEditingStyleDelete) {
    32. }
    33. if (editingStyle == UITableViewCellEditingStyleInsert) {
    34. }
    35. }
    36. */
    37. /*
    38. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    39. return YES;
    40. }
    41. */
    42. /*
    43. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    44. }
    45. */
    46. /*
    47. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    48. return YES;
    49. }
    50. */
    51. - (void)dealloc {
    52. [super dealloc];
    53. }
    54. - (void)viewDidLoad {
    55. [super viewDidLoad];
    56. self.title = @"Kurse";
    57. UIBarButtonItem *addButton = [[[UIBarButtonItem alloc]
    58. initWithTitle:NSLocalizedString(@"+", @"")
    59. style:UIBarButtonItemStyleBordered
    60. target:self
    61. action:@selector(addAction:)] autorelease];
    62. self.navigationItem.rightBarButtonItem = addButton;
    63. }
    64. - (IBAction)addAction:(id)sender{
    65. }
    66. - (void)viewWillAppear:(BOOL)animated {
    67. [super viewWillAppear:animated];
    68. //courseList = [[NSMutableArray alloc] init];
    69. [courseList initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"courselist" ofType:@"plist"]];
    70. }
    71. - (void)viewDidAppear:(BOOL)animated {
    72. [super viewDidAppear:animated];
    73. }
    74. - (void)viewWillDisappear:(BOOL)animated {
    75. }
    76. - (void)viewDidDisappear:(BOOL)animated {
    77. }
    78. - (void)didReceiveMemoryWarning {
    79. [super didReceiveMemoryWarning];
    80. }
    81. @end
    Alles anzeigen


    Gruß

    dragi
  • Ich wollte damit nicht sagen, dass du deinen kompletten Code hier reinkopieren sollst. Das ist doch größtenteils für die Fragestellung gar nicht relevant. Ich habe nur keine Lust, den Code umrahmt von blinkenden Bannern mit der Lupe zu lesen...
    Übrigens gehört das Laden der Daten eher in die init-Methode deines Controllers. Du willst doch, dass das nur einmal aufgerufen wird, oder? Ist ansonsten nämlich ein schönes Memory-Leak...
  • OK, werde ich mir merken :)
    Verstehe, sollte wirklich in die Init-Methode, keine Ahnung warum ich das heute Nacht so gemacht habe. Schon geändert...und ein alloc hat natürlich gefehlt. Jetzt habe ich ein Array! Zwar noch irgend ein Fehler, aber das Array wurde erzeugt.

    Danke

    dragi
  • Also, jetzt mal vorausgesetzt deine courselist.plist ist im Ressourcen-Ordner und ist eine gültige plist-Datei, sowie courseList eine Instanzvariable vom Typ NSMutableArray.

    Folgendes funktioniert nicht:

    Quellcode

    1. courseList = [[NSMutableArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"courselist" ofType:@"plist"]];
    ?

    EDIT: zu spät... :) bzw. irgendwie habe ich die zweite Hälfte deines letzten Posts überlesen...
  • Leider habe ich mich zu früh gefreut!
    Ich bekomme folgende Fehlermeldung:

    2008-07-27 12:57:53.016 MyNavTest[7015:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray count]: method sent to an uninitialized mutable array object'

    Er initialisiert das Array nicht mit der plist. Vielleicht ist an der plist etwas falsch?
    Ich habe Root auf Typ Array eingestellt und dann Item1 als Typ string mit dem Value "test" (ohne Anführungszeichen).

    Gruß

    dragi
  • Wie erstellst du denn deine Plist? Xcode hat da einen ganz netten, eingebauten Editor. Du kannst über "New File" -> "Other" -> "Property List" eine leere Plist erstellen und hast dann eine tabellenartige Ansicht dafür. So kannst du Tippfehler in der XML-Syntax ganz gut vermeiden.
  • Ja, genauso habe ich das auch gemacht. Das ganze liegt dann bei der info.plist und den nib Files in dem Ordner Resources in der IDE.
    Und als Plaintext sieht es dann so aus:

    XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    3. <plist version="1.0">
    4. <array>
    5. <string>testcourse</string>
    6. </array>
    7. </plist>