Swift and Firebase 3.x saving and retrieving data - swift

I'm saving data in one view with the following code:
let item1:String = textfield.text!
if TextField1.text != "" {
self.ref.child("userProfile").child((user!.uid)/value1Total").setValue(Double(item1)!)
}
What would be my code in a different view to set that saved value to a label?

You can try like below example:
let name = nameTextField.text
let user: NSDictionary = ["name":name!,"dob":dateOfBirthTimeInterval]
//add firebase child node
let profile = firebase.ref.childByAppendingPath(name!)
// Write data to Firebase
profile.setValue(user)
Have a look on it this link for more info

Related

Assign username value from firestore

i'm creating my first app (and newbie in swift). When i login from Facebook, the name and email are saved in Firestore. I'm trying to set the name from facebook to a variable to use it in other places, but i can't assign the value, always shows "nil" in the console. Anyone can help me please?
I set the variable
var userN: String?
I get the data from Firestore
func readDatabase(){
let db = Firestore.firestore()
let docRef = db.collection("users").document("email")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Document data: \(dataDescription)")
let data = document.data()
let userName = data!["name"]! as! String
print(userName)
let userEmail = data!["email"]! as! String
print(userEmail)
let containerController = ContainerController()
let containerController.userN = userName;
return
}
}
}
i want to assign userN = userName, to use it in other view
How can i do that? thanks
If you are using StoryBoards you can pass this through the segue function;
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "YourStoryBoardSegue" {
if let viewController = segue.destination as? ContainerController {
viewController.userN = userName
}
}
}
otherwise, best practice would be to use a delegate method.
Search stack overflow for best practices using delegates to pass data.
The question is extremely broad and without knowing details the only way to address it is with a general answer that specifically addresses how to read data from Firestore and save it in a variable to be used later.
Suppose your Firestore looks like this
root
users
uid_0
name: "users name"
uid_1
name: "another users name"
and when the app loads, we want to read the users name and store it in in a variable per your question:
a variable to use it in other places
Here's what that could look like
class ViewController: NSViewController {
var usersName = ""
override func viewDidLoad() {
super.viewDidLoad()
FirebaseApp.configure()
self.db = Firestore.firestore()
let settings = self.db.settings
self.db.settings = settings
self.readUserName()
}
func readUsersName() {
let users = self.db.collection("users")
let thisUser = users.document("uid_1")
thisUser.getDocument(completion: { documentSnapshot, error in
if let error = error {
print(error.localizedDescription)
return
}
let name = documentSnapshot?.get("name") as! String
self.usersName = name
})
}
The code sets up Firestore, reads the user name from the uid_1 document and stores it in a variable where it could be used later.
Suppose we want to let the user change their name. There's 100 ways to do it; passing data via a segue, use a delegate method or open a detail view controller and before it closes, have this master controller read the updated name from a textField and save the data. You could even pass the users uid and then in the detail viewcontroller read the document via that uid and then update it upon closing. However, all of those go beyond the scope of the question.

Load data before views in Swift

I'm trying to load some data via JSON from the web and save it globally to my app.
I have a separate swift file
struct MyAppData {
static var vendorCol = "15"
static var vendorDel = "45"
static var VendorID = "1"
}
Using alomofire i populate it.
Alamofire.request("https://domainname/data.json").responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let json = JSON(responseData.result.value!)
guard let times = json["content"]["clients"].array else {
print("No Data")
return
}
for time in times {
MyAppData.vendorCol = time["col"].string!
MyAppData.vendorDel = time["del"].string!
MyAppData.VendorID = time["id"].string!
}
}
}
This works as expected if I place it on a view controller and use MyAppData.VendorID
My issue is I need a place load the data at a place where it's immediately available to all views and only want to load it once.
I tried in app delegate with no success, the function was called but the data was never updated all over the app. Some labels I set only had the default values from MyAppData.
Any help would be appreciated.

How Save UILocalNotifications in CoreData

