Reproductor del podcast Próxima parada swift
Reproductor del podcast Próxima Parada Swift publicado en https://proximaparadaswift.dev
Proyecto realizado con MVVM en SwiftUI, utilizando Observable, SwiftData, Combine, AVFoundation, Regex,
Funcionalidades
Ordena los episodios por fecha, búscalos por título o filtra por categoría
Escucha el episodio ajustando la velocidad de reproducción
Descarga el audio de los episodios para escucharlos después
Lleva el registro de tus episodios favoritos y escuchados
Obtén un listado de enlaces que recomiendo para aprender Swift
Retos personales conseguidos
* AVFoundation para reproducir los audios del podcast y poder cambiar la velocidad de reproducción.
* Regex (Expresiones Regulares) para obtener a patir del json generado por la API de WordPress el contenido y de ahí obtener la url del audio.
* SwiftData para la persistencia de datos
* Convertir correctamente un post de WordPress en formato HTML a un `AttributedString`
Referencias
Vista Previa
Apuntes
Convertir un html a un attributedString
//Convierte de un html a un AttributedString
func attributedTextFromHTML(_ html: String) -> AttributedString? {
guard let data = html.data(using: .utf8) else { return nil }
do {
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue]
let attributtedString = try AttributedString.init(NSAttributedString(data: data, options: options, documentAttributes: nil))
return attributtedString
} catch {
return nil
}
}
Container de SwiftData con dos schemas
extension ModelContainer {
static var previewContainer: ModelContainer {
let schema = Schema([
Episodio.self,
PostCategory.self
])
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: schema, configurations: config)
return container
}
}
Container para la preview
extension ModelContainer {
static var previewContainer: ModelContainer {
let schema = Schema([
Episodio.self,
PostCategory.self
])
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: schema, configurations: config)
return container
}
}
¿Quieres recibir posts, cheatCodes, enlaces y katas en Swift para practicar?
Quincenalmente recibirás en tu correo electrónico la newsletter, solo hace falta tu correo electrónico.