SQLite – Swift3

Ca si solutie de persistenta, pe langa Core Data si NSUserDefault, IOS utilizaza SQLite. Nu insist pe povesti despre SQLite, insa fiind disponibil si pe Android, am considerat oportuna folosirea lui.
Pe Swift, pentru a folosi SQLite e nevoie de un wrapper, o aplicatie de background care sa parseze cererile din aplicatie catre SQLite.
Solutii disponibile in acest sens: FMDB sau SQLite Swift.
Pentru un cod suplu al aplicatiei este de recomandat construirea unui wrapper propriu, de fapt a unui set de functii care vor apela comenzi SQL.
Cum folosim SQLite in Swift?

1. In General Setting specificam faptul ca vom lega libsqlite3.tbd la aplicatie.


2. Adaugam un header file la proiect care va permite bridging catre API-ul C al lui SQLite. Numim de exemplu BridgingHeader.h acest header file si includem in el
#include

3. In Build Settings specificam faptul ca vom folosi acest bridge. Pentru aceasta, adaugam in sectiunea “Objective-C Bridging Header” header file pe care l-am generat la pasul 2.



4. Aplicatia noastra este pregatita in acest moment pentru a folosi SQLite.

In urmatorul post voi detalia calea prin care voi defini modelul pe care il voi folosi pentru a putea “executa” comenzi SQL

Share Button

Localizarea unei aplicatii IOS – cazul 1

Se da o aplicatie IOS. Butoane, label-uri “scrise” in limba de baza – base language. Se cere, de un ipotetic client, ca aplicatia sa fie disponibila in … olandeza de exemplu.
Cum procedam?
1. Introducem un nou fisier in proiect – String File si il denumim Localizable




2. Fisierul nostru va fi disponibil sub numele de Localizable.strings. Adaugam in cadrul proiectului limba olandeza pentru ca Xcode sa stie ca proiectul nostru are localizare si pentru aceasta limba. Pentru aceasta Localization -> click pe + si selectam limba dorita.


3. Deschidem fisierul nostru de stringuri – Localizable.strings – si in File Inspector observam un meniu nou “Localization” cu un buton “Localize” pe care trebuie sa-l activam. Aceasta sectiune isi schimba continutul, avand in mod predefinit Base – bifat. Activam si limba pe care tocmai am adaugat-o in proiect si in acest moment fisierul nostru Localizable.strings devine folder cu doua inputuri – Localizable.strings (Base) si Localizable.strings (Dutch).

Cum folosim localizarea mai sus configurata?

Avem de exemplu un label “Cancel”. Acesta va trebui sa fie etichetat cu “Annuleer” in olandeza.

1. In fisierul Localizable.strings (Base) adaugam:
cancelButton = "Cancel";
iar in Localizable.strings (Dutch)
cancelButton = "Annuleer";
acesta este stringul pe care-l vom folosi functie de ce localizare are telefonul userului

2. definim un string localizat de forma in fisierul nostru in care avem IBOutlet-ul catre buton:
let cancelBtn = NSLocalizedString("cancelButton", comment: "Cancel")

3. Definim un AlertAction – de exemplu – care va fi etichetat functie de localizare
let cancel = UIAlertAction(title: cancelBtn, style: .Cancel, handler: {
(alert: UIAlertAction) -> Void in
Log.d("Cancel");
});

4. Command+R

Share Button

Utilizare XIB – cazul 1 – View Controller

Situatie: Storyboard-ul este prea plin. Multe ViewController-e incarcate, timp mare de asteptare atunci cand intru in storyboard pentru modificari.
Solutie: adaugare XIB file atunci cand adaug un fisier “Cocoa Touch Class”. Se adauga fisierului .swift un fisier .xib cu acelasi nume dar continand “reprezentarea grafica” a clasei derivate.
Exemplu:
– clasa adaugata pentru un UIViewController -> RequestProfileViewController.swift si .xib file adaugat.
– definim continutul RequestProfileViewController.swift
– adaugam continut in RequestProfileViewController.xib si generam IBOutlet/IBAction pentru elementele din .xib in .swift
– in clasa in care vrem sa utilizam o instanta de RequestProfileViewController trebuie sa adaugam ViewController-ul generat in .xib:

