save data depending on passed value in swift - ios

I'm trying to save time taken to complete each level. so im looking for a better way to save data, i have 100 variables for all levels i.e, leveltime1, levetime2....and so on..leveltime100
I have this code which is not working
var leveltime : [Int] = [leveltime1, levetime2, leveltime3......leveltime100]
defaults.setInteger("leveltime[Currentlevel -1]")
leveltime[Currentlevel -1] = defaults.integerForKey("leveltime[Currentlevel -1]")
so this is not working. is there any other way ? other than if else and switch statement?

lets assume you are in level 3 and want to save the time you needed
var level = 3
var time = 21
now you want to safe this to your defaults, for this you generate a key (string)
var key = "leveltime-\(level)"
and store the time
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(time,key)
done.
to retrieve this at some point in time
var level = 3
var key = "leveltime-\(level)"
var defaults = NSUserDefaults.standardUserDefaults()
var time = defaults.integerForKey(key)

Related

How to append an array to an array at current index?

I have an array myarray and I am using a for loop to get a few information which I add to myarray. But next time the for-loop runs, I don't want to create a separate index, but instead the 2nd time and so on, I want to append the information to myarray[0].
How do I do that?
var myarray = [String]()
for var j in 0 < 12 {
// do some stuff
for var i in 0 ..< 10 {
let parta = json?["users"][j]["name"].string
let partb = json?["users"][j]["Lname"].string
let partc = json?["users"][j]["dob"].string
myarray.append("\(parta)-\(partb)-\(partc)---")
// Here when the for loop comes back again (i = 1) , i dont want to make
// myarray[1] , but instead i want myarray[0] ,
// having value like [parta-partb-partc--parta-partb-partc]
}
}
Basically what I am trying to do is, append the new name/lname/dob values at myarray[0] without affecting the current value/string at myarray[0].
You can insert single element and also add array as below.
Swift 5
var myarray = [String]()
myarray.insert("NewElement", at: 0)
myarray.insert(contentsOf: ["First", "Second", "Third"], at: 0)
If I understand your question correctly, you want to create one long string and add the new data always at the beginning of the string. One way to do that would be:
// Store somewhere
var myString = String()
for var i in(0..<10) {
let parta = json?["name"].string
let partb = json?["Lname"].string
let partc = json?["dob"].string
let newString = "\(parta)-\(partb)-\(partc)---")
newString.append(myString)
myString = newString
// Here when the for loop comes back again (i = 1) , i dont want to make
//myarray[1] , but instead i want myarray[0] ,
//having value like [parta-partb-partc--parta-partb-partc]
}

Save multiple data with a loop in FirebaseDatabase - Swift IOS

with my code I would save multiple data with a loop in my Firebase Database. I have used a while loop to save some strings in my Database but my app saves only the last book and I don't know how to fix this problem. Any ideas?
let refUsers = FIRDatabase.database().reference().child("Users").child("User" + tag_login).child(user_key).child("Books").child("Others")
let key = refUsers.childByAutoId().key
let multipleBooksValues = ["multipleBooks": "Yes", "read": "Yes"] as NSDictionary
refUsers.child(key).setValue(multipleBooksValues)
let refBooks = FIRDatabase.database().reference().child("Books").child("User's books").child(book_key)
var bookNumber = 0
let numberOfBooks = bookList.count
while bookNumber < numberOfBooks {
let book = bookList[bookNumber]
let values = ["book_key\(bookNumber)" : book.book_key!] as NSDictionary
refUsers.child(key).child("multipleBooksNumber").setValue(values)
refBooks.updateChildValues(["onGoingNegotiations" : "Yes", "other_user_key" : self.user_key, "other_tag_login": self.tag_login])
refUsers.child(key).child("multipleBooksNumber").observe(.value, with: { (snapshot) in
let numberChildren = Int(snapshot.childrenCount - 1)
if numberChildren == bookNumber{
bookNumber += 1
}
})
}
Thank you in advance.
Each next book in your loop is overwriting the previous book. The easiest way to prevent this is to call setValue() one level deeper in the tree:
while bookNumber < numberOfBooks {
let book = bookList[bookNumber]
refUsers.child(key).child("multipleBooksNumber/\(bookNumber)").setValue(book.book_key!)
}
Note though that the Firebase documentation and blog recommend against using arrays like this for storing data. Either store the books under their natural key:
refUsers.child(key).child("multipleBooksNumber/\(book.book_key!)").setValue(true)
Or store them under so-called push IDs:
refUsers.child(key).child("multipleBooksNumber").childByAutoId().setValue(book.book_key!);
Maybe the problem is that you save all books to the same path and they are being re-written one by another all the time, so only the last one is being saved in the end?
You specify your key once
let key = refUsers.childByAutoId().key
and then save all values to path
refUsers.child(key).child("multipleBooksNumber").setValue(values)