Answer is below, image is here:
I was searching how to do this for a couple of days and was only able to find people who stored UILocalNotificaations in NSUserDefaults. Saving these in NSUserDefaults seemed wrong to me because it is supposed to be used for small flags. I just now finally figured out how to store notifications in CoreData. This is Using Xcode 7.3.1 and Swift 2.2
First off you need to create a new entity in your CoreDataModel
and then add a single attribute to it. the attribute should be of type Binary Data I named my table/entity "ManagedFiredNotifications" and my attribute "notification". it should look like this:
Image linked in Question above.
Next you need to add an extension to UILocalNotification it should go like this:
extension UILocalNotification {
func save() -> Bool {
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let firedNotificationEntity = NSEntityDescription.insertNewObjectForEntityForName("ManagedFiredNotifications", inManagedObjectContext: appDelegate!.managedObjectContext)
guard appDelegate != nil else {
return false
}
let data = NSKeyedArchiver.archivedDataWithRootObject(self)
firedNotificationEntity.setValue(data, forKey: "notification")
do {
try appDelegate!.managedObjectContext.save()
return true
} catch {
return false
}
}
}
Now for saving a notification all you need to do is call
UILocalNotification.save()
On the notification you would like to save. my notifications were named 'notification' so I would call notification.save()
To retrieve a notification you need a method like this
func getLocalFiredNotifications() -> [UILocalNotification]? {
let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)!.managedObjectContext
let firedNotificationFetchRequest = NSFetchRequest(entityName: "ManagedFiredNotifications")
firedNotificationFetchRequest.includesPendingChanges = false
do {
let fetchedFiredNotifications = try managedObjectContext.executeFetchRequest(firedNotificationFetchRequest)
guard fetchedFiredNotifications.count > 0 else {
return nil
}
var firedNotificationsToReturn = [UILocalNotification]()
for managedFiredNotification in fetchedFiredNotifications {
let notificationData = managedFiredNotification.valueForKey("notification") as! NSData
let notificationToAdd = NSKeyedUnarchiver.unarchiveObjectWithData(notificationData) as! UILocalNotification
firedNotificationsToReturn.append(notificationToAdd)
}
return firedNotificationsToReturn
} catch {
return nil
}
}
Note that this returns an array of UILocalNotifications.
When retrieving these if you plan on removing a few of them and then storing the list again you should remove them when you get them something like this works:
func loadFiredNotifications() {
let notifications = StudyHelper().getLocalFiredNotifications()
if notifications != nil {
firedNotifications = notifications!
} else {
// throw an error or log it
}
classThatRemoveMethodIsIn().removeFiredLocalNotifications()
}
I hope this helps someone who had the same problems that I did trying to implement this.

JSQMessages send media

Im building a small chat app using JSQMessages, and trying to send images from photo library or camera.
I got to the point where I saved the image to parse backend but I cannot display it on screen. I found few solutions but they were in obj-C, I tried to swift-fy but it failed.
I have extra column in parse "images" next to "message".
Here is what I tried:
var message = messages[indexPath.row]
if message != "" {
return messages[indexPath.row]
} else if message?.isMediaMessage == true {
let mediaItem:JSQMessageMediaData = message!.media
if (mediaItem.isKindOfClass(JSQPhotoMediaItem)) {
var photoItem: JSQPhotoMediaItem = mediaItem as! JSQPhotoMediaItem
var image: UIImage = photoItem.image
print("yay")
}
}
return messages[indexPath.row]
You are not actually setting the message content to the photo that you have saved on the backend. You have a var image: UIImage = photoItem.image that just saves it to a variable not to the message content that is being displayed. Also this does evaluate if (mediaItem.isKindOfClass(JSQPhotoMediaItem)) {
var photoItem: JSQPhotoMediaItem = mediaItem as! JSQPhotoMediaItem
so if set your message.media = (data from parse) it should show up.

Show Image from URL in detailView after selection in tableView

I have a tableView which display a list of traffic-cameras parsed from a XML file. When I select a cell, it sends the ImageURL, Roadname, Coordinates etc. via the prepareForSegue method.
In my detailviewcontroller I declare the incoming values as the following:
var selectedFeedURL = String()
var selectedFeedRoadname = String()
var selectedFeedLongitude = String()
var selectedFeedLatitude = String()
I have no problem printing all the values into the log or set it as labels. The problem occurs when I try to load the selectedFeedURL (which is the URL to the image, i.e: http://webkamera.vegvesen.no/kamera?id=559847) and set it to my imageView..
In my viewDidLoad, I have the following code, which should download the image and set it to my imageView named cameraImageView.
if let url = NSURL(string:"\(selectedFeedURL)") {
if let data = NSData(contentsOfURL: url){
print("Suksess")
cameraImageView.image = UIImage(data: data)
}
}
My imageView stays empty and I doesn't get any errors or complains in the debug area. If I print out the selectedFeedURL, the link is there.
The weird part is that if I change
NSURL(string:"\(selectedFeedURL)")
to
NSURL(string:"http://webkamera.vegvesen.no/kamera?id=559847")
Basically changing the variable to a camera URL, it works perfectly.
Soo... any suggestions on what the problem might be?
Much appreciated :)
If there are white spaces and newline characters at the start and end of your URL string, it won't work.
Try:
selectedFeedURL = selectedFeedURL.stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())
if let url = NSURL(string: selectedFeedURL) {
if let data = NSData(contentsOfURL: url){
print("Suksess")
cameraImageView.image = UIImage(data: data)
}
}