Posts

Post not yet marked as solved
0 Replies
319 Views
I have a controller that its functions are to open the front camera, show the instructions in the view with a guide for the user to place his face, draw two buttons to capture the selfie photo and cancel the process. When capturing the photo with that controller, a function is called in a controller called 'Service Manager' to send the photo and update the stream's lifecycle. The problem occurs in devices like iPhone 7, when tapping on the "CAPTURE SELFIE" button the photo turns out to be dark or bright. Another problem that this driver has, but on all iOS devices, is that if the user minimizes the app and reopens it, the camera freezes and you have to minimize and reopen more than once to get the camera to work. resume and the user can capture the selfie correctly but the instructions are redrawn each time the user minimizes and opens the app again so the camera preview shows black. What can be caused this? I attached part of the code. func setUpAVCapture() { session.sessionPreset = AVCaptureSession.Preset.hd1280x720 guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: AVCaptureDevice.Position.front) else { return } } func stopCamera() { session.stopRunning() } @objc func captureButtonTapped() { guard let captureSession = captureSession else { return } self.animacion?.isHidden = true blurView?.addBlurToView() if self.activityView == nil { activityView = UIView(frame: CGRect(x: (self.view.frame.width / 2) - 50, y: (self.view.frame.height / 2) - 50, width: 100, height: 100)) activityView!.backgroundColor = UIColor(red:0 , green: 0, blue: 0, alpha: 0.8) activityView!.layer.cornerRadius = 4 activityIndicator = UIActivityIndicatorView(frame: CGRect(x: (activityView!.frame.width / 2) - 15, y: (activityView!.frame.height / 2) - 15, width: 30, height: 30)) if #available(iOS 13.0, *) { activityIndicator!.style = .large activityIndicator?.color = .white } else { activityIndicator?.style = .whiteLarge } activityView!.addSubview(activityIndicator!) self.view.addSubview(activityView!) } if intentosRealizados == 1 { if captureSession.canAddOutput(self.photoOutput) { captureSession.addOutput(self.photoOutput) } } let settings = AVCapturePhotoSettings() if let connection = photoOutput.connection(with: .video) { connection.videoOrientation = .portrait } let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let fileUrl = paths[0].appendingPathComponent("selfie.png") try? FileManager.default.removeItem(at: fileUrl) photoOutput.capturePhoto(with: settings, delegate: self) DispatchQueue.main.asyncAfter(deadline: .now() + 6.0){ self.performSelector(onMainThread: #selector(self.stopSelfie), with: nil, waitUntilDone: false) } activityIndicator?.startAnimating() activityView?.isHidden = false } func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { self.maskImage?.image = UIImage(named: "face_yellow") if let imageData = photo.fileDataRepresentation(), let image = UIImage(data: imageData) { let compressedData = image.jpegData(compressionQuality: 0.5) if let compressedImage = UIImage(data: compressedData ?? Data()){ if let compressedData = compressImage(image: compressedImage, maxSizeInBytes: 1 * 1024 * 1024) { let rotatedImage = UIImage(data: compressedData)?.rotate(radians: .pi / 0.5) let pngData = rotatedImage?.jpegData(compressionQuality: 1.0) let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectory.appendingPathComponent("selfie.png") if let data = pngData { do { try data.write(to: fileURL) } catch { } } } } } } func compressImage(image: UIImage, maxSizeInBytes: Int) -> Data? { let maxHeight: CGFloat = 1024.0 let maxWidth: CGFloat = 1024.0 var actualWidth = image.size.width var actualHeight = image.size.height if actualWidth <= maxWidth && actualHeight <= maxHeight { return image.jpegData(compressionQuality: 1.0) } let imgRatio = actualWidth / actualHeight var newWidth: CGFloat var newHeight: CGFloat if imgRatio > maxWidth / maxHeight { newWidth = maxWidth newHeight = maxWidth / imgRatio } else { newHeight = maxHeight newWidth = maxHeight * imgRatio } let renderRect = CGRect(x: 0, y: 0, width: newWidth, height: newHeight) let renderer = UIGraphicsImageRenderer(size: renderRect.size) let compressedImage = renderer.image { context in image.draw(in: renderRect) } var compressionQuality: CGFloat = 1.0 var finalImageData = compressedImage.jpegData(compressionQuality: compressionQuality) while finalImageData?.count ?? 0 > maxSizeInBytes && compressionQuality > 0.1 { compressionQuality -= 0.1 finalImageData = compressedImage.jpegData(compressionQuality: compressionQuality) } return finalImageData } That the use of the camera, in the application, is compatible with all devices from iPhone 6+. The intention of this controller is that the application takes a selfie photo, saves it in png and that the file size is less than 5MB. Thank you
Posted
by rockyto.
Last updated
.
Post not yet marked as solved
0 Replies
305 Views
I am using a pod called SpreadsheetView to show data, from a json, in a grid but I don't know how to show them because with this pod it is necessary to invoke an array for each column. I would like to order this data from my json in the corresponding columns and also when touching a cell in a row I was taken to a view to show the related data. Attached the code of what I have done. The view i use to display the data import UIKit import SpreadsheetView class TiendasViewController: UIViewController, SpreadsheetViewDataSource, SpreadsheetViewDelegate, ConsultaModeloProtocol{ let data = ["Sucursal", "Venta total", "Tickets", "Piezas", "Pzs/Ticket", "Ticket prom.", "Utilidad", "Última venta"]   let sucursales = ["Hamleys", "Bobby Brown", "Aristocrazy", "Jo Malone"]   let vtaTotal = ["$1","$1","$1","$1"]   let tickets = ["1","2","3","4"]   let pzas = ["10", "20", "30", "40"]   let pzasTicket = ["20", "40", "60", "80"]   let tktProm = ["$2", "$4", "$6", "$8"]   let utilidad = ["10%", "20%", "30%", "40%"]   let ultVta = ["13:00","14:00","15:00","16:00"]       var feedItems = [DetallesConsulta]()       func itemConsulta(LaConsulta: [DetallesConsulta]) {     feedItems = LaConsulta     self.tablaTiendas.reloadData()         }       var selectDato : DetallesConsulta = DetallesConsulta()       private let tablaTiendas = SpreadsheetView()           override func viewDidLoad() {           super.viewDidLoad()           let consultaModelo = ConsultaModelo()     consultaModelo.ElDelegado = self     consultaModelo.downloadConsulta()           tablaTiendas.dataSource = self     tablaTiendas.delegate = self           tablaTiendas.contentInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 0)     tablaTiendas.intercellSpacing = CGSize(width: 4, height: 1)     tablaTiendas.gridStyle = .none                 tablaTiendas.gridStyle = .solid(width: 1, color: .blue)     tablaTiendas.register(SucursalesCell.self, forCellWithReuseIdentifier: String(describing: SucursalesCell.self))     tablaTiendas.register(DateCell.self, forCellWithReuseIdentifier: String(describing: DateCell.self))                view.addSubview(tablaTiendas)     print("Imprimiendo los feeditems: ", feedItems)     // Do any additional setup after loading the view.   }       override func viewDidLayoutSubviews() {     super.viewDidLayoutSubviews()     tablaTiendas.frame = CGRect(x: 0, y:216, width: view.frame.size.width, height: view.frame.size.height-100)   }       override func viewDidAppear(_ animated: Bool) {     super.viewDidAppear(animated)     tablaTiendas.flashScrollIndicators()   }       func spreadsheetView(_ spreadsheetView: SpreadsheetView, cellForItemAt indexPath: IndexPath) -> Cell? {           if case (0...(data.count), 0) = (indexPath.column, indexPath.row) {               let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: String(describing: DateCell.self), for: indexPath) as! DateCell       cell.label.text = data[indexPath.column - 0]       return cell             } else if case(0, 1...(sucursales.count + 1)) = (indexPath.column, indexPath.row){               let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: String(describing: SucursalesCell.self), for: indexPath) as! SucursalesCell               cell.label.text = sucursales[indexPath.row - 1]       return cell             }          /*     let cell = tablaTiendas.dequeueReusableCell(withReuseIdentifier: MyLabelCell.identifier, for: indexPath) as! MyLabelCell     if indexPath.row == 0 {       cell.setup(with: data[indexPath.column])       cell.backgroundColor = .systemBlue     }     return cell     */           return nil   }       func numberOfColumns(in spreadsheetView: SpreadsheetView) -> Int {     return data.count   }       func numberOfRows(in spreadsheetView: SpreadsheetView) -> Int {     return 1 + sucursales.count   }       func spreadsheetView(_ spreadsheetView: SpreadsheetView, widthForColumn column: Int) -> CGFloat {     return 200   }       func spreadsheetView(_ spreadsheetView: SpreadsheetView, heightForRow row: Int) -> CGFloat {     if case 0 = row{       return 24     }else{       return 55     }         }       func frozenColumns(in spreadsheetView: SpreadsheetView) -> Int {     return 1   } } class MyLabelCell: Cell {       private let label = UILabel()       public func setup(with text: String){     label.text = text     label.textAlignment = .center     contentView.addSubview(label)   }       override func layoutSubviews() {     super.layoutSubviews()     label.frame = contentView.bounds   } } class DateCell: Cell {   let label = UILabel()   override init(frame: CGRect) {     super.init(frame: frame)     label.frame = bounds     label.autoresizingMask = [.flexibleWidth, .flexibleHeight]     label.font = UIFont.boldSystemFont(ofSize: 15)     label.textAlignment = .center     contentView.addSubview(label)   }   required init?(coder aDecoder: NSCoder) {     super.init(coder: aDecoder)   } } class SucursalesCell: Cell {   let label = UILabel()   override init(frame: CGRect) {     super.init(frame: frame)     label.frame = bounds     label.autoresizingMask = [.flexibleWidth, .flexibleHeight]     label.font = UIFont.monospacedDigitSystemFont(ofSize: 12, weight: UIFont.Weight.medium)     label.textAlignment = .center     contentView.addSubview(label)   }   override var frame: CGRect {     didSet {       label.frame = bounds.insetBy(dx: 6, dy: 0)     }   }   required init?(coder aDecoder: NSCoder) {     super.init(coder: aDecoder)   } }
Posted
by rockyto.
Last updated
.
Post marked as solved
2 Replies
1.4k Views
Hello good afternoon to everyone. I hope you are doing very well despite the situation we are going through. I tell you my problem. I am trying to save in an array, a series of data that is selected from a tableView through a JSON. That is, the tableView shows some data available to select, the ones that are selected I want to save them in an array but when I select a data in the tableView my app crashes and shows me a breakpoint "Thread 1: signal SIGABRT" And in the console I get this: Could not cast value of type 'MallConcierge.DetallesIntereses' (0x10ca9be10) to 'NSString' (0x7fff86d8bbb0). I hope you can help me, I attach the classes from where I download the data, the details and the class where I connect the tableView. InteresesModelo.swift (in this class is where I download the data in JSON) import UIKit protocol InteresesModeloProtocol: class{ func interesesDownload (interest: NSArray) } class InteresesModelo: NSObject { weak var delegate: InteresesModeloProtocol! let urlPath = "http://localhost:8888/mallconcierge/API-movil/interests.php" func interestDownload(){ let url: URL = URL(string: urlPath)! let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.ephemeral) URLCache.shared.removeAllCachedResponses() let task = defaultSession.dataTask(with: url){ (data, response, error) in if error != nil{ print("Error al descargar datos") }else{ print("Datos descargados") self.parseJSON(data!) } } task.resume() } func parseJSON(_ data:Data){ var jsonResult = NSArray() do{ jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSArray }catch let error as NSError{ print(error) } var jsonElement = NSDictionary() let detalles = NSMutableArray() for i in 0 ..< jsonResult.count{ jsonElement = jsonResult[i] as! NSDictionary let detalle = DetallesIntereses() let idInteres = jsonElement["idInteres"] let nombreInteres = jsonElement["interesNombre"] detalle.idInteres = idInteres as? String detalle.nombreInteres = nombreInteres as? String detalles.add(detalle) } DispatchQueue.main.async(execute: { ()-> Void in self.delegate.interesesDownload(interest: detalles) }) } } DetallesIntereses.swift import UIKit class DetallesIntereses: NSObject { var idInteres: String? var nombreInteres: String? override init() { } init(idInteres: String, nombreInteres:String) { self.idInteres = idInteres self.nombreInteres = nombreInteres } override var description: String{ return "idInteres: \(idInteres), nombreInteres: \(nombreInteres)" } } InteresesViewController.swift import UIKit class InteresesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, InteresesModeloProtocol { var selectIntereses = [String]() var feedInterests: NSArray = NSArray() // var selectInterests: DetallesIntereses = DetallesIntereses() var items=[String]() @IBOutlet var listaInteresesTableView: UITableView! func interesesDownload(interest: NSArray) { feedInterests = interest self.listaInteresesTableView.reloadData() } override func viewDidLoad() { self.listaInteresesTableView.isEditing = true self.listaInteresesTableView.allowsMultipleSelectionDuringEditing = true self.listaInteresesTableView.delegate = self self.listaInteresesTableView.dataSource = self let interesesModelo = InteresesModelo() interesesModelo.delegate = self interesesModelo.interestDownload() super.viewDidLoad() // Do any additional setup after loading the view. } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return feedInterests.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "celInterests", for: indexPath) as! InteresesTableViewCell let interest: DetallesIntereses = feedInterests[indexPath.row] as! DetallesIntereses cell.lblNombreIntereses!.text = interest.nombreInteres return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { self.selectDeselectCell(tableView: listaInteresesTableView, indexPath: indexPath) print("Seleccionado") } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { self.selectDeselectCell(tableView: listaInteresesTableView, indexPath: indexPath) print("Deseleccionado") } func selectDeselectCell(tableView: UITableView, indexPath: IndexPath){ self.selectIntereses.removeAll() if let arr = listaInteresesTableView.indexPathsForSelectedRows{ for index in arr{ selectIntereses.append(feedInterests[indexPath.row] as! String) } } print(selectIntereses) } @IBAction func seleccionarIntereses(_ sender: Any){ print(selectIntereses) } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } The JSON [ { "idInteres": "1", "interesNombre": "Moda Mujer" }, { "idInteres": "3", "interesNombre": "Moda Hombre" }, { "idInteres": "4", "interesNombre": "Belleza" }, { "idInteres": "5", "interesNombre": "Relojes y Joyería" }, { "idInteres": "6", "interesNombre": "Hogar/Interiorismo" }, { "idInteres": "7", "interesNombre": "Gastronomía" }, { "idInteres": "8", "interesNombre": "Entretenimiento" }, { "idInteres": "9", "interesNombre": "Wellness" } ] I hope you can help me, please. I thank you all
Posted
by rockyto.
Last updated
.