Appending an array in swift, having problems - ios

I am getting the error 'AnyObject' does not have a member named 'append' for results that I am trying to post to an array. I'm not sure how to fix the error, as I thought my code was correct. Can someone help me make the proper adjustments? My code is as follows:
import CloudKit
import UIKit
import Foundation
class Items {
var theSelfie: [String]
init(record: CKRecord) {
println("init")
var record: CKRecord
var iama: String
var youarea: String
var image: CKAsset? // tried also initializing the CKAsset separately
var postPic: UIImage?
let database = CKContainer.defaultContainer().publicCloudDatabase
let container = CKContainer.defaultContainer()
let publicDB = container.publicCloudDatabase
let data = CKRecord(recordType: "theUsers")
var predicate = NSPredicate(value: true)
let myQuery = CKQuery(recordType: "theUsers", predicate: predicate)
var mySelfie = theSelfie
publicDB.performQuery(myQuery, inZoneWithID: nil) { results, error in
if error != nil {
println(error)
} else {
for record in results{
let aselfie = data.objectForKey("selfie")
aselfie.append[mySelfie]()
return ()
}
}
}
}
}
}

The return type of objectForKey is AnyObject!
The type AnyObject doesn't have a method named append. You'll need to cast the return value to the correct type.
In addition, I don't think I see you ever put an entry in data with key "selfie". If you want it to be an array then somewhere you need to call data.setObject

You're getting aselfie from a dictionary. The dictionary returns objects of type AnyObject. Since you seem confident, that's it's an Array you can cast it to Array or NSArray.
let aselfie = data.objectForKey("selfie") as Array

I don't think that aselfie.append[mySelfie]() is valid Swift syntax. Does it even compile? Maybe you meant aselfie.append(mySelfie)?
Also, how do you know that aselfie is an Array? You should cast it:
let aselfie = data.objectForKey("selfie") as? Array<Whatever>
aselfie.append[mySelfie]()
return ()
}

You should cast aselfie to array then call its append method not its subscript
if let aselfie = data.objectForKey("selfie") as? [AnyObject] // if aselfie is supposed to hold object of single type case it as [ObjcetsToHold]
aselfie.append(mySelfie)
return ()
}

Related

Swift: use filter function on array of dictionaries? Error: Cannot invoke 'filter' with an argument list of type

The goal of this code below is to filter out dictionaries with a certain ID, where ID is a string.
let dictArray = networkData["dicts"] as! [[String:AnyObject]]
localData["dicts"] = dictArray.filter{ ($0["id"] as! String) != sample.getId() }
This code, however, generates an error:
Cannot invoke 'filter' with an argument list of type '(([String :
AnyObject]) throws -> Bool)'
Based on other SO answers like this one and this one, it seems the error is the dictionaries don't conform to Equatable.
So is the only option for using filter to create a custom class to hold the array of dictionaries and make that class conform to Equatable?
If so, perhaps it seems cleaner to simply iterate and create a new array.
Filtering [[String:AnyObject]] (a.k.a. Array>) results in another [[String:AnyObject]]. You're trying to assign this to a var of type AnyObject, which is not allowed in Swift 3, since arrays are structs, not objects.
Make a type-safe struct or object to hold this data, rather than a dict.
For example:
let dictArray = networkData["dicts"] as! [[String:AnyObject]]
let filteredDicts = dictArray.filter{ ($0["id"] as! String) != sample.getId() }
localData["dicts"] = filteredDicts
The issue isn't on hash objects not conform to Equatable because you are using String to do the comparing.
I have the code runs well in Playground:
// make sure data is type of [String: [[String: AnyObject]]]
// make sure filteredData is type of [String: [[String: AnyObject]]]
let key = "hashes"
if let hashArray = data[key] {
let id = sample.getId() // make sure it's String type
filteredData[key] = hashArray.filter { ($0["id"] as? String) != id }
}

Type '(String, AnyObject)' has no subscript members in swift

I am using this line to get data
let productDict = arrProductCart[sender.tag] as! [String: AnyObject]
and I want to filter data from dictionary so i am using this code
let filteredSubitems = productDict.filter{
$0["groupid"] as!String != "1"
}
it is giving me error Type '(String, AnyObject)' has no subscript members
do i need to convert [String: AnyObject] to [String: String]?
what to do.
Most probably you want to filter arrProductCard array instead of productDict, which doesn't make sense. Try this:
let filteredProducts = arrProductCard.filter{
guard let groupId = $0["groupid"] as? String else { return false }
return groupId != "1"
}
You should avoid forced unwrapping whenever you can. Note that your code inside filter closure will crash if there is no groupid value in the dictionary or if it is not a string.
Edit:
If you're using NSMutableArray for some reason, you can just filter it with a predicate:
let mutableArray = NSMutableArray(array: [["groupid": "1"], ["groupid": "2"]])
let groupIdPredicate = NSPredicate(format: "groupid != %#", "1")
mutableArray.filter(using: groupIdPredicate)
However, I would strongly recommend to use Swift native collections.

Swift: Cannot convert of type NSNumber to expected argument type Int16

