query user objectIDs stored in an array swift - arrays

I am trying to make groups of users in a class that will queried to form a group chat. I have stored the objectId's of each user in the group in an array. Then I save the array to Parse.
I am having trouble figuring out how to query the array, and then compare the objectID's with the _User class so the group members can be identified by name and profile picture.
Right now this is the code I have, but I know that it isn't the right method. Does anyone have any advice? Thanks!
class squadDetailInformation: UIViewController{
var currentObject: PFObject?
var squadmemberstrial: NSArray = []
override func viewDidLoad() {
super.viewDidLoad()
if let object = currentObject{
squadmemberstrial = (object.objectForKey("SquadMembers") as? NSArray)!
let user : PFUser = object.objectForKey("objectID") as! PFUser
let queryUsers = PFUser.query()
queryUsers.getObjectInBackgroundWithId(user.objectId, block: {
(userGet :PFObject!,error : NSError!) -> Void in
})
}
}
}

Don't use an array of object ids. An array of proper pointers would be better, but still isn't ideal. Instead you should use a relationship as you can directly query it and you can also use the relationship query in other queries as a filter.

Related

overwrite a core data binary data item

My swift code below saves 3 images. What I want to do is overwrite iamgedata2 is func press. Imagedata2 should be replaced with Gwen. So the order should be Gwen Gwen Gwen instead of Gwen gwen2 Gwen. I don't know what really to put in func press to achieve this goal.
import UIKit; import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
let gwen = UIImage(named: "blank")
let gwen2 = UIImage(named: "g.jpg")
if let imageData = gwen.self?.pngData() {
CoredataHandler.shareInstance.saveImage(data: imageData)
}
if let imageData2 = gwen2.self?.pngData() {
CoredataHandler.shareInstance.saveImage(data: imageData2)
}
if let imageData3 = gwen.self?.pngData() {
CoredataHandler.shareInstance.saveImage(data: imageData3)
}
}
#objc func press(){
CoredataHandler.shareInstance.saveImage(data: 1)
return
}
}
class CoredataHandler : NSManagedObject {
static let shareInstance = CoredataHandler()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
private class func getContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
func saveImage(data: Data) {
let imageInstance = Information(context: context)
imageInstance.pic = data
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
}
If you want a Core Data entity that can store more than one image, you have a few options:
Declare multiple image properties
Instead of just having a pic property, have more than one. As many as you like. Name them pic1, pic2, pic3, etc, or whatever seems best for your app. In code, read or write whichever makes sense at the time.
This is easy but not flexible, since your code can only save up to the number of attributes you declare in the model.
Use an array property with transformable
With a transformable attribute you can store any data that can be converted to a Data. In your case you'd do something like this:
Two things to notice: The type is transformable, and the custom class is [Data]. Xcode will generate code where the property type is [Data]?. You can save as many Data blobs as you want in it, representing however many images you want.
This is also easy but may use a lot of memory, because you can't access one image without loading all of them into memory at once. If you always load all of them anyway then it's no different. If you often load only one of them, this technique might use a lot more memory (e.g. 4 images would mean around 4x as much memory used).
Use a separate entity to hold the image and a to-many relationship
With this approach you'd create a new Core Data entity that only holds the image. Your existing entity would have a to-many relationship to this entity. You'd create as many image-only instances as you want, and the relationship would mean they were all available at any time.
You would probably want to make sure the to-many relationship is ordered, otherwise the images would be an unordered set that could be in any order.
This is a little more complex to write but it's flexible and doesn't have the potential memory problems of other approaches.

Swift: Cannot add element in Array from another object

I am struggeling with swift syntax . I want to add objects to an array but I have syntax errors.
The array is located in class Document, and the class that should add objects is in class Viewcontroller.
The array is of type Content:
public class Content: NSObject {
#objc var bankAccSender: String?
#objc var bankAccReceiver: String?
Declaration snippest in Document:
class Document: NSDocument {
var content=[Content]()
override init() {
super.init()
self.content = [Content]()
// force one data record to insert into content
content += [Content (… )] // checked with debugger
The ViewController has assigned the represented Object
contentVC.representedObject = content
But adding data in ViewController gives a compiler error „Type of expression is ambiguous without more context“:
var posting = Content(…)
self.representedObject.append(posting)
Hope you can help..
You can't append an element to an object of type Any. What you need is to replace the existing value with a new collection:
representedObject = (representedObject as? [Content] ?? []) + CollectionOfOne(posting)
representedObject is of type Any?, which is a very difficult type to work with in Swift. Since you already have a content property, I would probably adjust that, and then re-assign it to representedObject.
You can also try this (untested), as long as you are certain that the type is always [Content]:
(self.representedObject as! [Content]).append(posting)
It's possible you'll need some more complex like this:
(self.representedObject as! [Content]?)!.append(posting)
As I said, Any? is an incredibly obnoxious type. You probably want to wrap this up into a function. Or I you can avoid using representedObject, then I would recommend that. In many cases you don't need it. It's often just a convenience (in ObjC; in Swift, it's very hard to use).

Filtering an array of objects by class not working

I have a UIStackView that contains UIViews or objects of a class I have created called MyView.
MyView is a subclass of UIView.
I want to extract from that array, all objects of class MyView.
This is what I have tried and the respective errors:
let views = Array< MyView >(allViews).filter { $0 is MyView }
type of expression is ambiguous without more context
I love these messages that say nothing.
let views = Array<Any>(allViews).filter { $0 is MyView }
I love how this compiles with Any.
No error in this case, but views contains the same objects as myViews, nothing is being filtered.
I understand that MyView is a subclass of UIView, so what swift is testing here is if the object is of class UIView. If this is true, why bothering allowing programmers to specify any class on the filter, if it can only filter some classes?
Is there a way to test for subclasses?
I'm guessing allViews is an array of UIView.
You should use compactMap, which will map to an array of the subclass, throwing away any nil values (which result from the as?):
let views = allViews.compactMap { $0 as? MyView }
Note here views is already of type [MyView]; take a look at compactMap's method signature to understand:
func compactMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

SWIFT - How to get the type of an Array?

i'm writing a generic method who take a Dictionary and a given type in parameters for build an object.
For example, if you make a SOAP request for get a movie and put away the response in Dictionary you can make:
var movie : Movie = myGenericMethod(dic : Dictionary, objectToIntrospect : Movie()) as Movie
It's work with:
Simple Object
Complex Object
But i have a problem if you have an array of object.
So imagine your movie object contains an Array of Actors...
With reflection, i get all type of my class's attributes.
With this, i build an Array of Any object which contains my types.
For example, an object contained in other object (Actor in a Movie):
//All type of attributes of my movie object, at index [i] i have my "Actor" object
var anyType : Any = typesOfProperties[i]
//I cast it in object
var objectType : NSObject = anyType as NSObject
//Dont worry about this method, it's just for get the dictionary
var otherDico : NSDictionary = ConverterUtilities.extractDictionaryFromOtherDictionary(dict, dicoName: property, soapAction: soapAction) as NSDictionary
//I build the Actor object with the data of the dictionary. objectType.self give the Actor type
var propertyObject: NSObject = self.buildAnyObjectWithDictionary(otherDico, soapAction: "", objectToIntrospect:objectType.self) as NSObject
//I set the property Actor in my Movie object (myObjectToReturn)... The "property" parameter is the key
ConverterUtilities.setPropertyValue(property, value: propertyObject, objectToReturn : myObjectToReturn, isObject : true)
It's work perfectly... If i have just one actor in my movie object, the "propertyObject" will be an Actor type, and this cause objectType is an Actor object.
But, if i have an array, i'm redirect in method who treat Array, and my objectType return "Swift._NSSwiftArrayImpl" and my anyType object return "([myproject.Actor])".
I dont need to know this is just an Array, cause i know it. But i need to know that's an Array of Actor for build some Actor object dynamicly !
This is what i have for the moment:
var objToAdd: NSObject = self.buildAnyObjectWithDictionary(newDic, soapAction: "", objectToIntrospect: Actor()) as NSObject
arraySpecific.append(objToAdd)
As you can see, this work perfectly if i hardcode the type. But i need to make it like the previous example ! Like that:
var objToAdd: NSObject = self.buildAnyObjectWithDictionary(newDic, soapAction: "", objectToIntrospect: anObjectWithActorType) as NSObject
arraySpecific.append(objToAdd)
(Difference between first and second version is the objectToIntrospect parameter)
Do you know how can i use my Any object (contains: ([myproject.Actor]) for build an instance of one Actor ?
I really need ur help for this ! Regards !
PS: sorry for my bad english, i hope u understand me :)
Ok guys, i come back on my post cause i found a solution:
i create a master class, and all of my classes herit of this class.
This super-class have a method name getArrayType.
If one of my children-class need to be used with my generic method and if she contain a Array, they need to override the getArrayType.
Like that:
override func getArrayType(anyType : Any) -> String {
var className = " "
if(anyType as? NSObject == rows){
className = Properties.PROJECT_NAME + ".SimpleRow"
}
return className
}
And i call this method like that (TObject is my super-class):
var className = (objectToIntrospect as TObject).getArrayType(anyType)
var obj: AnyClass! = NSClassFromString(className)
This work perfectly, but you need to override a method. I hope this help u if u got the same problem !

Save my own class as an array in Parse

I have a class named Pet. I collect it in an array. Then I try to save it like below code. I also tried inheriting NSObject to the Pet class with no use. Is it not possible to save my own class of arrays in Parse or am I doing something really wrong? Note that the current user exists and valid.
Somewhere in code defined:
var pets : [Pet] = [Pet]()
populated:
pets.append(newPet)
and tried to save:
#IBAction func saveTapped(sender: UIBarButtonItem) {
PFUser.currentUser().setObject(pets, forKey: "pets")
user.saveInBackgroundWithBlock({ (success, error) -> Void in
if error == nil {
DLog("Suceess saving")
} else {
displayAlertWithTitle(self, nil, error.description)
DLog(error)
}
})
}
The error I am getting is:
2015-02-17 18:28:59.906 Patikoy[38292:2121589] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Patikoy.Pet)'
p.s. I am a beginner in Swift as well as Parse. Any help is appreciated.
Parse is likely trying to serialize the "pets" array into JSON. However, your "Pet" class is not serializable to JSON.
From the NSJSONSerialization Class Reference:
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
You need to create a method on your Pet class that converts it to a Dictionary, as described in this Stack Overflow answer.

Resources