Signal SIGABRT in Swift using NSuserdefaults - xcode

I'm building a swift game and a need to set up a class. My code works for all the elements in my class, but not for this.
func saveInformationMember(){
var MembersDefaultName = NSUserDefaults.standardUserDefaults()
MembersDefaultName.setValue(globalCurrentMembers, forKey: "globalCurrentMembersData")
MembersDefaultName.synchronize()
}
GlobalCurrentMembers is an array of Member which looks like that:
class Member {
var image = String ()
var name = String ()
var progression = Int()
var round = Int()
var level = Int()
var imageProgression = [UIButton]()
func Init(){
image = "default.png"
name = "default"
progression = 0
round = 0
level = 0
}

To save your class this way, Member needs to conform to the NSCoding protocol.

Thx to Aaron Brager for is response. This is the response :
func saveInformationMember(){
let data = NSKeyedArchiver.archivedDataWithRootObject(globalCurrentMembers)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "member")}
func loadInformationMember(){
if let data = NSUserDefaults.standardUserDefaults().objectForKey("member") as? NSData {
globalCurrentMembers = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [Member]
}
And my class:
class Member : NSObject, NSCoding {
var image = String ()
var name = String ()
var progression = Int()
var round = Int()
var level = Int()
var imageProgression = [UIButton]()
func initiation(){
image = "default.png"
name = "default"
progression = 0
round = 0
level = 0
}
required convenience init(coder decoder: NSCoder) {
self.init()
self.image = decoder.decodeObjectForKey("image") as String!
self.name = decoder.decodeObjectForKey("name") as String!
self.progression = decoder.decodeIntegerForKey("progression") as Int!
self.round = decoder.decodeIntegerForKey("round") as Int!
self.level = decoder.decodeIntegerForKey("level") as Int!
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.image, forKey: "image")
coder.encodeObject(self.name, forKey: "name")
coder.encodeInt(Int32(self.progression), forKey: "progression")
coder.encodeInt(Int32(self.round), forKey: "round")
coder.encodeInt(Int32(self.level), forKey: "level")
}}

Related

Filtering String from Firestore database sends an error on SwiftUI

I'm working on implementing a search for a movies database stored in firestore using SwiftUI. I've tried doing filtering the movie names by the entered text as follows:
#ObservedObject var movies = getMoviesData()
...
ForEach(self.movies.datas) { movies in
ForEach(movies.title.filter({"\($0)".contains(searchText.lowercased()) || searchText.isEmpty})) { item in
if let url = URL(string: movies.img) {
AnimatedImage(url: url)
.resizable()
.frame(width: bounds.size.width / 2 - 0.6, height: bounds.size.height / 2 - 0.2)
}
}
.animation(.spring())
}
...
struct movies : Identifiable {
var id: String
var title: String
var img: String
var video: String
var description: String
var genre: String
}
class getMoviesData : ObservableObject{
#Published var datas = [movies]()
private var db = Firestore.firestore()
func fetchData(){
db.collection("movies").addSnapshotListener{ (querySnapshot, error) in
guard let mov = querySnapshot?.documents else{
print("No movies")
return
}
self.datas = mov.map{(queryDocumentSnapshot) -> movies in
let data = queryDocumentSnapshot.data()
let id = data["id"] as? String ?? ""
let title = data["title"] as? String ?? ""
let img = data["img"] as? String ?? ""
let video = data["video"] as? String ?? ""
let description = data["description"] as? String ?? ""
let genre = data["genre"] as? String ?? ""
return movies(id: id, title: title, img: img, video: video, description: description, genre: genre)
}
}
}
}
However, I'm receiving the following error on the second ForEach statement:
Referencing initializer 'init(_:content:)' on 'ForEach' requires that 'String.Element' (aka 'Character') conform to 'Identifiable'
Movies.title represents a String output of each movie identified in the ForEach statement. How should I filter movies.title against the provided search text without invoking this error?
I am little confused about your use of variable names.
ForEach(movies.title.filter({"\($0)".contains(searchText.lowercased()) || searchText.isEmpty})) { item in
}
}
In the above code movies.title is very misleading. Is there a title property on movies array. If you need to filter, you can perhaps check out the sample code below:
struct Movie {
let title: String
}
let movies = [Movie(title: "Spiderman"), Movie(title: "Batman"), Movie(title: "Superman")]
let searchWord = "batman"
let filteredMovies = movies.filter { movie in
return movie.title.lowercased().contains(searchWord.lowercased())
}
print(filteredMovies)

