- (BOOL)openURL:(NSURL*)url

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

  • - (BOOL)openURL:(NSURL*)url

    Ich beschreibe kurz mein Problem:
    1. Ich habe UITextView, der URLs erkennt.

    2. Ich möchte, dass die Links aus dem UITextView nicht in Safari, sonder in meinem
    UIWebView geöffnet werden. Darum habe ich folgende Klasse implementiert:

    Quellcode

    1. @interface UIApplication (Private)
    2. - (BOOL)openURL:(NSURL*)url;
    3. @end
    4. @implementation UIApplication (Private)
    5. - (BOOL)openURL:(NSURL*)url {
    6. if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
    7. WebViewController *mWebViewController = [[WebViewController alloc] initWithUrl:mUrl];
    8. UINavigationController *controller = ... // get navigationController
    9. [controller pushViewController:mWebViewController animated:YES];
    10. [controller release];
    11. return NO;
    12. }
    13. return YES;
    14. }
    15. @end
    Alles anzeigen


    3. Wenn im UITextView ein Link angecklickt wird, wird die Methode
    - (BOOL)openURL:(NSURL*)url aufgerufen, und mein WebView lädt die Seite.

    4. In der App habe ich noch eine Anruffunktion, und genau die Funktioniert nicht.
    Wenn ich meine Methode - (BOOL)openURL:(NSURL*)url auskommentiere, kann
    ich anrufen, aber die Links im UITextView öffnen sich dann im Safari-Browser.

    Jetzt die Frage: wie macht man es so, dass Anrufen und Links im UITextView in
    eigenem UIWebView sich öffnen.
  • RE: - (BOOL)openURL:(NSURL*)url

    Du hast eine Kategorie implementiert, nicht eine Klasse. Aber das nur am Rande. Diese Kategorie überschreibt auch noch die Instanzmethode der Klasse: Nicht gut.

    Schau dir mal an, was dein -openURL: bekommt, wenn du eine Telefonnummer anklickst. Ich würde mal fast wetten, dass da tel:… reinkommt.
    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"?
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von Amin Negm-Awad
    Du hast eine Kategorie implementiert, nicht eine Klasse. Aber das nur am Rande. Diese Kategorie überschreibt auch noch die Instanzmethode der Klasse: Nicht gut.

    Schau dir mal an, was dein -openURL: bekommt, wenn du eine Telefonnummer anklickst. Ich würde mal fast wetten, dass da tel:… reinkommt.


    Ok, ich merke mir, dass es nicht gut ist. Was wäre besser?
    Ja, es kommt tel: rein.
  • RE: - (BOOL)openURL:(NSURL*)url

    Jetzt die Frage: wie macht man es so, dass Anrufen und Links im UITextView in
    eigenem UIWebView sich öffnen.

    Da Du den kompletten Original-Funktionsumfang mit Deine Kategorie überschrieben hast, macht openURL logischerweise nichts als das, was Du implementiert hast - öffnet also irgendeine URL immer in deinem UIWebView.

    Versuche es mal mit einer vorgeschalteten Methode: Rufe eine andere (eigene) Methode als vorgeschaltetes Ziel auf und wenn das nichts mit dem, was kommt, anfangen kann, rufe die Originalmethode openURL mit dem Wert auf. Sonst mache in Deiner Methode weiter.

    Aber ein Anruf in Deinem UIWebView - das geht schon mal deshalb nicht, weil bei tel: (oder mailto: ) Deine App verlassen und die Telefon-App (oder mail.app) gestartet wird ...
  • Ich schreibe es gerne noch einmal, weil es immer wieder mal falsch gemacht wird (und es eigentlich auch gefühlte 237648723468327 Mal im Buch steht). Wenn man Standardverhalten ändern will, sucht man am besten die Möglichkeiten wie folgt:

    1. Parametriesierung: Lässt sich die Instanz so konfigurieren, dass ich mein Ziel erreiche. (Siehe auch Nachbarthread!)
    2. Delegating: Bietet mir die Instanz die Möglichkeit, über ein Delegate das Verhalten zu steuern.
    3. Subclassing (Diese Kategorie ist der fehlerhafte Versuch, Subclassing zu simulieren.)

    Subclassing ist also die letzte Möglichkeit, nicht die erste. Das ist konzeptionell deutlich anders als bei anderen Programmiersprachen/Frameworks, die Subclassing als das Standardverhalten erwarten. (Natürlich auch nach Parametrisierung.)
    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"?
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von iPhone3GS
    Original von Amin Negm-Awad
    Delegating ist das dafür vorgesehen Muster:
    developer.apple.com/iPhone/lib…pplication:handleOpenURL:

    Irgentwie schnalle ich das nicht. Vie sage ich dem standard UITextView, dass er bemi Klick auf
    eine URL die Methode - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    aufrufen soll. :( Ich grubele weiter.

    Ich habe es zwar noch nie ausprobiert, ahne aber, dass du nicht recht weißt, was das Konzept von Delegating ist. Hast du dazu etwas gelesen?
    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"?
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von Amin Negm-Awad
    Ich habe es zwar noch nie ausprobiert, ahne aber, dass du nicht recht weißt, was das Konzept von Delegating ist. Hast du dazu etwas gelesen?

    Bis jetzt habe ich delegate-Methoden für UIWebView, UIControl und weitere Überschrieben.
    Meine Idee wäre jetzt delegate-Methoden von UITextView zu überschreiben, aber openURL:
    gibt's da nicht.
  • RE: - (BOOL)openURL:(NSURL*)url

    Du muss in Deinem Klassen-Interface in den <> UIApplicationDelegate einfügen und dann

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

    entsprechend Amins Hinweis auf die Doku implementieren.

    Überschreiben musst Du (bei den Methoden von Protokollen) nichts.
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von iPhone3GS
    Wie sage ich dem standard UITextView, dass er bemi Klick auf
    eine URL die Methode - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url aufrufen soll.

    Gar nicht. Entweder er macht es automatisch (wenn du die Methode in deinem App Delegate implementiert hast) oder er macht es nicht. Ohne es ausprobiert zu haben, glaube ich, dass Amin hier falsch liegt. Mich würde es sehr wundern, wenn die Methode aufgerufen wird, da sie eigentlich einen anderen Zweck hat: sie ist Teil des Startvorgangs einer App, wenn deine App von einer anderen App über eine URL aufgerufen wird.

    Aus meiner Sicht bleibt für dich nur, UIApplication abzuleiten und openURL: zu überschreiben. Dann kannst du für alle URL-Schemen außer http super aufrufen. Den Namen deiner Subklasse musst du in main.m der Funktion UIApplicationMain mitgeben, damit das System sie auch instanziiert. Steht in der Doku.

    Oder du hackst dir eine funktionierende Kategorie mit Method Swizzling zusammen.
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von fwtag
    Du muss in Deinem Klassen-Interface in den <> UIApplicationDelegate einfügen und dann

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

    entsprechend Amins Hinweis auf die Doku implementieren.

    Überschreiben musst Du (bei den Methoden von Protokollen) nichts.


    Meine Klasse ist ein UIViewController. Wenn ich von UIApplicatonDelagate ableite und die Methode
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url definiere, wird
    sie beim Klick auf einen Link im UITextView nicht aufgerufen.
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von elo
    Original von iPhone3GS
    Wie sage ich dem standard UITextView, dass er bemi Klick auf
    eine URL die Methode - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url aufrufen soll.

    Gar nicht. Entweder er macht es automatisch (wenn du die Methode in deinem App Delegate implementiert hast) oder er macht es nicht. Ohne es ausprobiert zu haben, glaube ich, dass Amin hier falsch liegt. Mich würde es sehr wundern, wenn die Methode aufgerufen wird, da sie eigentlich einen anderen Zweck hat: sie ist Teil des Startvorgangs einer App, wenn deine App von einer anderen App über eine URL aufgerufen wird.

    handleOpenURL wird in der AppDelegate nicht aufgerufen.

    Aus meiner Sicht bleibt für dich nur, UIApplication abzuleiten und openURL: zu überschreiben. Dann kannst du für alle URL-Schemen außer http super aufrufen. Den Namen deiner Subklasse musst du in main.m der Funktion UIApplicationMain mitgeben, damit das System sie auch instanziiert. Steht in der Doku.

    Oder du hackst dir eine funktionierende Kategorie mit Method Swizzling zusammen.


    Dafür muss ich wissen, wie man einen Anruf startet, oder?
  • RE: - (BOOL)openURL:(NSURL*)url

    Mit seiner anderen Bemerkung (dass du Delegating noch nicht verstanden hast) hatte Amin aber definitiv Recht. Du leitest nicht von UIApplicationDelegate ab, du implementierst ein Protokoll! Und einen App Delegate hast du schon, da musst du keinen neuen schreiben!
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von elo

    Aus meiner Sicht bleibt für dich nur, UIApplication abzuleiten und openURL: zu überschreiben.
    Dann kannst du für alle URL-Schemen außer http super aufrufen. Den Namen deiner
    Subklasse musst du in main.m der Funktion UIApplicationMain mitgeben, damit das System
    sie auch instanziiert. Steht in der Doku.


    Es geht! Danke!
  • RE: - (BOOL)openURL:(NSURL*)url

    Spannend bleibt aber trotzdem die Frage, ob das Protokoll so einzusetzen ist, wie von Amin gedacht oder ob die Delegate-Methode tatsächlich nur beim Start aufgerufen wird, wie von elo beschrieben. Ich lese die Doku (ja, auch ich lese die Doku) so, dass ich eher zu Amins Interpretation neige.

    Hat das schon mal jemand probiert?
  • RE: - (BOOL)openURL:(NSURL*)url

    Original von fwtag
    Spannend bleibt aber trotzdem die Frage, ob das Protokoll so einzusetzen ist, wie von Amin gedacht oder ob die Delegate-Methode tatsächlich nur beim Start aufgerufen wird, wie von elo beschrieben. Ich lese die Doku (ja, auch ich lese die Doku) so, dass ich eher zu Amins Interpretation neige.

    Okay, ich hab's ausprobiert, und es ist so, wie ich es vermutet habe. application:handleOpenURL: wird nicht aufgerufen, wenn man aus der eigenen App openURL: aufruft. Delegating ist oft die Antwort, aber hier nicht.