2016-12-28 4 views
16

Ich möchte einige Aktionen in der App von heute Erweiterung (Widget) zu verwalten.Aktion in der Host-App von Heute-Erweiterung (Widget) ohne Öffnen der App IOS

Vollständige beschreibung: in meiner containing app, einige aktionen (wie play/pause audio) durchführen. Und will diese Aktion auch von heute aus (Widget) verwalten. Eine Aktion wird weiterhin im Hintergrund ausgeführt.

In der heutigen Erweiterung wird die gleiche Aktion ausgeführt. Wenn also in der App, die die App enthält, bereits eine Aktion gestartet und in den Hintergrundzustand versetzt wird, kann ein Benutzer die Aktion von einem Widget anhalten. und der Benutzer kann die Aktion auch jederzeit über das Widget (heutige Erweiterung) starten/pausieren.

Um dieses Ziel zu erreichen, habe ich UserDefault mit App Group-Fähigkeit verwendet und einen booleschen Wert gespeichert. Wenn das Widget vorhanden ist, prüft es den booleschen Wert und setzt den Knopfstatus play/pause. Es ist richtig eingestellt, aber wenn ich die Taste drücken, funktioniert die Aktion nicht in der Host-App.

Code:

in Haupt enthält App-Code

override func viewDidLoad() { 
    super.viewDidLoad() 
    let objUserDefault = UserDefaults(suiteName:"group.test.TodayExtensionSharingDefaults") 

    let objTemp = objUserDefault?.object(forKey: "value") 

    self.btnValue.isSelected = objTemp 

    NotificationCenter.default.addObserver(self, selector: #selector(self.userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil) 
} 




func userDefaultsDidChange(_ notification: Notification) { 

     let objUserDefault = UserDefaults(suiteName: "group.test.TodayExtensionSharingDefaults") 
     objUserDefault?.synchronize() 
     let objTemp = objUserDefault?.object(forKey: "value") 
     self.btnValue.isSelected = objTemp 
    } 

In Erweiterung Klasse:

@IBAction func onPlayPause(_ sender: UIButton) { 
     DispatchQueue.main.async { 
     let sharedDefaults = UserDefaults(suiteName: "group.test.TodayExtensionSharingDefaults") 

     if let isPlaying = sharedDefaults?.bool(forKey: "isPlaing") { 

     sharedDefaults?.set(!isPlaying, forKey: "isPlaying") 

     }else{ 

     sharedDefaults?.set(false, forKey: "isPlaying") 
     } 

     sharedDefaults?.synchronize() 
} 

Meldung wurde nicht ausgelöst, wenn ein Standardbenutzer-Updates. Der Wert wird aktualisiert, wenn die App neu gestartet wird.

so, wie dieses Problem zu lösen?

und das gleiche möchte im Gegensatz dazu bedeutet, App zu einem Widget zu halten. (einfach zu Single-Action-Objekt, aber wie?)

Und ist eine andere Möglichkeit, eine schnelle Aktion in der App von der Erweiterung ohne App zu öffnen durchzuführen?

+0

Wo feuern Sie Ihre Mitteilung? – karthikeyan

Antwort

9

Verwenden Sie MMWormhole (oder seine neue und inoffizielle Swift-Version, nur Wormhole). Es ist sehr einfach.

im View-Controller App:

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    let wormhole = MMWormhole(applicationGroupIdentifier: "group.test.TodayExtensionSharingDefaults", 
           optionalDirectory: "TodayExtensionSharingDefaults") 

    wormhole.listenForMessage(withIdentifier: "togglePlayPause") { [weak self] _ in 
     guard let controller = self else { return } 
     controller.btnValue.isSelected = controller.btnValue.isSelected 
    } 
} 

In der Verlängerung:

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view from its nib. 

    self.wormhole = MMWormhole(applicationGroupIdentifier: "group.test.TodayExtensionSharingDefaults", optionalDirectory: "TodayExtensionSharingDefaults") 
} 

@IBAction func onPlayPause(_ sender: UIButton) { 
    guard let wormhole = self.wormhole else { extensionContext?.openURL(NSURL(string: "foo://startPlaying")!, completionHandler: nil) } // Throw error here instead of return, since somehow this function was called before viewDidLoad (or something else went horribly wrong) 

    wormhole.passMessageObject(nil, identifier: "togglePlayPause") 
} 

