[Gelöst][MySQL/JSON] Daten werden unregelmäßig geladen

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

    • [Gelöst][MySQL/JSON] Daten werden unregelmäßig geladen

      Hallo,

      ich bin erst seit kurzem in die iPhone-Programmierung eingestiegen und möchte anhand eines Beispielprojekts mein Erlerntes umsetzen. Leider komme ich im Moment nicht weiter und brauche etwas Hilfe von erfahrenen Entwicklern.

      Mein Versuch ist es Daten aus einer Datenbank in einem TableView anzeigen zu lasssen. Ich baue dazu eine Verbindung zum Pfad meines PHP-Skriptes auf, dass die Abfrage durchführt und mir anschließend die Daten aus der Datenbank als JSON zurückliefert. Das JSON parse ich mit Hilfe von stig/json-framework. Das funktionert auch alles soweit. Im Simulator. Wenn ich die App auf meinem Gerät installiere und das TableView lade, werden die Daten mal angezeigt und mal nicht.

      Die Konsole gibt folgende Warnungen aus (in unterschiedlicher Reihenfolge):

      Quellcode

      1. -JSONValue failed. Error is: Unexpected end of input
      2. -JSONValue failed. Error is: Illegal start of token [i]
      3. -JSONValue failed. Error is: Token 'string' not expected before outer-most array or object
      4. -JSONValue failed. Error is: Token 'key-value separator' not expected before outer-most array or object


      Ich weiß nicht wo das Problem liegt, damit ich den Fehler beheben kann. Laut JSONLint ist das zurückgelieferte JSON valide.
      Das merkwürdige ist, dass dieses Problem nur auf dem Gerät auftaucht. Im Simulator werden alle Daten wie gewünscht geladen und dementsprechend ausgegeben.
      Außerdem habe ich das mit Datenbanken die sowohl lokal als auch online liegen ausprobiert, aber immer wieder mit dem selben Ergebnis. Simulator = :thumbsup: / Gerät = :thumbdown:

      Weiß jemand Rat?
      Beste Grüße,
      Jens

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jmar23 () aus folgendem Grund: Problem behoben

    • Wie holst Du denn die Daten vom Server ? Klingt für mich so als wären die JSON Daten unvollständig im Device. Lass Dir doch mal die Länge des JSON ausgeben sowohl im PHP Script als auch im Device nach dem Empfang.


      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • hm wir reden wohl aneinander vorbei.

      Benutzt du ein HTTPRequest oder was um die Daten zu laden ?

      Wie wäre es mal mit ein wenig Code wo man sieht wie du den Request erzeugst, abschickst etc ?

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Thallius ()

    • Sry.

      Quellcode

      1. // TopAdsTableViewController.h
      2. #import
      3. @interface TopAdsTableViewController : UIViewController {
      4. UITableView *myTableView;
      5. NSMutableArray *topAds;
      6. NSMutableArray *retailer;
      7. NSMutableArray *article_id;
      8. NSMutableArray *price;
      9. }
      10. @property (nonatomic, retain) IBOutlet UITableView *myTableView;
      11. @property (nonatomic, retain) NSMutableArray *topAds;
      12. @property (nonatomic, retain) NSMutableArray *retailer;
      13. @property (nonatomic, retain) NSMutableArray *article_id;
      14. @property (nonatomic, retain) NSMutableArray *price;
      15. @end
      Alles anzeigen


      Quellcode

      1. // TopAdsTableViewController.m
      2. #import "TopAdsTableViewController.h"
      3. #import "SBJson.h"
      4. #import "CustomCell.h"
      5. #import "TopAdsDetailView.h"
      6. #define URL_PATH @" ... "
      7. @implementation TopAdsTableViewController
      8. @synthesize myTableView;
      9. @synthesize topAds, retailer, article_id, price;
      10. - (void)viewDidLoad {
      11. self.title = @"Top-Anzeigen";
      12. topAds = [[NSMutableArray alloc] init];
      13. retailer = [[NSMutableArray alloc] init];
      14. article_id = [[NSMutableArray alloc] init];
      15. price = [[NSMutableArray alloc] init];
      16. [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
      17. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL_PATH]];
      18. NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      19. [super viewDidLoad];
      20. }
      21. #pragma mark -
      22. #pragma mark NSURLConnection delegate methods
      23. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
      24. {
      25. NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
      26. NSDictionary *jsonValue = [jsonString JSONValue];
      27. NSArray *results = [jsonValue objectForKey:@"pt_onlytopads"];
      28. for (NSDictionary *result in results)
      29. {
      30. NSString *ta_title = [result objectForKey:@"ta_title"];
      31. [topAds addObject:ta_title];
      32. NSString *company = [result objectForKey:@"company"];
      33. [retailer addObject:company];
      34. NSString *ta_adid = [result objectForKey:@"ta_adid"];
      35. [article_id addObject:ta_adid];
      36. NSString *ta_price = [result objectForKey:@"ta_price"];
      37. [price addObject:ta_price];
      38. }
      39. [myTableView reloadData];
      40. }
      41. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
      42. {
      43. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
      44. UIAlertView *alertError = [[UIAlertView alloc] initWithTitle:@"Fehler"
      45. message:[NSString stringWithFormat:@"%@", [error localizedDescription]]
      46. delegate:self
      47. cancelButtonTitle:@"Abbrechen"
      48. otherButtonTitles:nil];
      49. [alertError show];
      50. [alertError release];
      51. [connection release];
      52. }
      53. - (void)connectionDidFinishLoading:(NSURLConnection *)connection
      54. {
      55. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
      56. [connection release];
      57. }
      58. #pragma mark - UITableView delegate methods
      59. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
      60. {
      61. return 1;
      62. }
      63. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
      64. {
      65. return [topAds count];
      66. }
      67. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      68. {
      69. return 90;
      70. }
      71. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      72. {
      73. static NSString *MyIdentifier = @"CustomCell";
      74. CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
      75. if (cell == nil) {
      76. NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil];
      77. for (id currentObject in topLevelObjects)
      78. {
      79. if ([currentObject isKindOfClass:[UITableViewCell class]])
      80. {
      81. cell = (CustomCell *)currentObject;
      82. break;
      83. }
      84. }
      85. }
      86. if ([topAds objectAtIndex:indexPath.row] == [NSNull null])
      87. {
      88. cell.titleLabel.text = @"Kein Titel vorhanden";
      89. } else
      90. {
      91. cell.titleLabel.text = [topAds objectAtIndex:indexPath.row];
      92. }
      93. cell.titleLabel.font = [UIFont boldSystemFontOfSize:14.0];
      94. cell.titleLabel.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0];
      95. cell.titleLabel.adjustsFontSizeToFitWidth = NO;
      96. cell.retailerLabel.text = [NSString stringWithFormat:@"Händler: %@", [retailer objectAtIndex:indexPath.row]];
      97. cell.retailerLabel.font = [UIFont systemFontOfSize:13.0];
      98. cell.retailerLabel.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0];
      99. cell.retailerLabel.adjustsFontSizeToFitWidth = NO;
      100. cell.articel_idLabel.text = [NSString stringWithFormat:@"Artikel-Nr: %@", [article_id objectAtIndex:indexPath.row]];
      101. cell.articel_idLabel.font = [UIFont systemFontOfSize:11.0];
      102. cell.articel_idLabel.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0];
      103. cell.articel_idLabel.adjustsFontSizeToFitWidth = NO;
      104. cell.priceLabel.text = [NSString stringWithFormat:@"%@ €", [price objectAtIndex:indexPath.row]];
      105. cell.priceLabel.font = [UIFont boldSystemFontOfSize:14.0];
      106. cell.priceLabel.textColor = [UIColor colorWithRed:170/255.0 green:5/255.0 blue:21/255.0 alpha:1.0];
      107. cell.priceLabel.textAlignment = UITextAlignmentRight;
      108. cell.priceLabel.adjustsFontSizeToFitWidth = NO;
      109. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
      110. cell.selectionStyle = UITableViewCellSelectionStyleGray;
      111. return cell;
      112. }
      113. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
      114. {
      115. TopAdsDetailView *topAdsDetailView = [[TopAdsDetailView alloc] initWithNibName:@"TopAdsDetailView" bundle:nil];
      116. topAdsDetailView.navigationItem.title = [topAds objectAtIndex:indexPath.row];
      117. topAdsDetailView.detail_adid = [article_id objectAtIndex:indexPath.row];
      118. topAdsDetailView.detailTitle = [topAds objectAtIndex:indexPath.row];
      119. topAdsDetailView.detailRetailer = [retailer objectAtIndex:indexPath.row];
      120. topAdsDetailView.detailPrice = [price objectAtIndex:indexPath.row];
      121. [self.navigationController pushViewController:topAdsDetailView animated:YES];
      122. [topAdsDetailView release];
      123. [myTableView deselectRowAtIndexPath:indexPath animated:YES];
      124. }
      125. #pragma mark - Memory Management methods
      126. - (void)didReceiveMemoryWarning {
      127. [super didReceiveMemoryWarning];
      128. }
      129. - (void)viewDidUnload {
      130. [super viewDidUnload];
      131. }
      132. - (void)dealloc {
      133. [price release];
      134. [article_id release];
      135. [retailer release];
      136. [topAds release];
      137. [myTableView release];
      138. [super dealloc];
      139. }
      140. @end
      Alles anzeigen
      Beste Grüße,
      Jens

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von jmar23 ()

    • So habe in der Zwischenzeit Feierabend gemacht und bin Heim gefahren.

      Ja, die connection:didFailWithError:-Methode habe ich implementiert.


      Meinen Beitrag von vorhin habe ich eben aktualisiert und einen ausführlicheren Code bereitgestellt.
      Habe jetzt Zuhause exakt die selben Bedingungen wie in der Agentur und das Problem besteht weiterhin.
      Beste Grüße,
      Jens
    • Also eigentlich sieht alles gut aus. Das einzige was wir spontan auffällt ist, das du das [super viewDidLoad] als erstes machen solltest und nicht als letztes aber das kann eigentlich nicht zu dem Fehler führen.

      Weiterhin würde ich den Request im viewDidAppear und nicht im viewDidLoad machen, da Du ja im Fehlerfall einen alertView machst und der ja einen Rootview braucht auf dem er angezeigt werden kann. Beim viewDidLoad ist ja der View noch gar nicht vorhanden.

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Michael schrieb:

      Thallius schrieb:

      Das einzige was wir spontan auffällt ist, das du das [super viewDidLoad] als erstes machen solltest und nicht als letztes aber das kann eigentlich nicht zu dem Fehler führen.

      Ich frage mich sowieso, ob man überhaupt [super viewDidLoad] machen muss. Laut Dokumentation muss man das nämlich nicht.

      Michael


      Warum kann ich Dir leider auch nicht sagen, aber erstelle einfach mal ein neues Projekt mit einem ViewController. Da steht das [super viewDidLoad] schon drin. Also wird es wohl irgendeinen Sinn haben.

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Thallius schrieb:

      Michael schrieb:

      Thallius schrieb:

      Das einzige was wir spontan auffällt ist, das du das [super viewDidLoad] als erstes machen solltest und nicht als letztes aber das kann eigentlich nicht zu dem Fehler führen.

      Ich frage mich sowieso, ob man überhaupt [super viewDidLoad] machen muss. Laut Dokumentation muss man das nämlich nicht.

      Michael


      Warum kann ich Dir leider auch nicht sagen, aber erstelle einfach mal ein neues Projekt mit einem ViewController. Da steht das [super viewDidLoad] schon drin. Also wird es wohl irgendeinen Sinn haben.

      Was in dem Code der Templates so drin steht, ist für mich keine vernünftige Begründung. Bei den view..Appear Methoden steht in der Dokumentation drin, das man einen „call to super“ machen muss. Bei viewDid(Un)Load steht das eben nicht.

      Michael
    • Michael schrieb:

      Thallius schrieb:

      Michael schrieb:

      Thallius schrieb:

      Das einzige was wir spontan auffällt ist, das du das [super viewDidLoad] als erstes machen solltest und nicht als letztes aber das kann eigentlich nicht zu dem Fehler führen.

      Ich frage mich sowieso, ob man überhaupt [super viewDidLoad] machen muss. Laut Dokumentation muss man das nämlich nicht.

      Michael


      Warum kann ich Dir leider auch nicht sagen, aber erstelle einfach mal ein neues Projekt mit einem ViewController. Da steht das [super viewDidLoad] schon drin. Also wird es wohl irgendeinen Sinn haben.

      Was in dem Code der Templates so drin steht, ist für mich keine vernünftige Begründung. Bei den view..Appear Methoden steht in der Dokumentation drin, das man einen „call to super“ machen muss. Bei viewDid(Un)Load steht das eben nicht.

      Michael


      Jetzt stellt sich halt die Frage ob Apple ei der Doku zum viewDidLoad vergessen hat das reinzuschreiben oder bei den Templates das super zu viel reingeschrieben hat.

      Eigentlich egal. Schaden tut es auf jeden Fall nicht.

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Der Fehler liegt in didReceiveData, hier kann es sein das noch nicht alle Data geleseworden sind. Diese Funktion kann mehrmals aufgerufen werden, bis alle Daten vorhanden sind, deswegen dein Bruch im Json Konstrukt ! Erst wenn die Connection komplett durch ist (connectionDidFinishLoading) solltest Du den String mittels Json parsen ! Also erst alles sammeln, wenn feddich parsen !
      Si tacuisses, philosophus mansisses !
    • Hallo,

      ich hätte noch eine Frage und würde da gerne noch einmal nachhaken:

      Und zwar habe ich ja die Connection in die viewDidAppear-Methode geschrieben. Das bedeutet ja, dass jedesmal, wenn der View erscheint, die Methode ausgeführt wird.
      Als Beispiel: Wenn ich auf ein TableViewCell tippe, rufe ich über die didSelectRowAtIndexPath-Methode ein DetailViewController auf. Wenn ich nun von dem DetailViewController mittles "Zurück"-Button zurück zum TableView navigiere, werden ja die Daten erneut geladen. Kann man das verhindern?
      Beste Grüße,
      Jens
    • Mon, moin,

      ich mache das immer mit einem Flag, z.B. eine bool variable firstStart. Diese setzte ich in viewDidLoad auf YES. Beim ersten viewDidAppear wird diesee abgefragt und dann beim ersten mal Ausführen der Connection Anfrage auf NO gesetzt.


      Quellcode

      1. -(void)viewDidAppear ...
      2. if(firstStart) {
      3. [self tueWasMitderConnectionOderSo]; // Daten für die Table laden oder so etwas ...
      4. firstStart = NO;
      5. }
      Si tacuisses, philosophus mansisses !

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von FRing ()