I am struggling to comprehend how to cache images in my listview that I have fetched from Firebase. I have checked online and most of the solutions are somewhat different from the style of code I am writing so find it difficult to transfer over. Any solutions would be grateful for the class I have provided below.
class StaffListTableViewCell: UITableViewCell {
#IBOutlet weak var staffFirstAndLastName: UILabel!
#IBOutlet weak var JobTitle: UILabel!
#IBOutlet weak var staffImageView: UIImageView!
var databaseRef: DatabaseReference {
return Database.database().reference()
}
var storageRef: Storage {
return Storage.storage()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func configureCell(teacher: StaffListsSTRUCT) {
//this line of code helps sets the imageviews in the list view to nil before loading.
self.staffImageView.image = nil
self.staffFirstAndLastName.text = teacher.staffName
self.JobTitle.text = teacher.staffJobTitle
let imageURL = teacher.staffImageViewString!
self.storageRef.reference(forURL: imageURL).getData(maxSize: 1 * 1024 * 1024, completion: { (imgData,
error) in
if error == nil {
DispatchQueue.main.async {
if let data = imgData {
self.staffImageView.image = UIImage(data: data)
}
}
} else {
print(error!.localizedDescription)
}
})
}
}
Related
This question already has answers here:
How to remove optional text from json Result In swift
(3 answers)
Optional Text in Alert in ResetPassword - iOS Project using Swift
(2 answers)
Closed 1 year ago.
So I'm using firebase Authentication in my ios app, and I want to display the email address, and Username in UIlabels on a viewcontroller. But when i display the value of Auth.auth().email on a UIlabel, the Label would show Optional"email adress".How do i get rid of the Optional and also how to allow the user to have a display name in firebase Authentication?
import Firebase
import FirebaseAuth
class ProfileViewController: UIViewController {
#IBOutlet weak var profiepic: UIImageView!
#IBOutlet weak var UsernameLabel: UILabel!
#IBOutlet weak var EmailLabel: UILabel!
#IBOutlet weak var league: UILabel!
#IBOutlet weak var Achievements: UIButton!
#IBOutlet weak var resetpasswd: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
UsernameLabel.layer.borderColor = UIColor.black.cgColor
EmailLabel.layer.borderColor = UIColor.black.cgColor
league.layer.borderColor = UIColor.black.cgColor
Achievements.layer.cornerRadius = 55/2
resetpasswd.layer.cornerRadius = 55/2
resetpasswd.layer.borderColor = UIColor.black.cgColor
displayinfo()
}
func displayinfo() {
let user = Auth.auth().currentUser
if let user = user {
// The user's ID, unique to the Firebase project.
// Do NOT use this value to authenticate with your backend server,
// if you have one. Use getTokenWithCompletion:completion: instead.
let email = user.email
let photoURL = user.photoURL
EmailLabel.text = "Email: \(email)"
// ...
}
}
/*
// 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.
}
*/
}
You need to use if or guard to display string info properly.
Using if:
func displayinfo() {
let user = Auth.auth().currentUser
if let user = user {
if let email = user.email {
EmailLabel.text = "Email: \(email)"
}
if let photoURL = user.photoURL {
...
}
// ...
}
}
Using guard:
func displayinfo() {
guard let user = Auth.auth().currentUser else {
print("No user info found")
return
}
if let email = user.email {
EmailLabel.text = "Email: \(email)"
//EmailLabel.text = "Email: " + email
}
if let photoURL = user.photoURL {
...
}
// ...
}
Let me know if you have any issue in these solutions.
Apart from this, I would rather write UIViewController in this manner which seems to be a more clearer approach.
class ProfileViewController: UIViewController {
#IBOutlet weak var profiepic: UIImageView!
#IBOutlet weak var lblUsername: UILabel! {
didSet {
lblUsername.layer.borderColor = UIColor.black.cgColor
}
}
#IBOutlet weak var lblEmail: UILabel! {
didSet {
lblEmail.layer.borderColor = UIColor.black.cgColor
}
}
#IBOutlet weak var lblLeague: UILabel! {
didSet {
lblLeague.layer.borderColor = UIColor.black.cgColor
}
}
#IBOutlet weak var btnAchievements: UIButton! {
didSet {
btnAchievements.layer.cornerRadius = 55/2
// For button height, instead of 55 here you can use, btnAchievements.bounds.height / 2 or use constrain also to change button height when bound changes
}
}
#IBOutlet weak var btnReset: UIButton! {
didSet {
btnReset.layer.cornerRadius = 55/2
btnReset.layer.borderColor = UIColor.black.cgColor
}
}
private var currentUser: AuthUser? {// Type of Auth.auth().currentUser
didSet {
// Use above code for displayInfo or simply call displayInfo from here
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.currentUser = Auth.auth().currentUser
}
...
}
I hope this would help you designing other UIViewControllers as well.
I am currently trying to build an app that uses google's autoML feature. I have trained a model and published it on google firebase and have integrated the necessary code into my app following the documentation:
https://firebase.google.com/docs/ml-kit/ios/label-images-with-automl
I am using a remote model instead of making it local. However when I try running the code, then choose an image in the simulator, an empty list of predictions is output in the console.
I have also turned on the debugging feature, but this has not helped me fix my error. This is the code I am running in ViewController:
import UIKit
import CoreML
import Vision
import Firebase
import FirebaseMLCommon
var serverImage: UIImage? = nil
var topResult = ""
class ViewController: UIViewController {
#IBOutlet var skinDiseaseImageView: UIImageView!
#IBOutlet var result1Label: UILabel!
#IBOutlet var result1Confidence: UILabel!
#IBOutlet var result2Label: UILabel!
#IBOutlet var result2Confidence: UILabel!
#IBOutlet var result3Label: UILabel!
#IBOutlet var result3Confidence: UILabel!
override func viewDidLoad() {
let initialConditions = ModelDownloadConditions(allowsCellularAccess: true,
allowsBackgroundDownloading: true)
let updateConditions = ModelDownloadConditions(allowsCellularAccess: false,
allowsBackgroundDownloading: true)
let remoteModel = RemoteModel(
name: "skinDiseaseModel", // The name you assigned in the console.
allowsModelUpdates: true,
initialConditions: initialConditions,
updateConditions: updateConditions
)
ModelManager.modelManager().register(remoteModel)
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension ViewController {
#IBAction func selectImage(_ sender: Any) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .savedPhotosAlbum
present(pickerController, animated: true)
}
}
extension ViewController: UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
dismiss(animated: true)
guard let skinImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Error Retrieving Image Line 95")
}
var skinImageToDiagnose = VisionImage(image: skinImage)
serverImage = skinImage
skinDiseaseImageView.image = skinImage
let labelerOptions = VisionOnDeviceAutoMLImageLabelerOptions(
remoteModelName: "skinDiseaseModel", // Or nil to not use a remote model
localModelName: nil // Or nil to not use a bundled model
)
labelerOptions.confidenceThreshold = 0 // Evaluate your model in the Firebase console
// to determine an appropriate value.
let labeler = Vision.vision().onDeviceAutoMLImageLabeler(options: labelerOptions)
var topThreeResults = [String]()
var topThreeConfidences = [String]()
labeler.process(skinImageToDiagnose) { labels, error in
guard error == nil, let labels = labels
else {
print(error)
return
}
//task succeeded
print("1")
print(labels)
var counter = 0
for label in labels {
topThreeResults.append(String(describing: label))
topThreeConfidences.append(String(describing: label.confidence))
counter = counter + 1
print("counter")
if counter == 3 {
break
}
}
}
result1Label.text = topThreeResults[0]
result1Confidence.text = (topThreeConfidences[0] + "%")
result2Label.text = topThreeResults[1]
result2Confidence.text = (topThreeConfidences[1] + "%")
result3Label.text = topThreeResults[2]
result3Confidence.text = (topThreeConfidences[2] + "%")
}
}
This is the error I recieved:
Fatal error: Index out of range
2019-08-31 19:50:19.763469-0700 medicalAppFinal[13776:2281569] Fatal error: Index out of range
(lldb)
I reasoned that the index out of range problem is due to the list of labels(output predictions) being empty after having printed it. Thus I understand why it is index out of range, but I do not know why I am recieving an empty list after passing in the image into labeler.process() How do I solve this error? Tell me if you need more information
This seems to be duplicate of the following question (which was answered by the author):
Not Retriveing Output Prediction List from Remote Firebase Automl custom model
i am making an app Redmine, i have a website with a user with pass and there are issues. But i can't understand what i should do to make authorization.
Here I have Router, Request, AuthViewController. I also wanted to ask how i have to make AuthRequest? What has to be there?
AuthViewController
import UIKit
class AuthViewController: UIViewController {
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var signInBotton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func signInDidTap(_ sender: Any) {
login()
}
fileprivate func login(){
AuthRequest.login(email: emailField.text!, password: passwordField.text!){(user, error) in DispatchQueue.main.async {
[unowned self] in self.openIssues()
}
}
}
}
//extension AuthViewController: Router{
// func prepare() {
// Here error with 'seque' if(seque.identifier = Seque.issues.rawValue){
// print("It's OK")
// guard let controller = seque.destination as? IssuesViewController else { print("Wrong destination"); return}
// //controller.presenter = IssuesPresenter();
// }
// }
//
// func openIssues() {
// print("kek")
// }
//
//
// enum Seque: String {
// case issues = "IssuesSeque"
// }
//
//}
There is also an error in if-block in extension.
When using a UICollectionView with a lot of cells that have images in it, I'm getting this odd warning in the log whenever an offscreen cell is scrolled to be onscreen:
2015-11-06 15:50:20.777 MyApp[49415:13109991] [/BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreUI_Sim/CoreUI-370.8/Bom/Storage/BOMStorage.c:517] <memory> is not a BOMStorage file
Here's the cell setup:
import UIKit
class FeaturedCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
private var xml: XMLIndexer? = nil
override func awakeFromNib() {
super.awakeFromNib()
// this enables the parallax type look
self.imageView.adjustsImageWhenAncestorFocused = true
self.imageView.clipsToBounds = false
}
func loadImageFromUrlString(str: String) {
if let url = NSURL(string: str) {
if let data = NSData(contentsOfURL: url){
let image = UIImage(data: data)
self.imageView.image = image
self.activityIndicator.stopAnimating();
}
}
}
func setXml(xml: XMLIndexer) {
self.xml = xml;
if let imageUrl: String = (xml["FullAd"].element?.text)! {
self.loadImageFromUrlString(imageUrl)
}
}
}
According to this thread this message is harmless.
My code is randomly generating 2 separate images on the same interface controller. I need to check if the images match each other, but i'm unsure how to go about this as they are being randomly generated. I have tried writing if statements such as:
if blueColour.setBackgroundImageNamed("colour\(randomImage).jpg") == mainBackgroundColour.setBackgroundImageNamed("mainColour\(randomMainBackground).jpg") {
println("they match")
} else {
println("they dont match")
}
but it doesn't seem to work, i get an error saying "binary operator '==' cannot be applied to two Void operands"
My code is below:
#IBOutlet var blueColour: WKInterfaceButton!
#IBOutlet var pinkColour: WKInterfaceButton!
#IBOutlet var greenColour: WKInterfaceButton!
#IBOutlet var yellowColour: WKInterfaceButton!
#IBOutlet var mainBackgroundColour: WKInterfaceGroup!
#IBOutlet var scoreLabel: WKInterfaceLabel!
var randomImage = UInt32()
var randomMainBackground = UInt32()
#IBAction func onePressedTest() {
if blueColour.setBackgroundImageNamed("colour\(randomImage).jpg") == mainBackgroundColour.setBackgroundImageNamed("mainColour\(randomMainBackground).jpg") {
println("they match")
} else {
println("they dont match")
}
randomImage = arc4random_uniform(4)
blueColour.setBackgroundImageNamed("colour\(randomImage).jpg")
randomImage = arc4random_uniform(4)
pinkColour.setBackgroundImageNamed("colour\(randomImage).jpg")
randomImage = arc4random_uniform(4)
greenColour.setBackgroundImageNamed("colour\(randomImage).jpg")
randomImage = arc4random_uniform(4)
yellowColour.setBackgroundImageNamed("colour\(randomImage).jpg")
randomMainBackground = arc4random_uniform(4)
mainBackgroundColour.setBackgroundImageNamed("mainColour\(randomMainBackground).jpg")
}
NEW AMENDED CODE 20.04.2015:
import WatchKit
import Foundation
protocol WKInterfaceComparableImage {
func getImage()->UIImage;
func equalsImage(comparableWKObject:WKInterfaceComparableImage)->Bool;
}
class WKInterfaceButtonComparable : WKInterfaceButton, WKInterfaceComparableImage {
private var image:UIImage?;
override func setBackgroundImage(image: UIImage?) {
self.image = image;
super.setBackgroundImage(image);
}
func equalsImage(comparableWKObject: WKInterfaceComparableImage)->Bool {
return self.image === comparableWKObject.getImage();
}
func getImage() -> UIImage {
return image!;
}
}
class WKInterfaceGroupComparable : WKInterfaceButton, WKInterfaceComparableImage {
private var image:UIImage?;
override func setBackgroundImage(image: UIImage?) {
self.image = image;
super.setBackgroundImage(image);
}
func equalsImage(comparableWKObject: WKInterfaceComparableImage)->Bool {
return self.image === comparableWKObject.getImage();
}
func getImage() -> UIImage {
return image!;
}
}
class ImageProvide {
private let MAX_RANDOM_NUMBER:UInt32 = 4
static let shared:ImageProvide = ImageProvide();
var images:[UIImage];
private init() {
images = [];
for i in 1...MAX_RANDOM_NUMBER {
//get image with the best way to you
images.append(UIImage(named: "colour\(i).jpg")!);
}
}
func getRandomImage()->UIImage {
let randomImage = arc4random_uniform(MAX_RANDOM_NUMBER);
return getImage(id: Int(randomImage));
}
func getImage(#id:Int)->UIImage {
return images[id];
}
}
class InterfaceController: WKInterfaceController {
#IBOutlet var blueColour: WKInterfaceButtonComparable!
#IBOutlet var pinkColour: WKInterfaceButtonComparable!
#IBOutlet var greenColour: WKInterfaceButtonComparable!
#IBOutlet var yellowColour: WKInterfaceButtonComparable!
#IBOutlet var mainBackgroundColour: WKInterfaceGroupComparable!
#IBOutlet var scoreLabel: WKInterfaceLabel!
var randomImage = UInt32()
var randomMainBackground = UInt32()
var score:Int = 1
#IBAction func onePressedTest() {
if blueColour.equalsImage(mainBackgroundColour) || pinkColour.equalsImage(mainBackgroundColour) || greenColour.equalsImage(mainBackgroundColour) || yellowColour.equalsImage(mainBackgroundColour) {
println("they match")
scoreLabel.setText("\(score)")
score++
} else {
println("they dont match")
}
blueColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
pinkColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
greenColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
yellowColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
mainBackgroundColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
I made an example what I think can help you find the way to resolve your issues, I created class custom with comparable power to help your work. I do it very fast, and I don't have way to test for you, but you can see the concept to help you create a solution. I hope so helped you with my example.
ComparableImage is the key to compare, this protocol can do your mission.
WKInterfaceButtonComparable extends WKInterfaceButton and with this you can save the current image to compare after, I did same with WKInterfaceGroupComparable.
ImageProvide is important because this will manage your images, there you need code your logic about images and with this Singleton you can preload your images and send to your WK components. I hope it help too.
protocol WKInterfaceComparableImage {
func getImage()->UIImage;
func equalsImage(comparableWKObject:WKInterfaceComparableImage)->Bool;
}
class WKInterfaceButtonComparable : WKInterfaceButton, WKInterfaceComparableImage {
private var image:UIImage?;
override func setBackgroundImage(image: UIImage?) {
self.image = image;
super.setBackgroundImage(image);
}
func equalsImage(comparableWKObject: WKInterfaceComparableImage)->Bool {
return self.image === comparableWKObject.getImage();
}
func getImage() -> UIImage {
return image!;
}
}
class WKInterfaceGroupComparable : WKInterfaceButton, WKInterfaceComparableImage {
private var image:UIImage?;
override func setBackgroundImage(image: UIImage?) {
self.image = image;
super.setBackgroundImage(image);
}
func equalsImage(comparableWKObject: WKInterfaceComparableImage)->Bool {
return self.image === comparableWKObject.getImage();
}
func getImage() -> UIImage {
return image!;
}
}
class ImageProvide {
private let MAX_RANDOM_NUMBER:UInt32 = 4
static let shared:ImageProvide = ImageProvide();
var images:[UIImage];
private init() {
images = [];
for i in 1...MAX_RANDOM_NUMBER {
//get image with the best way to you
images.append(UIImage(named: "colour\(i).jpg")!);
}
}
func getRandomImage()->UIImage {
let randomImage = arc4random_uniform(MAX_RANDOM_NUMBER);
return getImage(id: Int(randomImage));
}
func getImage(#id:Int)->UIImage {
return images[id];
}
}
class InterfaceController: WKInterfaceController {
#IBOutlet var blueColour: WKInterfaceButtonComparable!
#IBOutlet var pinkColour: WKInterfaceButtonComparable!
#IBOutlet var greenColour: WKInterfaceButtonComparable!
#IBOutlet var yellowColour: WKInterfaceButtonComparable!
#IBOutlet var mainBackgroundColour: WKInterfaceGroupComparable!
#IBOutlet var scoreLabel: WKInterfaceLabel!
var randomImage = UInt32()
var randomMainBackground = UInt32()
var score:Int = 1
#IBAction func onePressedTest() {
if blueColour.equalsImage(mainBackgroundColour) {
println("they match")
} else {
println("they dont match")
}
blueColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
pinkColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
greenColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
yellowColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
mainBackgroundColour.setBackgroundImage(ImageProvide.shared.getRandomImage())
}
}