foo:// erklären (oder was auch immer Sie verwenden) in Xcode Dokumenttypen Abschnitt unter URLs, dann implementieren application(_:open:options:) in Ihre AppDelegate, damit die App Musik spielt, wenn die URL foo://startPlaying übergeben wird.

how to add URL to Xcode

+0

hi, diese Bibliothek funktioniert nicht, wenn eine App im inaktiven Status und im Hintergrund ist –

+0

Nun, wenn die App nicht läuft, wie würde die Musik beginnen? – Coder256

+0

Das ist das Problem. Ich möchte playAndRecord starten und stoppen –

4
  1. Erstellen von benutzerdefinierten URL Sceheme

  2. überprüfen Gruppen Daten.(Setzen Sie richtig oder nicht)

  3. Jedes Mal, wenn Sie auf die Schaltfläche klicken, wird der Host-App von AppDelegate,

    func application(_ application: UIApplication, open urls: URL, sourceApplication: String?, annotation: Any) -> Bool { 
    
         let obj = urls.absoluteString.components(separatedBy: "://")[1] 
         NotificationCenter.default.post(name: widgetNotificationName, object: obj) 
         print("App delegate") 
         return true 
        } 
    
  4. Feuer Ihre Benachrichtigung von dort UIApplication Delegat dann beobachten gecallt überall in Ihrem Hostapp.

    Widget Button-Aktion Code

    @IBAction func doActionMethod(_ sender: AnyObject) { 
    
        let button = (sender as! UIButton) 
        var dailyThanthi = "" 
        switch button.tag { 
        case 0: 
         dailyThanthi = "DailyThanthi://h" 
        case 1: 
         dailyThanthi = "DailyThanthi://c" 
        case 2: 
         dailyThanthi = "DailyThanthi://j" 
         //  case 3: 
         //   dailyThanthi = "DailyThanthi://s" 
         //  case 4: 
         //   dailyThanthi = "DailyThanthi://s" 
        default: 
         break 
        } 
    
        let pjURL = NSURL(string: dailyThanthi)! 
        self.extensionContext!.open(pjURL as URL, completionHandler: nil) 
    
    } 
    
  5. Check-out-Typ benutzerdefinierte url: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html

  6. Hinweis:

    Es gibt keine direkte Verbindung zwischen einer App-Erweiterung und ihre enthält App; In der Regel wird die enthaltene App nicht einmal ausgeführt, während eine enthaltene Erweiterung ausgeführt wird. Eine App-Erweiterung, die die App enthält, und die Host-App kommunizieren überhaupt nicht.

    In einer typischen Anfrage/Antwort-Transaktion öffnet das System eine App-Erweiterung im Auftrag einer Host-App, die Daten in einer vom Host bereitgestellten Erweiterung übermittelt. Die Erweiterung zeigt eine Benutzerschnittstelle an, führt einige Arbeit aus, und, falls für den Zweck der Erweiterung geeignet, gibt Daten an den Host zurück.

    Die gepunktete Linie in Abbildung 2-2 zeigt die begrenzte Interaktion zwischen einer App-Erweiterung und ihrer App. Ein Today Widget (und kein anderer App-Erweiterungstyp) kann das System bitten, seine App zu öffnen, indem die openURL:completionHandler: Methode der die NSExtensionContext Klasse aufgerufen wird. Wie in den Read/Write-Pfeilen in , Abbildung 2-3, angegeben, können alle App-Erweiterungen und ihre zugehörige App auf freigegebene Daten in einem privat definierten gemeinsamen Container zugreifen. Das vollständige Vokabular der Kommunikation zwischen einer Nebenstelle, ihrer Host-App und der zugehörigen App wird in einfacher Form in Abbildung 2-3 angezeigt.

    https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html

+0

nicht Punkt 3 & 4. Kannst du bitte mehr und richtig erklären. –

+0

Dies wird Ihre App öffnen, 6 Punkte überprüfen .. aber Sie sagen, ohne App zu öffnen, ich denke, das ist nicht möglich, überprüfen Sie die Dokumentation. – karthikeyan

Verwandte Themen