fatal : Array index out of range

Every child has a pick up point location consists of latitude and longitude that i fetch from sqlite database. I have childIdArray which is array of childID's. I want to calculate the estimate time(ETA) from current location of their respective drivers location i fetch from getCurrentLocationOfRespectiveDrivers() method with pickUp point of children that i fetch from sqlite database in form of array of latitude and longitude.
but i get error
fatal error: Array index out of range
in getCurrentLocationOfRespectiveDrivers() method.
Any help would be highly appreciated.. thanks in advance
var etaArray : [String] = []
var estimatedTime : String?
var latitudeArray : [Double] = []
var longitudeArray : [Double] = []
override func viewDidLoad() {
super.viewDidLoad()
let rs = ModelManager.sharedInstance.fetchingPickUpAnnotationsArray(ChildDetailsVC.parentID)
latitudeArray = rs.latPickUp
longitudeArray = rs.longPickUp
print("pickUpLatitudeArray = \(latitudeArray)")
print("pickUpLongitudeArray = \(longitudeArray)")
let result = ModelManager.sharedInstance.fetchingChildren( ChildDetailsVC.parentID)
self.childNameArray = result.childNames
self.childImageArray = result.childImages
self.childIDArray = result.chidIDs
self.childDriverArray = result.childDrivers
getCurrentLocationOfRespectiveDrivers()
for (var i = 0; i < childIDArray.count; i++)
{
etaArray.append("")
}
}
func getCurrentLocationOfRespectiveDrivers()
{
for( var i = 0 ; i < latitudeArray.count ; i++)
{
let url:NSURL = NSURL(string:"http://development.ssntpl.com/gogo_app/api.php?action=getDriverCurrentLocation")!
let request = NSMutableURLRequest(URL:url)
request.HTTPMethod = "POST"
let post:NSString = "child_id=\(childIDArray)"
request.HTTPBody = post.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{
data, response, error in
if error != nil
{
print("error is \(error)")
return;
}
do
{
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = myJSON
{
let Status = parseJSON["status"] as! Int
let Code = parseJSON["code"] as! Int
if (Status == 1 && Code == 200)
{
let Result = parseJSON["result"] as! NSArray
self.etaArray.removeAll()
//here i get the crash fatal error: Array index out of range
let latitudePickUp = self.latitudeArray[i]
let longitudePickUp = self.longitudeArray[i]
let CoordinatePickUp = CLLocation(latitude: latitudePickUp, longitude: longitudePickUp)
for res in Result
{
self.estimatedTime = ""
if (res["exists"] as! Int == 1)
{
let lastLatitude = res["latitude"] as! CLLocationDegrees
let lastLongitude = res["longitude"] as! CLLocationDegrees
let Location : CLLocation = CLLocation(latitude: lastLatitude, longitude: lastLongitude)
let meters:CLLocationDistance = Location.distanceFromLocation(CoordinatePickUp)
print(meters)
let ID = res["child_id"] as! String
let time = round(meters/40000 * 60)
self.estimatedTime = String(time)
self.etaArray.append(self.estimatedTime!)
}
else
{
self.etaArray.append("")
}
}
}
else
{
}
}
}
catch
{
print(error)
}
}
//executing the task
task.resume()
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
}

Could not cast value of type '__NSCFNumber' (0x10e59f3c0) to 'NSString' (0x10dba7ad8) swift 3

I've been tying to figure out this one for a few days now... Here is my original code:
if let ratingDic = dictionary["rating"] as? [String: Any],
let ratingId = ratingDic["id"] {
searchResult.ratingID = ratingId as! String
}
Here is my api:
"amount" = "50.00";
"rating" = {
"name" = "Platinum";
"id" = 5
I'm pretty sure I need to use "valueForKey" so here is my updated code:
if let ratingDic = dictionary["rating"] as? [String: Any],
//let ratingId = ratingDic["id"] {
let ratingId = [ratingDic.valueForKey("id")!] {
searchResult.ratingID = ratingId as! Number
}
However now I receive the "Value for type String:Any has no member "valueForKey"
Never mind, I was forgetting to change the actual variable to a "Double" or number
var ratingID = 0.0
instead of
var ratingID = ""
and the code now reads
if let ratingDic = dictionary["rating"] as? [String: Any],
let ratingId = ratingDic["id"] {
searchResult.ratingID = ratingId as! Double
}

string.unpack swift equivalent?

I've been looking all over and can't seem to find an equivalent of String.unpack (ruby) for Swift. For example, I am trying to write these two statements in Swift:
offset = digest.unpack('#19C').first & 0x2f
value = digest.unpack("#{offset}#L").first
If anyone knows how I could accomplish this it would be very helpful, thank you!
EDIT:
Code so far:
import Foundation
class PasswordViewController: UIViewController {
#IBOutlet weak var simpleLabel: UILabel!
var email:String!
var LRA:String!
var sysid:String = "SECRET"
override func viewDidLoad() {
super.viewDidLoad()
var x:Int = 1446569017
reset_code(x)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func randomInt(min: Int, max:Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}
func reset_secret()->String {
return sysid.hmac(.SHA512, key: "THISISAKEY")
}
func reset_input(t:Int)->String{
var time:String = String(t)
var input:[String] = [sysid, email, time]
var stringrep:String = "|".join(input)
return stringrep
}
func reset_hmac(t:Int)->String{
var firstTime:String = reset_secret().hmac(.SHA256, key: reset_input(t))
return reset_secret().hmac(.SHA256, key: firstTime)
}
func reset_code(t:Int){
var time:Int = t / 43200
var digest:String = reset_hmac(t)
simpleLabel.text = digest
}
}
enum CryptoAlgorithm {
case SHA256, SHA512
var HMACAlgorithm: CCHmacAlgorithm {
var result: Int = 0
switch self {
case .SHA256: result = kCCHmacAlgSHA256
case .SHA512: result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
var digestLength: Int {
var result: Int32 = 0
switch self {
case .SHA256: result = CC_SHA256_DIGEST_LENGTH
case .SHA512: result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
extension String {
func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
let strLen = Int(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLen = algorithm.digestLength
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
let keyStr = key.cStringUsingEncoding(NSUTF8StringEncoding)
let keyLen = Int(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
let digest = stringFromResult(result, length: digestLen)
result.dealloc(digestLen)
return digest
}
private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
var hash = NSMutableString()
for i in 0..<length {
hash.appendFormat("%02x", result[i])
}
return String(hash)
}
}

Casting NSManagedObject property from num to Bool in swift

I know that question has been asked many times, but the solutions didn't work with me. I have the following NSManaged object class:
#NSManaged var cellColor: AnyObject
#NSManaged var des: String
#NSManaged var name: String
#NSManaged var switcher: NSNumber
And when trying to assign this value to a var as a bool when loading the managed object, I get an error. This is an example of assigning the value to a var:
func loadData(){
var appDel = UIApplication.sharedApplication().delegate as AppDelegate
var context = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Row")
var result:NSArray = context.executeFetchRequest(request, error: nil)!
if result.count > 0 {
for i in result{
var name = i.name as String
var des = i.des as String
var color = i.cellColor as UIColor
var switcher:Bool{
get{
return i.switcher == NSNumber(bool: true)
//the problem happens here
However, when I try a simple example of casting in this way, It works well.
How to solve that ??
I think it just like this:
for i in results {
var name = i.name as String
var des = i.des as String
var color = i.cellColor as UIColor
var switcher: Bool {
return Bool(i.switcher)
}
}
Didn't test that though.

Resources