Programación en iOS

@acmupm

Swift: the great

@acmupm

  • Compilado (a máquina)
  • Interpretado
  • Multiplataforma
  • Imperativo
  • Orientado a objetos
  • Inferencia de tipos
  • Extensiones
  • Interoperable con C/C++ y Objective-C
  • Conceptos básicos de lenguajes funcionales (tipos de funciones de primer orden, manejo de listas, etc)
  • Sintaxis muy similar a Kotlin
  • Open Source

Swift: the great

@acmupm

let a = 5 //Valor inmutable
a = 6     //Error de compilación
        
var b = 6 //Valor mutable
b = 4
let f: (Int) -> Int = { x in 2 * x }
let f2 = { 2 * $0 }
let f3 = { 4 * $0 * $1 }
func divide(_ a: Int, _ b: Int) -> Int? {
    if b == 0 {
        return nil // También valdría return .none
    } else {
        return a / b
    }
}

let div: Int? = divide(10, 5)
let res: Int = div.map { $0 * 9 }
let res2: Int? = div.flatMap { divide($0, 2) }

let ints = [1, 2, 3]
let decimals = [1.0, 2.0, 3.0]
let strings = ["1", "2", "3"]

Swift: the great

@acmupm

struct Pair<A, B> {
    var first: A
    var second: B
}

func updateFirst<A, B>(_ p: Pair<A, B>, _ value: A) {
    var p2 = p
    p2.first = value
}

let pair = Pair(first: 1, second: 2)

print(pair)
updateFirst(pair, 5)
print(pair)

Swift: the great

@acmupm

extension Int {
    var squared: Int {
        return self * self
    }
}

protocol Multipliable {
    func multiply(by n: Self) -> Self
}

extension Int: Multipliable {
    func multiply(by n: Int) -> Int {
        return self * n
    }
}

extension Double: Multipliable {
    func multiply(by n: Double) -> Double {
        return self * n
    }
}

extension Multipliable {
    var squared: Self {
        return multiply(by: self)
    }
}

Swift: the great

@acmupm

protocol Addable {
    static var empty: Self { get }
    static func sum(_ x: Self, _ y: Self) -> Self
}

extension Int: Addable {
    static var empty: Int {
        return 0
    }
    
    static func sum(_ x: Int, _ y: Int) -> Int {
        return x + y
    }
}
func sum <A: Addable> (_ lst: [A]) -> A {
    return lst.reduce(A.empty, { A.sum($0, $1) })
}
extension Double: Addable {
    static var empty: Double {
        return 0
    }
    
    static func sum(_ x: Double, _ y: Double) -> Double {
        return x + y
    }
}

"Typeclasses"!

Swift: the "meh"

@acmupm

  • No existen las "clases abstractas"
  • Los protocolos no pueden tener tipos genéricos, solo "tipos asociados"
  • No existe ni covarianza ni contravarianza de tipos para tipos definidos por el usuario.

Swift: the worst

@acmupm

  • Las actualizaciones de Swift suelen romper la compatibilidad con versiones anteriores y se suele requerir de asistentes de migración para actualizarse.
  • XCode elimina la compatibilidad con versiones anteriores de Swift rápidamente.
  • La inferencia de tipos no es completa y puede dar problemas.

Gestión de Memoria

@acmupm

  • La app puede pedirle al sistema tanta memoria como necesite (hasta cierto límite).
  • La app deberá atender las notificaciones del sistema de advertencia de uso de memoria para eliminar aquello prescindible (cachés, etc) de la memoria, en cuanto éste se lo pida.
  • El sistema matará el proceso de la app si éste necesita una memoria que ésta no ha podido liberar.

Gestión de Memoria

@acmupm

  • ARC (Automatic Reference Counting): Libera la memoria de un objeto cuando su contador de referencias llega a 0.
let var1: UIView? = UIView() // ref: 1

if 1 == 1 {
    let var2 = var1 // ref: 2
} // ref: 1

weak var varWeak = var1 //ref: 1
var1 = nil // ref: 0 Objeto destruído.
  • Puede trabajar con grandes cantidadesde memoria sin problemas de rendimiento
     
  • No requiere pausas del programa para limpiar la memoria.
     
  • La asignación de memoria la realiza el sistema, y no una máquina virtual intermedia.
  • Strong references: aumentan el contador de referencias
  • Weak references: no aumentan el contador de referencias.
  • Unowned references: Igual que las weak, pero no requieren de un tipo opcional. El acceso a su valor después de su liberación puede producir un crash.

Gestión de Memoria

@acmupm

  • Referencias cíclicas

Interface Builder

@acmupm

  • Permite diseñar fácilmente interfaces para diferentes dispositivos y hacerte una idea de cómo quedará el diseño en ellos.
  • Soporta Storyboards y archivos XIB.
  • Los XML no se deben editar manualmente (como en Android)
  • Como los XML son generados automáticamente, pueden dar conflictos a la hora de usar un VCS.
  • Ciertas propiedades de los elementos no pueden modificarse desde el IB.
  • Soporte para vistas personalizados limitado.

Alternativa: Diseño de UI por código

Storyboards

@acmupm

  • Permiten agrupar diferentes vistas en un mismo archivo.
  • Permiten ver la relación entre las diferentes vistas del programa.
  • Cuando el número de vistas de un storyboard es elevado, el IB dará problemas de rendimiento.

Consejo: Agrupar las vistas de la app en diferentes storyboards.

Autolayout

@acmupm

  • Sistema para diseñar la disposición de las vistas en la pantalla y las relaciones entre ellas.
  • Muy maduro e integrado con todo el sistema (existe desde iOS 6)
  • Motor bastante potente. Apple se jacta de haber mejorado su rendimiento notablemente en iOS 12.
  • Universal: permite diseñar con las mismas herramientas cualquier tipo de interfaz.
  • Soporta animaciones.

