2013-02-12 6 views
13

Ich habe seit einiger Zeit mit diesem Problem kämpfen und ich kann es nicht genau genug reproduzieren, um den genauen Anwendungsfall zu beschreiben. Im Grunde, was ich tue ist iOS 6.0 Facebook share Dialog zum Öffnen einer nativen eine Anforderung ausgeben (unter Verwendung des Facebook-SDK für iOS 3.1.1):Inkonsistente Absturz beim Posten auf Facebook mit FBNativeDialogs auf iOS6.0

if ([[SocialManager sharedManager] isNativeFacebookShareDialogAvailable]) { 

     if (!url) { 
      url = [NSURL URLWithString:@""]; 
     } 

     if (!imageUrl) { 
      imageUrl = [NSURL URLWithString:@""]; 
     } 

     dispatch_async(backgroundQueue, ^{ 

      NSData *imageData = [NSData dataWithContentsOfURL:imageUrl]; 
      UIImage *image  = [UIImage imageWithData:imageData]; 

      if (!image) { 
       image = [[UIImage alloc] init]; 
      } 

      if ([FBNativeDialogs canPresentShareDialogWithSession:[FBSession activeSession]]) { 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        [FBNativeDialogs presentShareDialogModallyFrom:sender initialText:initialText images:@[image] urls:@[url] handler:^(FBNativeDialogResult result, NSError *error) { 
         if (error) { 
          failBlock([[error userInfo] description]); 
         } else { 
          if (result == FBNativeDialogResultSucceeded) { 
           completionBlock(); 
          } else if (result == FBNativeDialogResultCancelled) { 
           failBlock(@"User cancelled"); 
          } else if (result == FBNativeDialogResultError) { 
           failBlock(@"Unknown error"); 
          } 
         } 
        }]; 
       }); 

      } else { 
       LogErr(@"Can't display native share dialog for active session"); 
      } 
     }); 
    } 

Gleich nach presentShareDialogModallyFrom:sender genannt wird, entweder bekomme ich folgenden Absturz log:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x1d161490> was mutated while being enumerated.' 
*** First throw call stack: 
(0x32ede2a3 0x326b097f 0x32eddd85 0x35da094d 0x32edb62f 0x35da07f5 0x35e7e5e5 0x35e0ccd7 0x35e0cb6d 0x372c490f 0x35e0ca61 0x35e160d5 0x372b783b 0x35e160b1 0x372b711f 0x372b699b 0x372b6895 0x372c5215 0x372c53b9 0x36f5fa11 0x36f5f8a4) 
libc++abi.dylib: terminate called throwing an exception 

OR ich keinen Absturz und das native Anteil Dialog erscheint, wie es sollte.

Der Stapel einen Anruf an einem Faden UIRemoteViewControllerCreationRequest an dieser Stelle genannt schon sagt, hier sind zwei Beispiele für zwei verschiedene Abstürze: enter image description here enter image description here

Danke für Ihre Hilfe

+0

UIRemoteViewControllerCreationRequest ist Teil des Namens des Threads. Sie müssen den Thread-Stack mit dem Schieberegler unter den Stapeln erweitern. Dann können wir alle Anrufe im Stapel sehen. –

+0

Danke, bearbeitete Frage – Stavash

+0

Woher wird Ihr Snippet aufgerufen (z. B. viewDidLoad oder eine IBAction)? –

Antwort

2

Nach viel mit meiner Anwendung zu experimentieren und suchen in Facebook SDK Quelle erkannte ich 3 Dinge:

  1. ein SLComposeViewController selbst erstellen hilft nicht. Facebook SDK ist ziemlich einfach in diesem, es erstellt nur den Controller genau wie der Code in der Antwort mit Bonus.

  2. Wenn Sie die FB-Sitzung autorisieren, wird Ihre Anwendung ein- oder mehrmals deaktiviert. Dies wird durch die Warnmeldungen zur Bestätigung der Berechtigung verursacht.

  3. Die UIRemoteViewController ist eigentlich die SLComposeViewController, die in einem anderen Prozess ausgeführt wird.