How to sort NSmutableArray from one of it indexes (lat lng coordinates) in Swift

I'm new in swift and I'd know how to do that in php, but I'm lost with all those dictionaries and I have no idea how to do that in swift 2. I've been googling for a while and didn't found what I need.
I'm parsing a jSon and storing it's values in an NSMutableDictionary in a loop and at the end of the loop I store the NSMutableDictionary in an NSMutableArray, so at the end I have an NSMutableArray with 43 elements, and each element have about 10 keys with their values. I need to sort those 43 elements from their "distance" key and sort them descending. I don't know if that is posible with this current approach. The value of the key "distance" is an int number (meters). I don't know if to use an NSMutableDictionary inside an NSMutable Array is the correct approach to do this but I'm using it because it is possible to have string keys, and not numbers indexes, so for me it's easier to access the key "distance" than the index 8...
First I load the jSon content:
private func parseJson(json : NSMutableArray, tableView : UITableView){
var c : Int = 0
for j in json {
var jsonValues = NSMutableDictionary()
//Create main value
guard let value = j.valueForKey("value")?.valueForKey("value")! else{
continue
}
//Get name
guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
continue
}
jsonValues["name"] = Name
//more code like this....
TableData.append(Name)
nsDict.insertObject(jsonValues, atIndex: c)
c += 1
}
this is my NSMutableArray content after being loaded:
And this is the code I have this far. Im trying to load the sorted content in a new array, but in this new array some keys are missing.
//Reorder Array by shop distance from user...
var sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "distance", ascending: true)
var sortedArray : NSArray = nsDict.sortedArrayUsingDescriptors([sortDescriptor])//Crashes
print(sortedArray)
I've managed to sort the array with this technique:
created a new class with for my array
import Foundation
class JsonArrayValues {
init(){
}
var name = String()
var distance = Float()
var lat = Float()
var lng = Float()
var openingTime = String()
var country = String()
var code = String()
var address = String()
var categories = String()
var city = String()
var type = String()
var brands = String()
}
I instantiated one before the loop:
var jsonArrData : [JsonArrayValues] = []
And another one inside the loop, in which I've added the values:
var c : Int = 0
for j in json {
var jsonValues : JsonArrayValues = JsonArrayValues()
//Get name
guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
continue
}
jsonValues.name = Name
//more code...
jsonArrData.append(jsonValues)
c += 1
}
And finally I've been able to call the function to reorder the array:
//Reorder Array by shop distance from user...
jsonArrData.sortInPlace({$0.distance < $1.distance})
One of your first steps in any non-trivial project really should be to spend some time looking around on github for tools that simplify your problem. In this case, you'd find there are so very many tools to simplify working with JSON in Swift. I'd suggest you look at EVReflection and Gloss particularly, although there are also many people who use SwiftyJSON.
You don't mention how you're accessing the network; you could look at AFNetworking or Alamofire. The latter also has AlamofireJsonToObjects to help.
I also found JSONExport to be incredibly useful.
You'd be spending a lot less time futzing with details as in this unfortunate question and more getting on with your larger goal.

Longitude is always zero in image meta data

