Dodawanie Today Extension w 8 krokach

Od wprowadzenia iOS 8 w 2014 programiści mają dostęp do wielu użytecznych funkcjonalności. Jedna z nich – Today Extension pozwala na współdzielenie funkcjonalności aplikacji z iOS i innymi aplikacjami. Today Extension umożliwia wyświetlanie informacji dla użytkownika w centrum powiadomień, wyszukiwarce lub na ekranie blokady. Głównym zadaniem tego rozszerzenia jest zachowanie interakcji między aplikacją i użytkownikiem nawet jeśli aplikacja nie jest otwarta.

Poniżej znajdziesz instrukcję w 8 krokach (i jednym opcjonalnym) jak dodać Today Extension do twojego kodu. 

Zacznijmy więc!

Krok 1: Stwórz nowy projekt aplikacji

Today Extension działa tylko w powiązaniu z aplikacją. Aby utworzyć nowy projekt aplikacji otwórz XCode, wybierz New -> Project -> iOS -> Single View App. Po naciśnięciu Next, nazwij swój projekt i wybierz folder gdzie ma on być zapisany.

Krok 2: Stwórz nowy target dla Today Extension

Następnie, utwórz nowy target dla Today Extension. Możesz to wykonać przez wybranie Editor -> Add Target -> Today Extension w sekcji iOS \ Application Extension:

W kolejnym widoku należy ustawić Nazwę Produktu np.“Extension”. Po wciśnięciu “Finish” w projekcie, zobaczysz dwa targety:

Utworzone zostają następujące pliki:

Krok 3: Dodaj nowy label do MainInterface.storyboard

Teraz otwórz plik MainInterface.storyboard, zmień wysokość kontrolera widoku na 200, usuń istniejący label i dodaj nowy, o tytule “(No data)” w pozycji wyśrodkowanej:

Krok 4: Dodaj ciało klasy i połącz z plikiem storyboard

Przejdź do pliku TodayViewController.swift i dodaj poniższe do ciała klasy:

@IBOutlet weak var ipLabel: UILabel!

i połącz z plikiem storyboard

Krok 5: Dodaj kod do nagłówka pliku

Dodaj poniższe do nagłówka pliku:

struct Response: Codable {
    let ip: String
}

Krok 6: Skopiuj funkcję dodawania danych

Następnie, skopiuj następującą funkcję do ciała TodayViewController.swift:

// MARK: - Loading of data
	
	func loadData() {
		DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
			
            guard let url = URL(string: "https://api.ipify.org/?format=json") else { return }
            URLSession.shared.dataTask(with: url) { data, response, error in
                
                guard let data = data else { return }
                do {
                    let res = try JSONDecoder().decode(Response.self, from: data)
                    DispatchQueue.main.async {
                        self.ipLabel.text = res.ip
                    }
                } catch let error {
                    DispatchQueue.main.async {
                        self.ipLabel.text = error.localizedDescription
                    }
                }
            }.resume()
		}
	}

Powyższa funkcja podmienia label “(No data)” na label twojego API kiedy połączenie z internetem jest aktywne.

Funkcja jest już zaimplementowana, ale jeszcze nie wywoływana.

Step 7: Zastąp metodę viewDidLoad

Podmień metodę viewDidLoad na:

 override func viewDidLoad() {
        super.viewDidLoad()
  
        self.preferredContentSize.height = 200
        loadData()
    }

Wywołaj funkcję loadData w metodzie widgetPerformUpdate:

func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        // Perform any setup necessary in order to update the view.

        // If an error is encountered, use NCUpdateResult.Failed
        // If there's no update required, use NCUpdateResult.NoData
        // If there's an update, use NCUpdateResult.NewData

        loadData()
		
        completionHandler(NCUpdateResult.newData)
    }

Krok 8: Skompiluj i uruchom aplikację

Naciśnięcie z przytrzymaniem ikony aplikacji wyświetli następujące informacje:

Pokazana wartość to twój adres IP.

Możesz też dodać widget do twojej listy widgetów wyświetlanej na ekranie głównym po przesunięciu ekranu w lewo:

Krok 9 (opcjonalny): Dodaj funkcjonalność “Pokaż więcej/mniej”

Wraz z wprowadzeniem iOS10 Apple dostarczył API obsługujący funkcję „Show More/Show Less”. Rozszerz metodę viewDidLoad: 

override func viewDidLoad() {
        super.viewDidLoad()
		
		if #available(iOSApplicationExtension 10.0, *) {
			extensionContext?.widgetLargestAvailableDisplayMode = .expanded
		}
        
		self.preferredContentSize.height = 200
		
		loadData()
    }

Dodaj poniższe do ciała TodayViewController:

func widgetMarginInsets(forProposedMarginInsets defaultMarginInsets: UIEdgeInsets) -> (UIEdgeInsets) {
		return UIEdgeInsets.zero
	}
	
	@available(iOSApplicationExtension 10.0, *)
	func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
		if activeDisplayMode == .expanded {
			preferredContentSize = CGSize(width: maxSize.width, height: 300)
		}
		else if activeDisplayMode == .compact {
			preferredContentSize = maxSize
		}
	}

wyświetli się:

5 (100%) 2 vote[s]