I'm new to Swift developing. I made tableView with 16 rows - there are names and prices of every items.
When the user clicks on a row, a new tableView (with static cell) is shown. The user can edit price (I only need price to be mutable) and save it. Then, the original tableView with the new price is shown.
BUT when I stop and load app again there is the original prices.
I found out that I have to use Core Data to storage data permanently. BUT I need the database to be filled with these 16 rows (with the first load after installing) and then let user to change price permanently (or until change it again).
It is possible? And how? Should I use Core Data or is there an easier option?
Pretty much everything suggested to you so far is more complex than it needs to be. You're talking about local data, and a very small amount of it.
The simplest option is to use a plist.
Xcode can help if you create a new file, select Resource as the type and then Property List. Once created it'll contain a dictionary by default, but you can convert that to an array. Add your data, so you have an array of dictionaries with your values for price etc.
Now, this file will be part of the bundle when you run the app, so you can't edit it. You should copy the file by finding it with NSBundle and copying it with NSFileManager into the documents folder.
Once it's there you can use NSArray init?(contentsOfFile path: String) to load the data. Use mutableCopy to create a version you can edit. You can use this array to drive your table view and you can edit the values it contains. Note that with this simple technique the dictionaries in the array will be immutable, so you're probably better off using NSPropertyListSerialization class func propertyListWithData(_ data: NSData, options opt: NSPropertyListReadOptions, format format: UnsafeMutablePointer<NSPropertyListFormat>) throws -> AnyObject with an option of MutableContainersAndLeaves instead.
Once you've edited the array contents you can write it back to disk for next run (with class func dataWithPropertyList(_ plist: AnyObject, format format: NSPropertyListFormat, options opt: NSPropertyListWriteOptions) throws -> NSData)
Related
Firebase Database
I tried using this bit of code but it doesn't seem to work. I take the name the user selects and store it in nameList.
Lets say I store Blake Wodruff in nameList[0].
How do I remove only that name?
var nameList = [String](repeating: "", count:100)
func remove() {
print(nameList[countAddNames])
let usernameRef = Database.database().reference().child("Candidate 1").child("alton").child(nameList[countAddNames]);
usernameRef.removeValue();
}
To write to or delete a node, you must specify its entire path. So to delete node 0 from your JSON, you'd do:
let usernameRef = Database.database().reference().child("Candidate 1").child("alton").child("0");
usernameRef.removeValue();
Or a bit shorter:
let usernameRef = Database.database().reference().child("Candidate 1/alton/0");
usernameRef.removeValue();
If you only know the name of the user you want to remove, you'll need to first look up its index/full path before you can remove it. If you have the data in your application already, you can do it in that code. Otherwise you may have to use a database query (specifically .queryOrderedByValue and .queryEqualToValue) to determine where the value exists in the database.
Also see: Delete a specific child node in Firebase swift
Once you remove a value from your JSON structure, Firebase may no longer recognize it as an array. For this reason it is highly recommended to not use arrays for the structure that you have. In fact, I'd model your data as a set, which in JSON would look like:
"alton": {
"Jake Jugg": true,
"Blake Wodruff": true,
"Alissa Sanchez": true
}
This would automatically:
Prevent duplicates, as each name can by definition only appear once.
Make removing a candidate by their name as easy as Database.database().reference().child("Candidate 1/alton/Jake Jugg").removeValue()
For more on this, also see my answer to Firebase query if child of child contains a value
I'm trying to create a game and need to be able to save a number and retrieve it. I've found another tutorial on this but it is outdated and kept giving errors:
//To save highest score
var highestScore:Int = 20
NSUserDefaults.standardUserDefaults().setObject(highestScore,
forKey:"HighestScore")
NSUserDefaults.standardUserDefaults().synchronize()
//To get the saved score
var savedScore: Int =
NSUserDefaults.standardUserDefaults().objectForKey("HighestScore") as Int
println(savedScore)
More Details: It's to save a highscore if that helps (which I don't think it does).
Any help is welcome, Thanks.
NSUserDefaults.standardUserDefaults().setInteger(20, forKey: "HighestScore")
let valueOrZeroIfNotSet = NSUserDefaults.standardUserDefaults().integerForKey("HighestScore")
NSUserdefaults are a really useful tool, you can permenantly create mutable variables that can be read and written anywhere and anytime. Heres a brief explanation of how to use them.
let saves = NSUserdefaults.standardUserDefaults()
You need to declare a NSUserdefaults to begin, now this is where you will be storing data. Imagine it as a Bookshelf, right now its empty but you can fill it with all forms of information.
Now that we have our 'Bookshelf', we can start filling it with Books, these books can be everything such as Integers, and Strings.
If we want to store my name (Peter) in a 'book' on the shelf, we would first have to create the book and give it a name. The name of the book is called the "key". The key has to be a unique String. Because Im storing my name the key will be "myName". Now we know our key to write to, now lets fill the book with information (Which is my name).
saves.setString("Peter", forKey: "myName")
Now we've made a book in our bookshelf that stores our name.
We will probably want to read this information just in case we need it! We can access books from our bookshelf easily with:
saves.stringForKey("myName")
Now we did need the key (the books name) so we could find the right book of information.
Thats pretty much it for NSUserdefaults for you.
So I am really new to parse and I have no idea how to store a famous quote and it's own author, so then I can use that information in my iOS app made with swift.
I have imported all the frameworks in order to make parse work but I don't know to to store that quotes with the authors and then retrieve the information to display the quote in a label and the author in another label. Please don't be rude, I don't get who to make this work.
So if you want to save a text and retrieve to Parse
let's say you want to save some text into a class called Data
Save
var data = "Swift is nice"
var object = PFObject(className:"Data")
object["message"] = data
object.saveInBackground()
So I use the saveInBackground method just for simplicity however if you should other saveInBackground method where you could check if there is no error while you are saving into Parse.
Retrieve
#IBOutlet weak var textlabel:UILabel!
var query = PFQuery(className:"Data")
query.getFirstObjectInBackgroundWithBlock({ (objects:PFObject?, error:NSError?) -> Void in
if error == nil {
let retrieveData = objects?.objectForKey("message") as! String
//so lets say you had a UILAbel
self.textlabel.text = retrieveData
}
})
I used the getFirstObjectInBackgroundWithBlock method because I assume that I have at least one object save in Parse. So if you are retrieve a lot of data you could findObjects method .
Hope that helps :)
To answer your comment on Lamars's fine answer:
Create a class ("Add class") "Quotes" in Parse, if you haven't already. Create a column in that class named "Quote", set it's type to String. Click "Add Row" and you will get a new row in your table. Double Click it's field and you can write your quote there.
This is me editing the usernameField in my Parse Class:
You could have another column named "Author" of type String, and just do the same thing, but if your app gets more advanced and you would like to display all the quotes from a specific author, you should add another class, named "Author". Add a column named "Name", double click and submit your name.
In your "Quotes" class, add a column named "Author", type Pointer, and make it point to your Author Class. Then copy the correct objectId from Pointer (let's sat Steve Jobs has objectId "12345678") and paste it to the "Author" column in Quotes. Now, if there's another quote by Steve Jobs, you can re-use that objectId, not having to store the name "Steve Jobs" more than once.
I understand you're new to Parse.com and maybe databases as well, but this way of creating relations is very good knowledge, if you want to design stuff in the future.
Parse has a great documentation, in Obj-C and Swift, check it out:
https://www.parse.com/docs/ios/guide
I've created three PHCollections within my app. In a different part of my app, I'm attempting to fetch them and display them in a table view. I can get all of the user created libraries by using the following code
let topLevelUserCollections: PHFetchResult = PHCollectionList.fetchTopLevelUserCollectionsWithOptions(nil)
self.collectionsFetchResults = [topLevelUserCollections];
self.collectionsLocalizedTitles = ["My Clips"];
PHPhotoLibrary.sharedPhotoLibrary().registerChangeObserver(self) //With this you need to conform to PHPhotoLibraryChangeObserver
but how can I fetch only the asset collection I want? Also, I only want video and not images, is there a way to fetch only results with videos assests?
You are calling PHCollectionList.fetchTopLevelUserCollectionsWithOptions with a parameter of nil. But that nil is the PHFetchOptions. Those PHFetchOptions are exactly how you make this sort of specification.
In particular, if you created these collections yourself, you have their localIdentifier values. That is exactly what you would specify in the PHFetchOptions predicate to pull out those collections. You could also do it by localizedTitle and so on.
I am reading in a pList file that I created. It has a list of categories in it and it reads in each one and creates a button to represent that category. The names are:
cHelp, cFun, cReading-Class
I would prefer that the order in the plist file is kept. But instead I get cReading-Class first, cHelp second, and cFun last.
In the file they are listed has cHelp, cFun, cReading-Class.
Why does this happen? Is there a way to control the order? Modifing the order in the plist doesn't help.
Thanks for any and all help.
Are you talking about you have a plist file that contains a dictionary of category (which itself is a dictionary)? If it is a dictionary, it should have no order, if it is an NSArray, there should have an order. Double check for that