Was verursachte meinen Fehler?

  1. Benutzer bestätigt FB Berechtigungen
  2. Dies löst applicationDidBecomeActive:
  3. Es löst auch FB Rückruf um den Dialog zu präsentieren.
  4. Meine applicationDidBecomeActive: war etwas mit der UI, was nicht getan werden sollte, wenn die FB-Dialoge erscheinen (tiranggering eine Tabelle neu laden).

Auch ist es eine andere Sache, vorsichtig zu sein - der Handler von presentShareDialogModallyFrom... ist nicht auf einen bestimmten Thread aufgerufen (SLComposeViewController docs sehen). Das bedeutet, dass Sie dispatch_async(dispatch_get_main_queue(), ...) aus dem Handler verwenden sollten, wenn Sie die Benutzeroberfläche von ihm aktualisieren.

EDIT: Offensichtlich die vorherigen Schritte einige Abstürze behoben, aber einer der Abstürze wurde nicht gelöst. Nach einer Menge Googeln und Durchsuchen von Apple Developer Foren, denke ich, gibt es einen Fehler in iOS 6 mit Remote Controllern verbunden und mit UIAppearance, vor allem das Auftreten von UINavigationBar. Ich entferne derzeit die Verwendung von UIApperance aus meiner App.

+0

omg Entfernung UIAppearance von der App hat mir wirklich geholfen, ich sehe nicht Absturz im Augenblick, danke für diese Antwort BTW. Hast du irgendwelche Updates zu diesem Thema? –

+0

@ KonradSzczęśniak Es scheint, dass das Problem auf iOS 7 behoben wurde :) – Sulthan

+0

OK ich habe Lösung :) überprüfen Sie die genehmigte Antwort http://stackoverflow.com/questions/16256399/uinavigationbar-appearance-and-facebook-sheet-bug –

-2

Ich denke, Sie wissen, was ist offensichtlich, aber ich traf diesen Fehler einmal und es war ein NSMutableArray, das mutiert wurde, während es in einer for..in-Anweisung aufgezählt wurde.

Betrachten Sie das NSMutableArray, Sie werden Ihren Fehler finden.

Übrigens, wenn Sie IOS6 als Ziel haben, warum verwenden Sie nicht das soziale Framework mit nativer Facebook-Implementierung?

+0

Ich sehe keine NSArrays im geposteten Code. – StilesCrisis

+0

Dies hat nichts mit der Iteration über Arrays zu tun. Das Array, das den Absturz verursacht hat, wird vom Betriebssystem verwaltet und repräsentiert wahrscheinlich in diesem Kontext die Ansichtshierarchie. Ich benutze das Facebook SDK, um 5.0+ Kompatibilität zu bieten. – Stavash

+0

Oder vielleicht tut es, aber stürzt außerhalb des gebuchten Codes ab? Es ist nicht, weil dieser Code den Absturz verursacht, dass der Absturz in diesem Code passiert. – Diwann

1

Dies ist eine sehr seltsame Möglichkeit, einen Beitrag auf Facebook zu veröffentlichen. Hier ist ein viel einfacherer Weg, der niemals abstürzt.

ViewController.h

#import <UIKit/UIKit.h> 
#import <Social/Social.h> 
#import <Accounts/Accounts.h> 

@interface ViewController : UIViewController { 
SLComposeViewController *mySLComposerSheet; 
} 
- (IBAction)PostToFacebook:(id)sender; 

@end 

ViewController.m @implementation Viewcontroller

- (IBAction)PostToFacebook:(id)sender { 
mySLComposerSheet = [[SLComposeViewController alloc] init]; 
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook]; 
[mySLComposerSheet setInitialText:@"Place Text Here"]; 
[self presentViewController:mySLComposerSheet animated:YES completion:nil]; 
} 
@end 

Bei Bedarf gibt es ein Video here.

+1

Ich verstehe nicht, warum Sie dies eine seltsame Art, auf Facebook zu posten. So wie ich es sehe, hat Facebook ein SDK nur für den Zweck der Arbeit mit iOS erstellt, so dass es ziemlich vergeblich wäre, eine bessere Implementierung mit dem Social Framework als einzelner Entwickler zu versuchen. Das heißt, ich möchte Ihnen für Ihre Antwort danken, aber ich möchte die SDK-Implementierung verwenden. – Stavash