I am taking a photo using a MediaPicker in Xamarin. I start the geolocation service and then once the picture is taken I send the byte array of the image and the position information to my own platform specific implementation to add the position information in the meta data of the image.
I then save the image as a file and then email it to myself so I can open it in an external application (Picasa) to ensure the GPS information has been stored properly.
The problem I am running into is that the Latitude and Altitude show up fine, but the Longitude is always zero. I have put break points in my app and verified that the meta data is set properly and that all the information has valid values. I am at a loss at what is going on here.
Some of the following code may be redundant or inefficient simply because I have been testing different methods of adding the meta data. I am using the following code in my application in iOS implementation of this meta data adding method:
public byte[] AddPositionInformation(byte[] bytes, SaleScribe.PCL.Services.Geolocation.Position position)
{
var data = NSData.FromArray(bytes);
UIKit.UIImage original = UIKit.UIImage.LoadFromData(data);
CGImageSource myImageSource = CGImageSource.FromData(original.AsJPEG());
var options = new CGImageDestinationOptions();
options.GpsDictionary = new CoreGraphics.CGImagePropertiesGps();
options.GpsDictionary.Latitude = (float)position.Latitude;
options.GpsDictionary.Longitude = (float)position.Longitude;
options.GpsDictionary.Altitude = (int)position.Altitude;
NSMutableData mutableData = new NSMutableData();
using(var dest = CGImageDestination.Create(mutableData, myImageSource.TypeIdentifier, 1, new CGImageDestinationOptions()))
{
dest.AddImage(myImageSource, (int)(myImageSource.ImageCount - 1), options);
dest.Close();
}
return (mutableData as NSData).ToArray();
}
In the function that receives this byte array I am simply writing the byte array directly to a file.
Any help would be very much appreciated.
Thanks!
For anyone who may interested I had to use another method to get this to work, but the underlying problem was that the GPS Lat and Long require a uint so the -94.xxx longitude was invalid. I needed to add the absolute value of the lat and long and then add the appropriate ref value based on the original signed value.
Here is the code that worked for me:
public byte[] AddPositionInformation(byte[] bytes, SaleScribe.PCL.Services.Geolocation.Position position)
{
var data = NSData.FromArray(bytes);
CGImageSource myImageSource = CGImageSource.FromData(data);
var ns = new NSDictionary();
var imageProperties = myImageSource.CopyProperties(ns, 0);
var gps = new NSMutableDictionary();
gps.SetValueForKey(NSObject.FromObject(System.Math.Abs(position.Latitude)), CGImageProperties.GPSLatitude);
gps.SetValueForKey(NSObject.FromObject(new NSString(position.Latitude < 0 ? "S" : "N")), CGImageProperties.GPSLatitudeRef);
gps.SetValueForKey(NSObject.FromObject(System.Math.Abs(position.Longitude)), CGImageProperties.GPSLongitude);
gps.SetValueForKey(NSObject.FromObject(new NSString(position.Longitude < 0 ? "W" : "E")), CGImageProperties.GPSLongitudeRef);
gps.SetValueForKey(NSObject.FromObject(position.Altitude), CGImageProperties.GPSAltitude);
gps.SetValueForKey(NSObject.FromObject(position.Altitude < 0 ? 1 : 0), CGImageProperties.GPSAltitudeRef);
var mutableDictionary = imageProperties.MutableCopy();
mutableDictionary.SetValueForKey(gps, CGImageProperties.GPSDictionary);
NSMutableData mutableData = new NSMutableData();
var dest = CGImageDestination.Create(mutableData, myImageSource.TypeIdentifier, 1);
dest.AddImage(myImageSource, 0, mutableDictionary as NSDictionary);
dest.Close();
return mutableData.ToArray();
}

How to add elements to an array of custom objects in Swift

I am using this code to add custom objects to an array and then display that data in a custom TableView.
var tempCount = self.people?.count
for var k = 0 ; k < tempCount ; k++
{
if let PERSON = self.people?[k]
{
let name = (PERSON.compositeName != nil) ? PERSON.compositeName : ""
let number = (PERSON.phoneNumbers?.first?.value != nil) ? PERSON.phoneNumbers?.first?.value : ""
let image = (PERSON.image != nil) ? PERSON.image : UIImage(named: "aks.jpg")
let details = Contact(userImage: image!, userName: name!, phoneNumber: number!)
println(details.userName + " " + details.phoneNumber)
self.arrayOfContacts?.append(details)
println(self.arrayOfContacts?.count)
}
}
The count of the elements in the array always seems to be 'nil' for some reason. I have declared the array in the following manner
var arrayOfContacts:[Contact]?
, Contact being the type of Object that array is supposed to contain.
and the other one as
var people : [SwiftAddressBookPerson]? = []
The print statement does give out results but the object never gets added into the array.
Any idea about what I am doing wrong would be greatly helpful.
Your array is declared as an Optional array but is not created so it's nil.
Your declaration:
var arrayOfContacts:[Contact]?
Add the creation of an actual empty array:
arrayOfContacts = []
Or create it at once altogether:
var arrayOfContacts:[Contact]? = []
Your arrayOfContacts is nil, so arrayOfContacts?.count is nil as well.
If you really want to append to arrayOfContacts, don't write self.arrayOfContacts?.append(details) because this means "append to arrayOfContacts but actually I don't really care and if arrayOfContacts is nil, just give up".
Instead, write self.arrayOfContacts!.append(details), because now this means "append to arrayOfContacts, and since I really do care, tell me hard and loud, with a fatal crashing error, when arrayOfContacts is nil because well I'll have to figure out why on hell this array is nil when it should not be. I mean, I'm the master of the machine, not the opposite, and I know quite well that arrayOfContacts ought to be not nil when I want to append to it."
Often when you’re dealing with data you don’t just have a fixed amount of elements. Take for example a program where you compute the average of multiple grades in a class:
var grade1 = 4
var grade2 = 3
var average = Double(grade1 + grade2) / 2.0
println("Average grade: \(average)")
What if we wanted the program to also work when we have 3 grades?
We’d have to change our program to work with 3 grades.
var grade1 = 4
var grade2 = 3
var grade3 = 5
var average = Double(grade1 + grade2 + grade3) / 3.0
println("Average grade: \(average\)")

Resources