Warning – Expression of type ‘UIViewController?’ is unused

Atunci cand folosesc intr-o alerta pentru ramura de close o expresie de genul: navigationController?.popViewController(animated: true)

XCode 8 imi genereaza un warning de genul: Expression of type ‘UIViewController?’ is unused.

Adica eu iti returnez un UIViewController? si tu nu vrei sa-l folosesti de nici un fel?

Pana la Swift 3 toate functiile aveau implicit “discardable result”. Adica daca nu foloseai explicit outputul functiei, nici o problema.

La Swift 3 dispare aceasta “facilitate” tocmai pentru a preintampina situatiile in care returnul functiei este “uitat” de coderi.

Pentru a remedia acest warning este suficient sa rescriu utilizarea astfel:

let _ = navigationController?.popViewController(animated: true)

Share Button

SWIFT – Selector

Selector-ul este in Objective-C și SWIFT un fel aparte de referință a unei metode.
Pentru a înțelege mai bine ce-i cu acest selector, urmărim codul:

class ViewController : UIViewController {
@IBOutlet var b : UIButton!
func viewDidLoad() {
super.viewDidLoad()
self.b.addTarget( // prepare to crash!
self, action: "buttonPressed", for: .touchUpInside)
}
func buttonPressed(_ sender: Any) {
// ...
}
}

self.b este un buton în interfață care atunci când va fi apăsat se va apela metoda addTarget(action:for:)
Aceasta la rândul ei va încerca să apeleze buttonPressed. Însă buttonPressed nu este metodă în SWIFT, numele corect fiind buttonPressed:, ceea ce va duce la crash atunci când se va apăsa pe buton.
Pentru a remedia acest aspect se folosește #selector:


class ViewController : UIViewController {
@IBOutlet var button : UIButton!
func viewDidLoad() {
super.viewDidLoad()
self.b.addTarget(
self, action: #selector(buttonPressed), for: .touchUpInside)
}
func buttonPressed(_ sender: Any) {
// ...
}
}

Share Button

Map, Filter și Reduce în SWIFT – Update 24.05.2017

UPDATE 24.05.2017
Revin cu un exemplu practic pe care l-am incercat azi cu MAP. In Swift developerii folosesc din ce in ce mai mult MAP in locul clasicului FOR.
Convertesc secventa:
for user in (userList as! [String]) {
let fullMessages = SendReceiveMessages.sharedInstance.loadArchivedMessagesFrom(jid: user )
let last = fullMessages.lastObject as! JSQMessage
usersLastMessageStructArray.append(lastMessagesStruct(username: user, message: last.text, date: last.date))
}

in ceva mult mai swifty

usersLastMessageStructArray = (userList as! [String]).map({user in
let fullMessages = SendReceiveMessages.sharedInstance.loadArchivedMessagesFrom(jid: user )
let last = fullMessages.lastObject as! JSQMessage
return lastMessagesStruct(username: user, message: last.text, date: last.date)
})

Sortez de asemenea intr-un mod swifty acest array de struct-uri:

usersLastMessageStructArray = usersLastMessageStructArray.sorted{$0.date > $1.date}

Metode mai puțin cunoscute pentru array-uri însă extrem de puternice. Practic, cu ajutorul lor, nu mai e nevoie de pus o bucla for in sau foreach pe array.

filter(_:) – preia în noul array elementele din vechiul array în aceeași ordine cu precizarea că pot fi omise elementele care sunt specificate în filtru:
let elevi = [“Marius”, “Serban”, “Maria”]
let eleviM = elevi.filter {$0.hasPrefix(“M”)} // [Marius, Maria]

Un exemplu foarte concludent – formarea unui array de elemente pare din array-ul inițial”
let digits = [1,4,10,15]
let even = digits.filter { $0 % 2 == 0 } // [4, 10]

map(_:) – instanțiază un nou array în care fiecare element este rezultatul trecerii fiecărui element din vechiul vector prin funcția furnizată ca și argument. Interesant e faptul că această funcție poate modifica tipul parametrului

let vector = [1,2,3]
let vectorNou = vector.map {$0 * 2} // [2,4,6]

reduce(_:) – combină toate elementele din array pentru a obține o singură valoare
let litere = [“abc”,”def”,”ghi”]
let text = litere.reduce(“”, combine: +) // “abcdefghi”

sau

let array = [1, 4, 9, 13, 118]
let sum = arr.reduce(0) {$0 + $1} // 145

Share Button

Xcode 8 – problema loguri

La rularea unei aplicații în XCode8 apar în consolă tot felul de loguri ciudate:

2016-09-28 10:18:45.945891 test[1106:54365] bundleid: com.test.test, enable_level: 0, persist_level: 0, propagate_with_activity: 0
2016-09-28 10:18:45.946484 test[1106:54365] subsystem: com.apple.siri, category: Intents, enable_level: 1, persist_level: 1, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 0, privacy_setting: 0, enable_private_data: 0
2016-09-28 10:18:45.956716 test[1106:54704] subsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0

Aceste loguri interne sunt o povară atunci când trebuie să urmăresc logurile mele interne.
Cum le dezactivez?

1- Xcode -> Product -> Scheme -> Edit Scheme

2- Adaug în Environment Variables set OS_ACTIVITY_MODE = disable


xcode

Share Button

Elemente de arhitectură aplicație IOS

Elemente pe care le descopăr în App Programming Guide for iOS și care consider că sunt relevante pentru dezvoltarea unei aplicații:

1. tabul Info -> Custom iOS Target Properties -> Application uses Wi-Fi trecut pe TRUE.Necesar dacă aplicația comunică cun un server. Poate fi setat și din cod.

2. Application life cycle – nu insist acum pe cele cinci stări ci pe metodele care permit tranziția între stări. Aceste metode definesc cine intră în scenă atunci când rulez o aplicație:

application:willFinishLaunchingWithOptions: — execută pentru prima oară cod în aplicație după lansare

application:didFinishLaunchingWithOptions: — înainte ca aplicația să fie afișată utilizatorului se fac ultimele inițializări.

applicationDidBecomeActive: — Aplicația va fi în curând disponibilă în Foreground. Aici se pot face ultimele ajustări înainte de a fi vizibilă.

applicationWillResignActive: — aplicația intră în mod de Inactive.

applicationDidEnterBackground: — aplicația a intrat în mod de Background.

applicationWillEnterForeground: — aplicația a trece din Background în mod de Foreground, însă nu este încă activă.

applicationWillTerminate: – Aplicația trece în stare de Suspended.

3. Pentru a bloca aplicația să ruleze în background  -> “Application does not run in background” -> YES. În acest caz la apăsarea butonului Home se apelează applicationWillTerminate: Aplicația va avea aproximativ 5 secunde să își facă clean up și să închidă/salveze.

4. Diagrama tranzițiilor de stare IOS



 

Aici sunt detaliate toate IOS keys din info.plist

 

Share Button