let requestProfileVC = RequestProfileViewController(nibName: "RequestProfileViewController", bundle:nil)
self.addChildViewController(requestProfileVC)
requestProfileVC.view.frame = self.view.frame
self.view.addSubview(requestProfileVC.view)
requestProfileVC.didMove(toParentViewController: self)

Utilizarea addChildViewController este explicata de Matt Neuburg excelent aici.

Share Button

UserNotifications – Swift3 – utilizare

1. Import pentru UserNotifications framework si adaugam UNUserNotificationCenterDelegate in AppDelegate.swift
2. Implementare delegatii specifici pentru UNUserNotificationCenterDelegate in ViewController-ul dedicat sau folosind o extensie:
2.1.func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
print("S-a apasat pe notificare, acum ar trebui implementantat ce anume se doreste dupa ce s-a dat click pe notificare")
}

2.2. func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("S-a primit notificare in foreground, definim aici actiunea care se va efectua in foregorund")

}
3. Cerere permisiuni de notificare din partea utilizatorului, de asemenea in AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// register user notification
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.alert, .sound]) { (granted, error) in
}
return true
}

4. Delegarea actiunilor view-ului curent catre delegatii specifici: userNotificationCenter didReceive: si userNotificationCenter willPresent
UNUserNotificationCenter.current().delegate = self
5. Adaugam Observer care va “reactiona” atunci cand selectorul va “cere” sa efectueze o notificare:
NotificationCenter.default.addObserver(self, selector: #selector(numeMetodaNotificare()), name: NSNotification.Name(rawValue: "identificatorNumeNotificare"), object: nil)
6. Implementare metoda care va genera notificare numeMetodaNotificare()
func numeMetodaNotificare(output name:String)
{
let notification = UNMutableNotificationContent()
notification.title = NSString.localizedUserNotificationString(forKey: "Request received", arguments: nil)
notification.body = NSString.localizedUserNotificationString(forKey: "Request is: \(name)!", arguments: nil)
notification.sound = UNNotificationSound.default()
let request = UNNotificationRequest(identifier: "OneSecond", content: notification, trigger: nil)
let center = UNUserNotificationCenter.current()
print("s-a construit notificarea: \(notification.body)")
center.add(request)
}

Share Button

Swift3 – lucrul cu taskuri in background

Avem urmatorul scenariu: o aplicatie player audio care “observa” cand schimbam outputul audio: cand trecem de pe casti pe speaker si viceversa.
Nu intram in detalii aici cum e cu schimbarea rutei audio, poate intr-o discutie viitoare.
Ceea ce vreau sa punctez aici este urmatorul aspect: acest player poate functiona din IOS 8 si in background. Pot asculta muzica si atunci cand blochez ecranul sau comut pe alta aplicatie.
Cum pot permite unei aplicatii scrise in Swift3 sa “lucreze” si in background?

1. pot implementa metoda applicationWillResignActive(_ application: UIApplication)
2. putem inregistra notificarea UIApplicationWillResignActive oriunde in cadrul proiectului nostru Swift.

Cum facem lucrul asta:

1. func applicationWillResignActive(_ application: UIApplication) {
......
DispatchQueue.main.async {
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
})
.....
}

2. NotificationCenter.default.addObserver(
self,
selector: #selector(appDidEnterBackground(notification:)),
name: .UIApplicationWillResignActive ,
object: nil)

unde definim selectorul astfel:

func appDidEnterBackground(notification: NSNotification) {
var bti:UIBackgroundTaskIdentifier=0
bti=self.app.beginBackgroundTask{
UIApplication.shared.endBackgroundTask(bti)
}

Le-am folosit pe ambele in aplicatii, insa o prefer pe a doua din motiv de claritate a codului. Nu e chiar ok sa abuzez de AppDelegate.

Share Button