// AuthService.
swift
// CafeteriaXD
//
// Created by Suite on 20/12/25.
//
import Foundation
//Clase que almacena token y user_id por instancia
final class Session {
let token: String
let userId: String
init(token: String, userId: String) {
[Link] = token
[Link] = userId
}
}
class AuthService {
private let baseURL: String
private let apiKey: String
init(baseURL: String, apiKey: String) {
[Link] = baseURL
[Link] = apiKey
}
// Ahora la función login devuelve una Session
func login(email: String, password: String, completion: @escaping (Result<Session, Error>) -> Void)
{
let url = "\(baseURL)/auth/v1/token?grant_type=password"
struct LoginBody: Codable {
let email: String
let password: String
}
let loginBody = LoginBody(email: email, password: password)
let headers = [
"apikey": apiKey,
"Content-Type": "application/json"
]
[Link](url: url, method: "POST", body: loginBody, headers: headers) { (result:
Result<LoginResponse, Error>) in
switch result {
case .success(let loginResponse):
// Crear la sesión con token y userId
let session = Session(token: loginResponse.access_token, userId: [Link])
completion(.success(session))
case .failure(let error):
completion(.failure(error))
}
}
}
}
// [Link]
// CafeteriaXD
//
// Created by Suite on 20/12/25.
//
import Foundation
final class APICaller {
static let shared = APICaller()
private init() {}
func request<T: Codable, R: Codable>(
url: String,
method: String,
body: T?,
headers: [String: String] = [:],
completion: @escaping (Result<R, Error>) -> Void
){
guard let endpoint = URL(string: url) else {
completion(.failure(URLError(.badURL)))
return
}
var request = URLRequest(url: endpoint)
[Link] = method
[Link]("application/json", forHTTPHeaderField: "Content-Type")
[Link] {
[Link]($[Link], forHTTPHeaderField: $[Link])
}
if let body {
do {
[Link] = try JSONEncoder().encode(body)
} catch {
completion(.failure(error))
return
}
}
[Link](with: request) { data, response, error in
if let error {
completion(.failure(error))
return
}
guard let http = response as? HTTPURLResponse,
(200...299).contains([Link]) else {
completion(.failure(URLError(.badServerResponse)))
return
}
guard let data else {
completion(.failure(URLError(.cannotDecodeRawData)))
return
}
do {
let decoded = try JSONDecoder().decode([Link], from: data)
completion(.success(decoded))
} catch {
completion(.failure(error))
}
}.resume()
}
}
import Foundation
struct LoginResponse: Codable {
let access_token: String
let token_type: String
let expires_in: Int
let refresh_token: String
let user: User
}
struct User: Codable {
let id: String
let email: String
}
import UIKit
import Foundation
class LoginViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet weak var ImagenLogin: UIImageView!
@IBOutlet weak var logoCafeteria: UIImageView!
@IBOutlet weak var TitleLabel: UILabel!
@IBOutlet weak var EmailTexfield: UITextField!
@IBOutlet weak var passwordTexfiel: UITextField!
@IBOutlet weak var InicioButton: UIButton!
@IBOutlet weak var viewLogin: UIView!
// MARK: - Auth Service como instancia
private let authService = AuthService()
// MARK: - Lifecycle
override func viewDidLoad() {
[Link]()
setupUI()
// MARK: - Setup
private func setupUI() {
[Link](15)
[Link](.white)
[Link]()
[Link](placeholder: "Email")
[Link](placeholder: "Contraseña")
[Link](borderColor: .gray, borderWidth: 2)
[Link](5)
[Link] = UIImage(named: "ImageLogin")
[Link] = UIImage(named: "ImageIcon")
[Link](self, action: #selector(didTapLogin),
for: .touchUpInside)
// MARK: - Actions
@objc private func didTapLogin() {
guard let email = [Link], ![Link],
let password = [Link], ![Link] else {
showAlert(message: "Por favor ingresa email y contraseña")
return
[Link](email: email, password: password) { [weak self] result
in
[Link] {
switch result {
case .success(let session):
// Guardar token y user_id en UserDefaults
[Link]([Link], forKey:
"access_token")
[Link]([Link], forKey: "user_id")
self?.showAlert(message: "Login exitoso: \([Link])")
// Aquí podrías navegar a la siguiente pantalla
case .failure(let error):
self?.showAlert(message: "Error: \([Link])")
// MARK: - Helpers
private func showAlert(message: String) {
let alert = UIAlertController(title: "Login", message: message,
preferredStyle: .alert)
[Link](UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
/*/*/*/*//*/*/*/*/
//
// [Link]
// CafeteriaXD
//
// Created by Suite on 20/12/25.
//
import Foundation
struct LoginBody: Codable{
let email: String
let password: String
}
struct LoginResponse: Codable {
let access_token: String
let token_type: String
let expires_in: Int
let refresh_token: String
let user: User
}
struct User: Codable {
let id: String
let email: String
}
*/*/*/*/*/*/*/*/*/*/*/*/*/
// [Link]
// CafeteriaXD
//
// Created by user240043 on 12/22/25.
//
import Foundation
final class Sesion {
let token: String
let userId: String
init(token: String, userId: String) {
[Link] = token
[Link] = userId
}
}
*/*/*/*/*/*/*/*/*/*/*/*/*/*/
//
// [Link]
// CafeteriaXD
//
// Created by Suite on 20/12/25.
//
import Foundation
struct APIConfig {
static let baseURL = "[Link]
static let apiKey = "sb_publishable_Ji-HOOg47_E-RXeqcF-czQ_ivUt-XCJ"
}
class AuthService {
private let baseURL: String
private let apiKey: String
init() {
[Link] = [Link]
[Link] = [Link]
}
// Ahora la función login devuelve una Session
func login(email: String, password: String, completion: @escaping (Result<Sesion, Error>) -> Void)
{
let url = "\(baseURL)/auth/v1/token?grant_type=password"
let loginBody = LoginBody(email: email, password: password)
let headers = [
"apikey": apiKey,
"Content-Type": "application/json"
]
[Link](url: url, method: "POST", body: loginBody, headers: headers) { (result:
Result<LoginResponse, Error>) in
switch result {
case .success(let loginResponse):
// Crear la sesión con token y userId
let session = Sesion(token: loginResponse.access_token, userId: [Link])
completion(.success(session))
case .failure(let error):
completion(.failure(error))
}
}
}
}
*--/*/*/*/*/*/*/*/*/**//**/*/*/*/*/*/*/*/*/*
// [Link]
// CafeteriaXD
//
// Created by Suite on 20/12/25.
//
import UIKit
import Foundation
class LoginViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet weak var ImagenLogin: UIImageView!
@IBOutlet weak var logoCafeteria: UIImageView!
@IBOutlet weak var TitleLabel: UILabel!
@IBOutlet weak var EmailTexfield: UITextField!
@IBOutlet weak var passwordTexfiel: UITextField!
@IBOutlet weak var InicioButton: UIButton!
@IBOutlet weak var viewLogin: UIView!
// MARK: - Auth Service como instancia
private let authService = AuthService()
// MARK: - Lifecycle
override func viewDidLoad() {
[Link]()
setupUI()
}
// MARK: - Setup
private func setupUI() {
[Link](15)
[Link](.white)
[Link]()
[Link](placeholder: "Email")
[Link](placeholder: "Contraseña")
[Link](borderColor: .gray, borderWidth: 2)
[Link](5)
[Link] = UIImage(named: "ImageLogin")
[Link] = UIImage(named: "ImageIcon")
[Link](self, action: #selector(didTapLogin), for: .touchUpInside)
}
// MARK: - Actions
@objc private func didTapLogin() {
guard let email = [Link], ![Link],
let password = [Link], ![Link] else {
showAlert(message: "Por favor ingresa email y contraseña")
return
}
[Link](email: email, password: password) { [weak self] result in
[Link] {
switch result {
case .success(let session):
// Guardar token y user_id en UserDefaults
[Link]([Link], forKey: "access_token")
[Link]([Link], forKey: "user_id")
self?.showAlert(message: "Login exitoso: \([Link])")
// Aquí podrías navegar a la siguiente pantalla
case .failure(let error):
self?.showAlert(message: "Error: \([Link])")
}
}
}
}
// MARK: - Helpers
private func showAlert(message: String) {
let alert = UIAlertController(title: "Login", message: message, preferredStyle: .alert)
[Link](UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
}
// MARK: - Actions
@objc private func didTapLogin() {
guard let email = [Link], ![Link],
let password = [Link], ![Link] else {
showAlert(message: "Por favor ingresa email y contraseña")
return
}
[Link](email: email, password: password) { [weak self] result
in
[Link] {
switch result {
case .success(let session):
// Guardar token y user_id
[Link]([Link], forKey:
"access_token")
[Link]([Link], forKey: "user_id")
// Navegar a HomeViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let homeVC =
[Link](withIdentifier: "HomeViewController")
as? HomeViewController {
[Link] = .fullScreen
self?.present(homeVC, animated: true)
}
case .failure(let error):
self?.showAlert(message: "Error: \([Link])")
}
}
}
}
*/*/*/**/*//
Exception NSException * "Storyboard (<UIStoryboard:
0x600002632760>) doesn't contain a view controller with identifier
'HomeViewController'" 0x0000600000d3a6d0
-😍----*--😍/*/*/*/*/*/*/*/*/*/*
rror: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard
(<UIStoryboard: 0x600002632760>) doesn't contain a view controller with identifier
'HomeViewController''
*** First throw call stack:
(
0 CoreFoundation 0x0000000180491128 __exceptionPreprocess + 172
1 [Link] 0x000000018008412c objc_exception_throw + 56
2 UIKitCore 0x00000001854753d4 -[UIStoryboard
_instantiateInitialViewControllerWithCreator:storyboardSegueTemplate:sender:] + 0
3 CafeteriaXD 0x0000000102fd0c78
$s11CafeteriaXD19LoginViewControllerC06didTapC0030_B9DAB2F25489C3ADC2B73ABE24D08H1ELLy
yFys6ResultOyAA6SesionCs5Error_pGcfU_yyScMYccfU_ + 860
4 CafeteriaXD 0x0000000102fd11e4 $sIeg_IeyB_TR + 48
5 [Link] 0x00000001039540f0 _dispatch_call_block_and_release + 24
6 [Link] 0x000000010395593c _dispatch_client_callout + 16
7 [Link] 0x00000001039655e4 _dispatch_main_queue_drain + 1228
8 [Link] 0x0000000103965108 _dispatch_main_queue_callback_4CF + 40
9 CoreFoundation 0x00000001803f1a30
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
10 CoreFoundation 0x00000001803ec148 __CFRunLoopRun + 1936
11 CoreFoundation
😍-😍-😍-😍/*/*/*/
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental
variable.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number)
to CoreGraphics API and this value is being ignored. Please fix this problem.
*/*/*/*
Exception NSException * "Storyboard (<UIStoryboard:
0x600002630540>) doesn't contain a view controller with identifier
'HomeViewController'" 0x0000600000c66d30