I'm trying to pick an image and convert it to a string to save into the model var picture = "". I can select the image but it's not displaying any suggestions on my error will help.
UPDATE: I figured it out with these changes and still used a string for the model.
var imagePath = ""
var profilePic: UIImage?
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let referenceUrl = info[UIImagePickerControllerReferenceURL] as? URL, let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
ALAssetsLibrary().asset(for: referenceUrl, resultBlock: { asset in
let fileName = asset?.defaultRepresentation().filename()
let userModel = User()
userModel.picture = fileName!
let filePath = "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/\(String(describing: fileName))"
self.imagePath = filePath
let imageData : NSData = UIImagePNGRepresentation(pickedImage)! as NSData
imageData.write(toFile: filePath, atomically: true)
UserDefaults.standard.set(imageData, forKey: "profileImage")
UserDefaults.standard.synchronize()
self.profilePic = pickedImage
self.tableView.reloadData()
}, failureBlock: nil)
}
dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case Setting.preferences.rawValue:
guard let cell = tableView.dequeueReusableCell(withIdentifier: PreferencesTableViewCell.identifier,
for: indexPath) as? PreferencesTableViewCell else { return UITableViewCell() }
cell.addressTextfield.delegate = self
cell.cityTextField.delegate = self
cell.stateTextField.delegate = self
cell.zipcodeTextField.delegate = self
return cell
case Setting.personal.rawValue:
guard let cell = tableView.dequeueReusableCell(withIdentifier: PersonalTableViewCell.identifier,
for: indexPath) as? PersonalTableViewCell else { return UITableViewCell() }
cell.firstNameTextField.delegate = self
cell.lastNameTextField.delegate = self
cell.phoneNumberTextField.delegate = self
cell.emailTextField.delegate = self
cell.buttonTouchedClosure = { [weak self] in
self?.pickImage()
}
return cell
case Setting.notifications.rawValue:
guard let cell = tableView.dequeueReusableCell(withIdentifier: NotificationsTableViewCell.identifier,
for: indexPath) as? NotificationsTableViewCell else { return UITableViewCell() }
return cell
case Setting.social.rawValue:
guard let cell = tableView.dequeueReusableCell(withIdentifier: SocialTableViewCell.identifier,
for: indexPath) as? SocialTableViewCell else { return UITableViewCell() }
cell.logoutButton.addTarget(self, action: #selector(UserProfileTableViewController.logout), for: .touchUpInside)
return cell
default: return UITableViewCell()
}
}
Related
Please help me. Explain how to set the image in the cell. In my Database I have: title, description and imageURL (url from Firebase Storage). Can you write me a code and explain.
class TrainingProgram
{
var description = ""
var title = ""
var imageURL = ""
init(description: String, title: String, imageURL: String) {
self.description = description
self.title = title
self.imageURL = imageURL
}
function to get data from firebase.
func fetchPrograms() {
Database.database().reference().child("programs").observe(.childAdded) { (snapshot) in
if let dict = snapshot.value as? [String: AnyObject] {
let newTitle = dict["title"] as! String
let newDescription = dict["description"] as! String
let newImageURL = dict["imageURL"] as! String
let trainingCell = TrainingProgram(description: newDescription, title: newTitle, imageURL: newImageURL)
self.trainingPrograms.append(trainingCell)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
}
And this is how I set title and description to my cells.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TrainingProgramCollectionViewCell", for: indexPath) as! TrainingProgramCollectionViewCell
//cell.featuredImageView.setImage(from: indexPath.item)
cell.titleLabel.text = trainingPrograms[indexPath.item].title
cell.descriptionLabel.text = trainingPrograms[indexPath.item].description
What I need to write in the function for receiving data to get images and how to set images in cells
Install SDWebImage pod from this link https://github.com/SDWebImage
And in Your CollectioView cellForRow method
var images_list = [String]()
var imagesArray = [URL]()
images_list.append(itemModel[indexPath.row]. imageURL)
let storage = Storage.storage().reference()
for x in images_list{
print(x)
let storageRef = storage.child("images/\(x).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
imagesArray.append(url!)
}
if let x = images_list.last{
cell.itemImage.sd_setImage(with: URL(string: x), placeholderImage: UIImage(named: "default"))
}
}
}
Full code
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TrainingProgramCollectionViewCell", for: indexPath) as! TrainingProgramCollectionViewCell
//cell.featuredImageView.setImage(from: indexPath.item)
cell.titleLabel.text = trainingPrograms[indexPath.item].title
cell.descriptionLabel.text = trainingPrograms[indexPath.item].description
var images_list = [String]()
var imagesArray = [URL]()
for x in images_list{
print(x)
let storageRef = storage.child("images/\(x).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
imagesArray.append(url!)
}
if let x = images_list.last{
cell.itemImage.sd_setImage(with: URL(string: x), placeholderImage: UIImage(named: "default"))
}
}
}
}
Try this for single image downloadJust take your imageUrl from firebase
let x: String = "yourImageUrl"
let storageRef = storage.child("images/\(x).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
imagesArray.append(url!)
}
if let x = images_list.last{
cell.itemImage.sd_setImage(with: URL(string: x), placeholderImage: UIImage(named: "default"))
}
}
I've a problem after load data from firebase, when i call the reload data, the table view populate with new list data but are all white and if I click I can get the data value correctly.
If I use static data all works fine.
Any suggestion? thanks!
private func loadUniversity(url: String) {
let configuration = URLSessionConfiguration.ephemeral
let session = URLSession(configuration: configuration)
let url = URL(string: url)!
let task = session.dataTask(with: url) {
(data, response, error) in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let data = data else {
return
}
do {
let decoder = JSONDecoder()
let university = try decoder.decode([UniversityJSON].self, from: data)
for item in university {
self.universityArray.append(University(name: item.university_name.trim()))
}
let queue = OperationQueue.main
queue.addOperation {
self.currentUniversityArray = self.universityArray
print(self.currentUniversityArray)
self.table.reloadData()
}
} catch {
print("Error info: \(error)")
}
}
task.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? UniversityCell else {
return UITableViewCell()
}
cell.name.text = currentUniversityArray[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? UniversityCell else {
return UITableViewCell()
}
cell.name.text = currentUniversityArray[indexPath.row].name
// Put this background Color
cell.backgroundColor = .clear
return cell
}
User upload image to firebase storage and the url string is added to the firebase database,
How can I take the string in the firebase database and convert it to uiimage to use it as an image ?
The string returned from database is like this:
https://firebasestorage.googleapis.com/v0/b/ichatmessage.appspot.com/o/YNoodTnOSGXl6HkPoqhOPAopb8v1?alt=media&token=738771a5-53e3-46c2-b508-ad5cfa03e74e
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let currentID = Auth.auth().currentUser?.uid
let databaseRef = Database.database().reference().child("users").child(currentID!)
databaseRef.observe(.value) { (data) in
let dictinoray = data.value as? [String: AnyObject]
let profileImage = dictinoray!["profileimage"] as! String
cell.imageView?.image = profileImage.toImage()
print(profileImage)
}
return cell
}
extention
extension String {
func toImage() -> UIImage? {
if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters){
return UIImage(data: data)
}
return nil
}
}
I used other way by mapping and using storage downloadurl and it worked
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let storageref = Storage.storage().reference().child(user.userid)
storageref.downloadURL { (imgurl, er) in
let imagedata = try? Data.init(contentsOf: imgurl!)
cell.imageView?.layer.cornerRadius = (cell.imageView?.frame.size.width)!/2
cell.imageView?.image = UIImage.init(data: imagedata!)
}
Another option would be to load and cache the image through Kingfisher. It's how I would usually load images within a tableView that's from an API.
import Kingfisher above your class.
Then in your cellForRowAtIndexPath, set the image with Kingfisher.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let currentID = Auth.auth().currentUser?.uid
let databaseRef = Database.database().reference().child("users").child(currentID!)
databaseRef.observe(.value) { (data) in
let dictinoray = data.value as? [String: AnyObject]
let profileImage = dictinoray!["profileimage"] as! String
cell.imageView?.kf.setImage(with: URL(string: profileImage))
}
return cell
}
Not sure if you were looking for an alternative but that's another way to do it.
Here I load my images, I want to stop the images from loading when I click on the path. How can this be done? I tried setting the URL to nil but that didn't work.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? CustomCell
let pintrestsUrl = pintrest[indexPath.row].urls?.thumb
Library().parseImages(ImagesUrlArrayPath: pintrestsUrl!, completion: { (image) -> Void in
if let imageFromCache = imageCache.object(forKey: pintrestsUrl as AnyObject ) as? UIImage {
cell?.ImageView.image = imageFromCache
}
})
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// stop images from loading
}
EDIT -- added ParseImages Function
func parseImages(ImagesUrlArrayPath: String, completion: #escaping (UIImage)-> Void) {
if let imageFromCache = imageCache.object(forKey: ImagesUrlArrayPath as AnyObject ) as? UIImage {
completion(imageFromCache)
}
else
{
if let imageURL = URL(string: (ImagesUrlArrayPath)){
DispatchQueue.global().async{
let data = try? Data(contentsOf: imageURL)
if let data = data{
let imageToCache = UIImage(data: data)
// let image = imageToCache
DispatchQueue.main.async {
imageCache.setObject(imageToCache!, forKey: ImagesUrlArrayPath as AnyObject)
completion(imageToCache!)
print("sucess")
//cell?.videoImageView.image = image //?.resizeImage(targetSize: size)
}
}
}
}
}
}
Solved this awhile back
You have to set the images to nil before loading new images on them
This is my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "news", for: indexPath)
let lebel = cell.viewWithTag(1) as! UILabel
let lebel1 = cell.viewWithTag(2) as! UILabel
lebel.text = self.titlename[indexPath.row]
lebel1.text = self.content[indexPath.row]
var image: UIImage?
if let imageURL = URL(string:self.picture[indexPath.row] ) {
do {
let imageData = try Data(contentsOf:imageURL as URL)
image = UIImage(data:imageData as Data)
} catch {
print("error")
}
}
if image != nil {
cell.imageView?.image = image
}else{
cell.imageView?.image = nil
//cell.imageView?.image = UIImage(named: "failed")
}
return cell
}
self.picture is a String array. When I make a network request, the URL I want to connect to is https://localhost:8443/news/p0.jpg. I get this error:
2017-01-11 10:11:28.888 pro[19800:2397129] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)error
But I have been using Alamofire to connect to https in other places has been very successful. What is wrong with it?
OK,I try to use URL and Data,But this has nothing to do with the error
OK,it is done! because I use Alamofire to manager the connection, so I must use alamofire to fetch the image data. Rather than the original method!!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "news", for: indexPath)
let lebel = cell.viewWithTag(1) as! UILabel
let lebel1 = cell.viewWithTag(2) as! UILabel
let pict = cell.viewWithTag(3) as! UIImageView
lebel.text = self.titlename[indexPath.row]
lebel1.text = self.content[indexPath.row]
if let imageURL = URL(string:self.picture[indexPath.row]) {
Alamofire.request(imageURL, method: .get).responseData { response in
guard let data = response.result.value else {
pict.image = nil
//cell.imageView?.image = UIImage(named: "failed")
return
}
pict.image = UIImage(data: data)
}
}
return cell
}
But so much thanks!