Hola, Apple

1

Hablemos de iOS

2

Conozcamos XCode

3

¿Necesito un iPhone para ser iOS Developer?

Tu primera app en iOS

4

¡Hola, Mundo Apple!

5

Navegación con UINavigationController

6

Modales en la navegación

7

Utilizando controles en código

8

Autolayout vs SwiftUI

9

Autolayout

10

Listas con UITableView

11

Celdas personalizadas para nuestras listas.

12

Persistencia: UserDefaults

Manejo de dependencias

13

CocoaPods

14

Carthage

Servicios Web

15

Primeros pasos para consumir servicios

16

Afinando detalles para consumir servicios

17

Convirtiendo los JSON a modelos

18

Alamofire

Proyecto: PlatziTweets

19

Bienvenido a PlatziTweets

20

Configurando Proyecto

21

Diseñando vistas iniciales

22

Configuración de vistas iniciales

23

Configuración de registro

24

Descripción de la API de PlatziTweets

25

Conexión de la API y Autenticación

26

Registro de usuarios

27

Diseño del Tweet

28

Obteniendo Tweets

29

Creación de vista para publicar Tweets

30

Publicando Tweets

31

Borrando Tweets

32

Integración de la cámara

33

Conexión con Firebase

34

Configuración de XCode para correr app

35

Subir imagen a Firebase

36

Publicar Tweet con imagen

37

Tomando Videos para el Tweet

38

Publicar Tweet con video

39

Detalles del video

40

Accediendo al GPS

41

Implementando mapas con MapsKit

42

Mostrando todos los estudiantes en el mapa

43

Retos del proyecto

En producción

44

Enviar a pruebas con Firebase Distribution

45

Enviar tu aplicación a APP Store Connect

46

Distribución de tu app con TestFlight

iOS Avanzado

47

Dark Mode

48

SwiftUI

49

Terminando detalles de una vista con SwiftUI

50

Objective-C

Hola, iOS Developer

51

Felicidades

52

Expert Session: ¡nuevo espacio para resolver tus dudas sobre el desarrollo de Apps para iOS!

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
8 Hrs
37 Min
4 Seg

Afinando detalles para consumir servicios

16/52
Recursos

¿Cómo solucionar errores comunes al consumir servicios web en iOS?

Al desarrollar aplicaciones iOS que consumen servicios web, es fácil olvidar algunos detalles cruciales que pueden afectar el funcionamiento del código. Uno de los errores más comunes es olvidar ejecutar el dataTask. En este tipo de desarrollo, es importante seguir algunos pasos para asegurarse de que el servicio se consuma correctamente y, finalmente, ejecutar el request.

¿Cómo ejecutar correctamente un dataTask en Swift?

El uso de URLSession en Swift es estándar al consumir servicios web. Después de configurar tu request y asegurarte de que todo está correcto, nunca olvides el método .resume() en tu dataTask. Este es el paso final que permite que el request se ejecute:

let task = URLSession.shared.dataTask(with: url) { data, response, error in
    // Manejo de la respuesta
}
task.resume()

Este método es crucial para activar el data task. Olvidarlo es un error común que puede llevar a horas de frustración.

¿Por qué es importante hacer cambios en la UI desde el main thread?

Cuando se trata de realizar cambios en la interfaz de usuario (UI) en iOS, es imperativo que estos cambios se realicen en el hilo principal. Esto se debe a que la UI en iOS es notoriamente no thread-safe, lo que significa que si intentas actualizar la UI desde un hilo secundario, podrías enfrentar inconsistencias o fallos inesperados.

Usa el siguiente patrón para ejecutar actualizaciones de UI desde el main thread:

DispatchQueue.main.async {
    // Tu código de UI aquí
}

¿Cómo mejorar la interacción de la UI con Activity Indicators?

Para mejorar la experiencia del usuario, es esencial manejar los ActivityIndicators de manera eficiente. Al iniciar una solicitud de servicio, debes hacer que el ActivityIndicator comience a animarse y detener la animación una vez que el servicio haya terminado:

indicator.startAnimating()
// Iniciar la solicitud
URLSession.shared.dataTask(with: url) { data, response, error in
    DispatchQueue.main.async {
        indicator.stopAnimating()
    }
}.resume()

No olvides gestionarlo dentro del main thread ya que esto afecta directamente la UI.

¿Cómo cambiar un label basado en la respuesta de un servicio?

Supón que deseas cambiar un label basado en una respuesta JSON. Para esto, puedes convertir el diccionario recibido en una estructura más unificada y luego usar esa estructura para actualizar UI.