I have a CoreData entity named EntityOne and it has two attributes:
coreValue of type Int16
coreDate of type NSDate
When I try to access the core data entries from a fetch request and append the values to individual arrays the error appears for the line:
coreDataValues.append(item.coreValue!)
let request = NSFetchRequest(entityName: "EntityOne")
let fetchResults = try context.executeFetchRequest(request) as! [EntityOne]
var coreDataDates = [NSDate]()
var coreDataValues = [Int16]()
for item in fetchResults {
coreDataDates.append(item.coreDate!)
coreDataValues.append(item.coreValue!)
}
Try doing this:
item.coreValue!.shortValue
You should also think about safely unwrapping these before using them:
if let value = item.coreValue {
coreDataValues.append(value.shortValue)
}

error using valueForKey in swift

Why do I get an error when I used valueForKey... I am using same trick like in objectiveC ...
In ObjectiveC, the code is
self.strSubscribe =[responseObject[#"subscribe"] valueForKey:#"subscribe_ids"];
In Swift , the code is
self.strSubscribe = responseObject["subscribe"].valueForKey["subscribe_ids"] as! String
I declare the variables like
var arraySubCategory : NSMutableArray! = NSMutableArray()
var strSubscribe:String!
And I tried to access the value from below response
{
subscribe =
{
"subscribe_ids" = "1,14";
}
}
Edit
It works using Amit and Eric's solution but now for following data
{
data = (
{
"subscribe_ids" = "1,14";
}
);
}
let dictionary = responseObject["data"][0] as! Dictionary<String,AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
OR//
if let dic = responseObject["data"][0] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids
}
but it gives me error:
could not find member 'subscript'
Swift doesn't know the type of responseObject["subscribe"], you have to help the compiler a bit; for example:
if let dic = responseObject["subscribe"] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids // "1,14"
}
UPDATE:
It's still the same problem: the compiler doesn't know the type of responseObject["data"], so when you try to access the subscript there's an error (because you know it's a dictionary inside the array, but the compiler doesn't).
One solution is to give the type to the compiler by declaring an array of dictionaries in the if let condition:
if let arr = responseObject["data"] as? [[String:String]], let ids = arr[0]["subscribe_ids"] {
self.strSubscribe = ids
}
Notice that it's [[String:String]] (array of dictionaries), not [String:String] (dictionary).
Write like this.
let dictionary = responseObject["subscribe"] as! Dictionary<String, AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
Since responseObject["subscribe"] will give a AnyObject? output and AnyObject does not have any member called valueForKey.

NsMutable is not subtype of [anyobject] in swift

I want to get the array from NSUserdefault and store it into NsMutableArray but unfortunately it fails.
error
NsMutable is not subtype of [anyobject] in swift
code
arrayImage = NSUserDefaults.standardUserDefaults().arrayForKey("ImageArray") as NSMutableArray
I am also trying to do downcast NSArray->NSString like in this post.
The NSUserDefaults arrayForKey method returns an optional array of AnyObject. It you want it to be mutable just declare it using "var".// example:
var mutableArray = NSUserDefaults.standardUserDefaults().arrayForKey("ImageArray")
If you want it to be immutable you have to declare it using "let".
let imutableArray = NSUserDefaults.standardUserDefaults().arrayForKey("ImageArray")
If you want to make sure your method does not return nil before setting any value to userdefaults you can use the nil coalescing operator "??" to return an empty array as follow:
var mutableArray = NSUserDefaults.standardUserDefaults().arrayForKey("ImageArray") ?? []
If you want to store images using user defaults you have to first convert your image to NSData. So you should create a method class to help you with it:
class Save {
class func image(key:String, _ value:UIImage) {
NSUserDefaults.standardUserDefaults().setObject(UIImagePNGRepresentation(value), forKey: key)
}
class func imageArray(key:String, _ value:[UIImage]) {
NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(value), forKey: key)
}
}
class Load {
class func image(key:String) -> UIImage! {
return UIImage(data: ( NSUserDefaults.standardUserDefaults().objectForKey(key) as NSData))!
}
class func imageArray(key:String) -> [UIImage]! {
if let myLoadedData = NSUserDefaults.standardUserDefaults().dataForKey(key) {
return (NSKeyedUnarchiver.unarchiveObjectWithData(myLoadedData) as? [UIImage]) ?? []
}
return []
}
}
Testing
let myProfilePicture1 = UIImage(data: NSData(contentsOfURL: NSURL(string: "http://i.stack.imgur.com/Xs4RX.jpg")!)!)!
let myProfilePicture2 = UIImage(data: NSData(contentsOfURL: NSURL(string: "https://lh6.googleusercontent.com/-Axxzrunya9Y/AAAAAAAAAAI/AAAAAAAAAHo/gsDxk5FlliE/photo.jpg")!)!)!
Save.image("myPic", myProfilePicture1)
let myLoadedPic = Load.image("myPic")
let myImageArray = [myProfilePicture1,myProfilePicture2]
Save.imageArray("myPicArray", myImageArray)
let myLoadedPicArray = Load.imageArray("myPicArray")
Apple doc says:
You can also create an NSArray object directly from a Swift array literal, following the same bridging rules outlined above. When you explicitly type a constant or variable as an NSArray object and assign it an array literal, Swift creates an NSArray object instead of a Swift array.
A brief example here:
let imageArray: [AnyObject]? = NSUserDefaults.standardUserDefaults().arrayForKey("ImageArray")
if let array = imageArray{
var arrayImage: NSArray = array
}

Resources