Autolayout

@acmupm

Su funcionamiento es muy sencillo:

Constraints

Priorities

Content Hugging

Compression Resistance

Entrada

Motor de autolayout

Salida

(posición y tamaño de los rectángulos)

Alignment rects

Autolayout

@acmupm

Problemas de diseño:

  • Conflictos entre constraints: el motor de autolayout no puede satisfacer todas las constraints del diseño a la vez. (Suele acabar descuajeringando el diseño).
  • Diseños ambiguos: existe más de un diseño que satisface las constraints dadas. La selección de un diseño u otro no está determinado.

Stack View

@acmupm

  • Solventan fácilmente diseños basados en la apilación de vistas, tanto en vertical como en horizontal.
  • Más eficientes.
  • Construidos sobre autolayout.
  • Anidables.
  • Más fáciles de mantener.

Navegación

@acmupm

  • Objetivo: que el usuario sepa donde se encuentra dentro de la app, y cómo ha llegado ahi.
  • Requisitos de una buena navegación:
    • Coherente con el contenido: Seleccionar diferentes mecanismos de navegación acorde con lo que se pretende mostrar al usuario.
    • Consistente: el usuario debe poder volver sobre sus pasos viendo el contenido anterior a la pantalla en la que está de manera ordenada.

Navegación

@acmupm

  • UINavigationController:
    • Controla la barra de navegación.
    • Inicia una nueva pila de navegación con una primera vista (root view controller).
    • No puede haber anidación de UINavigationController`s.
  • UITabBarController:
    • Controla una barra inferior de pestañas.
    • Permite moverse entre View Controllers de una manera "plana", con independencia entre ellos.
    • Puede contener UINavigationController`s diferentes en cada pestaña.

Navegación

@acmupm

  • Modos de mostrar una nueva vista:
    • Modal: presenta una vista sobre la visible actualmente.
      • Pérdida de contexto.
      • Introducción de datos.
      • Acciones necesarias del usuario.
    • ​Push: Añade una nueva vista a la pila de navegación
      • Mantiene el contexto.
      • Información acerca de un elemento de la vista.
      • Accesos a otras partes de la app a través de la vista.
    • Pop: Retira una vista de la pila de navegación, volviendo a la anterior.

Navegación

@acmupm

Animaciones

@acmupm

Tablas

@acmupm

  • Permiten mostrar listas horizontales de contenido.
  • Posible división en secciones para organizar los elementos.
  • Las celdas son lazy: solo se cargan aquellas que son mostradas.

Gesture recognizers

@acmupm

  • Permiten detección de gestos.
  • Pueden añadirse y utilizarse en cualquier tipo de vista.
  • Algunos recognizers: Tap, Pan, Pinch, Rotation, Swipe, Screen Edge, Long Press

Arquitecturas de soft.

@acmupm

  • Objetivos:
    • Organizar el código.
    • Hacerlo modularizable y testeable.

@acmupm

  • Model View Controller:
    • Controlador: Responde a las interacciones del usuario, y solicita información al modelo.
    • Modelo: Provee información a la vista cuando el controlador lo solicita.
    • Vista: Muestra el contenido al usuario.

Arquitecturas de soft.

@acmupm

  • Model View Presenter:
    • Presentador: Responde a las interacciones del usuario, y solicita información al modelo.
    • Modelo: Provee información al presentador cuando éste lo solicita.
    • Vista: Muestra el contenido al usuario cuando el presenter se lo solicita.

Arquitecturas de soft.

Programación reactiva

@acmupm

En Swift: librería RxSwift

Publicación de Apps

@acmupm

  • Apple tiene un panel que permite subir nuevas versiones de las apps, añadir testers y editar la información de la app.
  • Las builds que se suben al App Store son comprobadas por procesos automáticos como por personas de manera manual.
  • Apple es muy restrictivo con las apps que permite subir al App Store.
  • Los criterios que usa Apple para aceptar o rechazar builds se encuentran enumerados en las App Store Review Guidelines.

Publicación de Apps

@acmupm

  • 2.4.1 To ensure people get the most out of your app, iPhone apps should run on iPad whenever possible.
  • 2.5.5 We will be reviewing on an IPv6 network, so if your app isn’t compatible with the IPv6 addressing, it may fail during review.
  • 2.5.7 Video streaming content over a cellular network longer than 10 minutes must use HTTP Live Streaming and include a baseline 192 kbps HTTP Live stream.
  • 5.1.1 (v) [...] Apps may not require users to enter personal information to function, except when directly relevant to the core functionality of the app or required by law.
  • 2.5.1 Apps may only use public APIs and must run on the currently shipping OS [...]

Últimos consejos

@acmupm

  • Conocer las App Store Review Guidelines para orientar el desarrollo de tu app acorde con sus exigencias.
  • Usar conocidos y probadas arquitecturas de software para organizar el código (MVC, MVP, MVVM, etc).
  • Desarrollar un código modularizable y testeable.
  • Hacer tests de unidad.
  • Usar mecanismos de interacción ya conocidos (no inventárselos).
  • Pensar bien cómo se va a estructurar la app desde el principio para hacer sistemas de navegación decentes.
  • Tratar de hacer diseños que sigan el look and feel clásico de iOS.
  • No abusar de las animaciones.
  • Conocer y utilizar las facilidades de accesibilidad que proporciona el sistema para permitir el uso de la app a personas con problemas de visión o auditivos.
  • Usar gestores de dependencias (CocoaPods)

Preguntas?

@acmupm

Made with Slides.com