+0

Die Arbeit mit SLComposeViewController war die einzige Problemumgehung, die mir geholfen hat. Deshalb gebe ich Ihnen das Kopfgeld. Es gibt jedoch ein Problem in Ihrem Code - eine redundante Allocation, init. Vielen Dank für Ihre Antwort – Stavash

+0

Sorry für den Fehler – OnkaPlonka

1

Leider einige dieser eher ist zu raten, aber ich dachte, ich würde versuchen:

Sind Sie sicher, dass canPresentShareDialogWithSession sicher von einem Nicht-UI-Thread aufgerufen werden kann?

Sie haben eine Zeile in beiden Stapeln von _NSDictionaryEnumerate. Es sieht aus wie von höheren Funktionen, dass etwas Aufruf enumerateKeysAndObjectsUsingBlock :.

Basierend auf Ihrer Notiz von Dingen, die kurz nach [presentShareDialogModallyFrom: sender] abstürzen. Wird etwas freigegeben, wenn die Ansicht des Absenders verschwindet?

Das variable "Bild" wird entweder beibehalten oder automatisch freigegeben, je nachdem, welcher Codepfad verwendet wurde.

+0

Ich dachte über die "canPresentShareDialogWithSession" -Ding, versuchte es aus dem Hauptthread aufrufen und bekam genau das gleiche Ergebnis. Wie ich DrAl3X gesagt habe - es ist nicht mein Anruf auf einem Nicht-UI-Thread, es sind interne Facebook SDK-Operationen. – Stavash

1

Ich denke, das Problem ist, was Walt schon gesagt hat. In deinem Code wird etwas außerhalb des Hauptthreads ausgeführt.

Im Crash-Protokoll können Sie sehen, dass jemand das Aussehen (UIAppearance) eines Oberflächenelements aus einem Nicht-UI-Thread festlegt. Das ist das Problem. Diese Operation MUSS NUR im UI (Haupt-) Thread ausgeführt werden.

+0

Ich stimme zu. Die Sache ist - ich mache nicht den Anruf, es sind interne Facebook SDK-Operationen. "presentShareDialogModallyFrom" wird vom Haupt-Thread aufgerufen, wie Sie sehen können. – Stavash

+0

Facebook SDK ist Open Source, Sie können genau sehen, was es tut. Gehen Sie tief hinein und versuchen Sie zu verstehen, wo das Problem stats. – DrAL3X

+0

Wird tun, danke – Stavash

1

Ich glaube, das hat mit der Kombination der UIAppearance-Methoden und dem Starten eines UIRemoteViewControllers aus einem Hintergrundthread zu tun. Wir haben das gleiche Problem in unserer App. Ich werde unsere Presenter-Klasse ändern, um alle Remote-ViewControllers aus dem Hauptthread zu präsentieren und zu sehen, ob das hilft.

In Ihrem Fall, ich denke, etwas im Facebook SDK präsentiert etwas aus einem Hintergrund-Thread.

Ich werde aktualisieren, nachdem ich überprüft habe, dass mein Fix funktioniert.

1

Dies ist ein Fehler in iOS 6 und sozialen Rahmen, überprüfen hier beantworten UINavigationBar appearance and Facebook-Sheet Bug

Wie dieses Problem zu lösen?

einfach anstelle der Verwendung [UINavigationBar appearance] Verwendung [UINavigationBar appearanceWhenContainedIn:...]

Sie können benutzerdefinierte Klasse für die Navigationssteuerung verwenden (zB.CustomNavigationController) und dann in Erscheinung gelten:

[UINavigationBar appearanceWhenContainedIn:[CustomNavigationController class], nil]

Aus meinen Experimenten soll es auf allen appearance Methoden verwendet wird, nicht nur UINavigationBar sondern auch UIBarButtonItem usw. (auf jedem Objekt, das Sie appearance Nachricht an)

senden
Verwandte Themen