Variable von AppDelegate in allen Klassen verfügbar machen?

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

  • DKCode schrieb:

    Dann bricht die App ab und ich bekomme den Error "Thread 1: EXC_BREAKPOINT (code=1, subcode=0x10023e4b0)"


    Schau' Dir Doch mal die Typen genau an, das kann doch gar nicht gehen:

    1. Eine Notification ist vom Typ NSNotification und kein String!

    2. Das DeviceToken an sich ist vom Typ NSData und ebenso kein String!

    Das sind tatsächlich Dinge, die man auf den ersten Blick in der Dokumentation findet.

    schönen Gruß

    gandhi

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

  • DKCode schrieb:

    getUserDeviceToken = userDeviceToken.object as NSString

    Mit "as String" sagst du nur "ich weiss, was ich tue, das hier ist ein String" - nur merkt das System den Betrug, sobald der Code aufgerufen wird -> Absturz.

    Quellcode

    1. ​getUserDeviceToken = userDeviceToken.object.description

    hingegen sagt "mach mir aus dem Objekt einen String" (meist braucht man dass für den Debugger, und man sollte diese Methode beispielsweise nicht bei Zahlen einsetzen: Die Ausgabe ist nicht lokalisiert, und für die Anzeige in der GUI sollte man sich auch darum kümmern).
    Bei NSData liefert description übrigens Statistik zum Datenblock - da muss ja kein String drin stecken. Dafür gibt es ein "initWithData:encoding:".
  • kmr schrieb:

    Thallius schrieb:


    Sich NSNotifications durchzulesen und zu verstehen dauert keine 30minuten.


    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    :D


    Ja da ist was dran ^^

    macmoonshine schrieb:

    DKCode schrieb:

    hm ich dachte das wäre der Weg den du Anfangs meintest.

    Halbrichtig: Der erste Vorschlag bestand darin, das Token weiterzugeben. Ich habe aber nicht geschrieben, dass du den Viewcontroller selber laden sollst. Auch diesen Code müsstest du in application:didRegisterForRemoteNotificationsWithDeviceToken: packen, und da hat die App wahrscheinlich schon den Rootview geladen. Wenn der Root-View das Token braucht, könnte das so aussehen:

    Quellcode

    1. (void)application:(UIApplication *)inApplication didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)inToken {
    2. MyViewController *theController = (MyViewController *)self.window.rootViewController;
    3. theController.deviceToken = inToken;
    4. }

    Sobald du jedoch eine etwas komplexere Navigationshierarchie hast, wird das aber ziemlich eklig. Deswegen habe ich dir den Weg über Benachrichtigungen empfohlen. ;)


    Alles klar dann habe ich das etwas falsch erstanden :) Danke für die Erklärung

    gandhi schrieb:

    DKCode schrieb:

    Dann bricht die App ab und ich bekomme den Error "Thread 1: EXC_BREAKPOINT (code=1, subcode=0x10023e4b0)"


    Schau' Dir Doch mal die Typen genau an, das kann doch gar nicht gehen:

    1. Eine Notification ist vom Typ NSNotification und kein String!

    2. Das DeviceToken an sich ist vom Typ NSData und ebenso kein String!

    Das sind tatsächlich Dinge, die man auf den ersten Blick in der Dokumentation findet.

    schönen Gruß

    gandhi


    Ja das ist mir schon bewusst, das diese Typen keine Strings sind. Das sind die Dinge die in der Doku sogar recht am Anfang kommen. Aber die Frage war ja eher wie ich diese Typen zu einem String mache.

    Gruß

    t-no schrieb:

    DKCode schrieb:

    getUserDeviceToken = userDeviceToken.object as NSString

    Mit "as String" sagst du nur "ich weiss, was ich tue, das hier ist ein String" - nur merkt das System den Betrug, sobald der Code aufgerufen wird -> Absturz.

    Quellcode

    1. ​getUserDeviceToken = userDeviceToken.object.description

    hingegen sagt "mach mir aus dem Objekt einen String" (meist braucht man dass für den Debugger, und man sollte diese Methode beispielsweise nicht bei Zahlen einsetzen: Die Ausgabe ist nicht lokalisiert, und für die Anzeige in der GUI sollte man sich auch darum kümmern).
    Bei NSData liefert description übrigens Statistik zum Datenblock - da muss ja kein String drin stecken. Dafür gibt es ein "initWithData:encoding:".


    ah ok das wusste ich gar nicht. Ich dachte ich würde nicht nur sagen das ich weiß was ich tu, sondern das es dann auch direkt ein String wird! Vielen Danke für deine Hilfe ! :D
  • macmoonshine schrieb:

    DKCode schrieb:

    Aber die Frage war ja eher wie ich diese Typen zu einem String mache.

    Du könntest die Bytes, jeweils als zweistellige Hexadezimalzahlen, in eine Zeichenkette schreiben.


    das klingt interessant, aber ich hab überhaupt keine Ahnung was du damit meinst ^^ soweit bin ich noch nicht :)

    Irgendwie verstehe ich den Ablauf der Xcode Scripte nicht so ganz :/ Mal die Frage in die Runde, wird der Code nicht von oben nach unten durchgearbeitet wie in Webscriptsprachen?

    Quellcode

    1. import UIKit
    2. class ViewController: UIViewController {
    3. @IBOutlet weak var webView: UIWebView!
    4. var getUserDeviceToken: String?
    5. let url = "http://meineURL.de/"
    6. required init(coder aDecoder: NSCoder) {
    7. super.init(coder: aDecoder)
    8. NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)
    9. }
    10. func methodOFReceivedNotication(notification: NSNotification){
    11. let userDeviceToken = notification
    12. let userDeviceTokenDesc: AnyObject? = userDeviceToken.object?.description
    13. getUserDeviceToken = (userDeviceTokenDesc as String)
    14. }
    15. override func viewDidLoad() {
    16. super.viewDidLoad()
    17. let requestURL = NSURL(string:url)
    18. let request = NSURLRequest(URL: requestURL!)
    19. webView.loadRequest(request)
    20. println(getUserDeviceToken)
    21. }
    22. override func didReceiveMemoryWarning() {
    23. super.didReceiveMemoryWarning()
    24. }
    25. }
    Alles anzeigen


    Ganz oben erstelle ich ja eine Variable "getUserDeviceToken".

    Dann kommt mein Init Aufruf, der mir die Benachrichtigung holt (den DeviceToken).

    Danach kommt im Code ja die Methode, die in der Init aufgerufen wird. Diese soll nun, die oben in der Klasse erstelle Variable, füllen (getUserDeviceToken).

    Anschließen folgt im Code die viewDidLoad Methode, die mein WebView anspricht und dann meine Variable ausgeben soll (getUserDeviceToken), aber es kommt nur nil dabei raus?

    Das heißt dann, das der per Benachrichtigung übergebene DeviceToken viel zu spät ankommt? Das die viewDidLoad Methode schon vorher aufgerufen wird?

    Alle Versuche, die Benachrichtigungs-Methode in die viewDidLoad Methode zu integrieren schlägt fehl. Den Code für meinen WebView kann ich aber auch nicht aus der viewDidLoad Methode rausnehmen.

    Durchläuft XCode den Code asynchron?
  • DKCode schrieb:

    Irgendwie verstehe ich den Ablauf der Xcode Scripte nicht so ganz Mal die Frage in die Runde, wird der Code nicht von oben nach unten durchgearbeitet wie in Webscriptsprachen?

    Nein, denn das sind keine Scripte.

    DKCode schrieb:

    Durchläuft XCode den Code asynchron?

    Xcode durchläuft deinen Code gar nicht. Xcode übersetzt deinen Code in eigenständig laufende Programme. Die laufen ganz alleine.
  • Wieso sind das keine Scripte? Codeblöcke ergeben ein Script.

    Ja da habe ich mich etwas falsch ausgedrückt. Da ich mittlerweile rausgefunden habe, das die Init Methode zwar vor der viewDidLoad aufgerufen wird, aber letztendlich nicht komplett durchläuft, bis die viewDidLoad Methode abgefeuert wird, frage ich mich, ob man hier eine Art "wait" einbauen kann? Anders ist es ja sonst nicht möglich :/
  • DKCode schrieb:

    Wieso sind das keine Scripte? Codeblöcke ergeben ein Script.

    Scripte werden von Programmen eingelesen und ausgeführt. Du brauchst die Scripte also, um sie ausführen zu können. Mit Xcode erzeugst du Programme aus Quelltext-Dateien. Hat Xcode das Programm durch Compilieren erzeugt, kann das Programm eigenständig ausgeführt werden. Die Quelltext-Dateien werden zur Laufzeit nicht benutzt.

    DKCode schrieb:

    Da ich mittlerweile rausgefunden habe, das die Init Methode zwar vor der viewDidLoad aufgerufen wird, aber letztendlich nicht komplett durchläuft, bis die viewDidLoad Methode abgefeuert wird,

    Du irrst dich. Jede Methode, die aufgerufen wird, läuft komplett durch, außer du programmierst eine Methode so, dass sie auf irgendetwas wartet. Das ist bei deiner init-Methode aber nicht der Fall.
  • Michael schrieb:

    Du irrst dich. Jede Methode, die aufgerufen wird, läuft komplett durch, außer du programmierst eine Methode so, dass sie auf irgendetwas wartet. Das ist bei deiner init-Methode aber nicht der Fall.


    Richtig das sollte eigentlich nicht so sein. Aber dennoch ruft meine Init Methode die "methodOFReceivedNotication" Methode auf und gleichzeitig wird die viewDidLoad Methode aufgerufen. Dadurch ist die Variable noch nicht gefüllt.
    Woran liegt das? Warum wartet die viewDidLoad Methode nicht ab?
  • Michael schrieb:

    DKCode schrieb:

    Aber dennoch ruft meine Init Methode die "methodOFReceivedNotication" Methode auf

    Nein, das tut sie nicht. Sie registriert die Instanz beim NSNotificationCenter für eine Benachrichtigung mit dem Namen „NotificationIdentifier“, was auch immer das für eine Benachrichtigung sein soll.


    ja das mein ich doch ^^ letztendlich ruft diese Instanzierung aber dann die Methode "methodOFReceivedNotication" auf (die Benachrichtigung ist der DeviceToken, der aus der AppDelegate gesendet wurde).

    Ich habe in alle Methoden println´s gesetzt um zu schauen, wie der Ablauf ist. Und nach dem Aufruf der Init-Methode wird direkt die viewDidLoad Methode aufgerufen erst danach die "methodOFReceivedNotication" Methode. Genau hier liegt das Problem was ich einfach nicht verstehe?

    Ausgabe in der Console sieht dann so aus:
    1
    3
    2

    Wie bringe ich die viewDidLoad Methode dazu, zu warten, bis die Benachrichtigung angekommen ist, bzw. die "methodOFReceivedNotication" vollständig durchgelaufen ist?
  • DKCode schrieb:

    Wie bringe ich die viewDidLoad Methode dazu, zu warten, bis die Benachrichtigung angekommen ist, bzw. die "methodOFReceivedNotication" vollständig durchgelaufen ist?

    Das ist ein asynchroner Vorgang: Das Betriebssystem sendet das Device-Token irgendwann an die App, während diese läuft. Da solltest du keine synchronen Techniken verwenden. In der Programmierung wie im richtigen Leben gilt folgende Regel (bitte mitschreiben): Warten ist immer Scheiße.

    Möglicher Lösungsweg:
    1. App-Delegate versendet Device-Token als Benachrichtigung (siehe oben).
    2. Viewcontroller registriert sich in viewDidLoad als Empfänger dieser Nachrichtenempfänger.
    3. Die Empfängermethode verarbeitet das Device-Token wie gewünscht.
    Anwendung und Beispiele für Benachrichtigungen: siehe oben!
    „Meine Komplikation hatte eine Komplikation.“
  • kmr schrieb:

    macmoonshine schrieb:

    Warten ist immer Scheiße.
    Ach. Vorfreude ist doch angeblich die schönste Freude.

    Ganz davon abgesehen, müsste ich nicht regelmäßig auf den Bus warten oder darauf, dass die Bahn endlich an meiner Zielhaltestelle ankommt – ich würde ja überhaupt gar keine Bücher mehr lesen!
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Marco Feltmann schrieb:

    kmr schrieb:

    macmoonshine schrieb:

    Warten ist immer Scheiße.
    Ach. Vorfreude ist doch angeblich die schönste Freude.

    Ganz davon abgesehen, müsste ich nicht regelmäßig auf den Bus warten oder darauf, dass die Bahn endlich an meiner Zielhaltestelle ankommt – ich würde ja überhaupt gar keine Bücher mehr lesen!


    oder hier im Forum posten :)

    Gruß

    Clau
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

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

    Wie bringe ich die viewDidLoad Methode dazu, zu warten, bis die Benachrichtigung angekommen ist, bzw. die "methodOFReceivedNotication" vollständig durchgelaufen ist?

    Gar nicht. Die -viewDidLoad Methode wartet darauf, dass das View geladen wurde. (Ich weiß, der Methodenname ist in dem Zusammenhang arg verwirrend… +scnr+)

    PushNotifications sind asynchron. Auf asynchrone Antworten zu warten ist so ein bisschen wie 'Warten auf Godot'.
    Die Antwort kann innerhalb einer viertel Sekunde da sein. Oder nach drei Wochen. Oder gar nicht.

    Du müsstest also Deine Denkweise anpassen:
    statt unbedingt zur Anzeigezeit des Views den deviceToken einblenden zu wollen lieber erst bei Bekanntgabe des deviceToken diesen einblenden.

    Ganz stumpfes Beispiel: Das Textview, das den Token zeigen soll, mit einem 'Warte auf Token vom Server…' vorbelegen.
    Vielleicht nach einem Timeout noch in ein 'Seit 60 Sekunden kein Token erhalten. Device offline?' ändern.

    Und in der asynchron aufgerufenen Methode zur Notification einfach das Device Token im Textfeld setzen.
    Lieber drei Monate darauf warten, dass das Token im Textfeld auftaucht (und den Programmierer auslachen, dass er nur von Sekunden ausgegangen ist – gibt nach drei Monaten ne hübsche Zahl) als drei Monate darauf warten, dass das View endlich angezeigt wird.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P