Un ejemplo sencillo de esta operación es el siguiente:

if let isHappy = dictionary["isHappy"] as? Bool {
    DispatchQueue.main.async {
        self.statusLabel.text = isHappy ? "Es feliz" : "Es triste"
    }
}

Usando un operador ternario, puedes determinar qué texto mostrar.

¿Es recomendable usar diccionarios para el manejo de datos?

Aunque puedes manejar tus servicios web usando diccionarios, esta es la forma más sencilla pero menos recomendable. Lo ideal es transformar la respuesta a estructuras de datos o modelos definidos que puedas manipular fácilmente y que te ofrezcan más seguridad y claridad en tu código. En futuras clases exploraremos cómo convertir estos datos a modelos en Swift, lo cual es una técnica que te aportará robustez y fiabilidad en tus aplicaciones.

¡No olvides practicar! Busca servicios de prueba como "mock json services" y sigue experimentando. Esto te ayudará a fortalecer tus habilidades y a enfrentarte con confianza a nuevos desafíos.

Aportes 14

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Por defecto la llamada al servicio se hace en un hilo secundario por lo que para hacer actualizaciones al UI se necesita envolver el código dentro del bloque DispatchQueue para indicarle que lo haga en el hilo principal.

😎

Hice un pequeño reto usando este JSON que me encontre en internet. Al parecer todo bien…

class ViewController: UIViewController
{
    @IBOutlet weak var userIDLabel : UILabel!
    @IBOutlet weak var idLabel : UILabel!
    @IBOutlet weak var titleLabel : UILabel!
    @IBOutlet weak var completedLabel : UILabel!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    
    
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        fetchServices()
    }

    private func fetchServices()
    {
        let URLServer = "https://jsonplaceholder.typicode.com/todos/1"
        
        guard let endpoint = URL(string: URLServer) else
        {
            return
        }
        
        //Inicializacion del Loader
        activityIndicator.startAnimating()
        
        URLSession.shared.dataTask(with: endpoint)
        {
            
            (data: Data?, _, error: Error?) in
            
            //Detencion del Loader
            DispatchQueue.main.async
            {
                self.activityIndicator.stopAnimating()
            }
            
            if error != nil
            {
                print("Error. Linea hecha por mi.")
                return
            }
            
            guard let dataFromService = data, let dictionary = try? JSONSerialization.jsonObject(with: dataFromService, options: []) as? [String:Any] else
            {
                return
            }
            
            //Importante: Todos los llamados a la UI; se hacen en el main thread
            DispatchQueue.main.async
            {
                //self.userIDLabel.text = dictionary["userId"] as? String
                
                let userIdIsOne = dictionary["userId"] as? Bool ?? false
                self.userIDLabel.text = userIdIsOne ? "Contiene algun valor" : "Pues no..."
                
                
                let idIsOne = dictionary["id"] as? Bool ?? false
                self.idLabel.text = idIsOne ? "Contiene algun valor" : "Al parecer no contiene un valor"
                
                self.titleLabel.text = dictionary["title"] as? String
                
                
                let isCompleted = dictionary["completed"] as? Bool ?? false
                self.completedLabel.text = isCompleted ? "completado" : "no completado"
                
                
            }
            
            
        }.resume()
        
        
    }
    
    
    
}


Super, solo añadiría al completion un [weak self] para evitar un retain cycle 😃

Con Xcode 13 cambiaron la forma en la que funcionan las Info.plist, ahora se se completa la Info.plist al hacer el build del target y sólo genera un Info.plist para los cambios que queremos hacer. Ahora debemos hacer los cambios dentro del target y dirigirnos a la tab de Info, entre Resource Tags y Build Settings

https://useyourloaf.com/blog/xcode-13-missing-info.plist/

no lo eh podido hacer con swif UI ahora menos con StoryBoard 😣.

eh tratato de usar la api get de woocommerce no. 😢

Interesante clase ! Feliz 😄

Buen ejercicio y muy bien explicada las ambas clases

excelente clase!

      DispatchQueue.main.async {
                self.activityIndicator.hidesWhenStopped = true // para ocultarlo cuando se detiene. 
                self.activityIndicator.stopAnimating()                                
                  }

Final version

Me encanto esta clase, poder lograr entender el codigo y la explicacion me ha llenado de mucho animo para seguir.

La magia de la version Xcode 12.4 es que ya te advierte que debes mover esa linea de codigo a un main thread

Antes de que se acabe el PlatziDay, muy buen curso, muchas gracias. Excelente explicacion. Psdt: No me quiero ir Stark :<