iOS - Swift - Compare 2 entities for the values - ios

I need to compare the values in one Entity another entity.
I donot want to have the one on one string comparison.
As it has so many Params, and the values will be keep adding in future.
Do we have any simple solution for this?
Its not about Core Data. Normal Custom Objects.
For Ex: I need to compare to Employee Object for its values.

func compareTwoEntities() -> Bool
{
let json = JSONSerializer.toJson(userEntity)
let json2 = JSONSerializer.toJson(userBackUpEntity)
if json == json2
{
return true
}
return false
}

You could try comparing two arrays made of these elements of entities. Have you tried that?

Related

Using CoreData to save array containing dictionaries

I'm trying to use CoreData framework inside an iOS app for the first time and I have some troubles with it.
I have a kind of complex type of array, containing tuples that contains dictionaries:
let DataSet: [( Float, Float, [String : String])] = ...
I created an NSManagedObjectContext and an NSManagedObject, I added the DataSet array to the NSManagedObject, but when I try to save the 1st NSManagedObjectContext, the app is crashing.
That's not happening using normal arrays but only with more complex ones like the one above.
Is there a way to deal with that problem? Do I need to adjust my xcdatamodel?
I would appreciate any help a lot.
First you need to declare 2 separate entities. One for Floats and another for Dictionary.
Then create "One to Many" relation ship between Float entity and Dictionary. It will look like this,
Then you need to convert your tuple into these 2 entities, Like this,
dataSet.forEach{ (member) in
let tuple = Test.(context: mainContext)
tuple.first = member.0
tuple.second = member.1
let dictionary = member.2
dictionary.forEach{ (key, value) in
let dick = Dick.(context: mainContext)
dick.key = key
dick.value = value
tuple.addToContains(dick)
}
}
Finally you need to save the values.
if mainContext.hasChanges {
do {
try mainContext.save()
} catch {
print(\(error))
}
}

Appending items to an array in dictionary not working

I have this static dictionary created as so:
static var pictures = Dictionary<Int, Array<UIImage>>()
I want to populate it with images. At the moment when I am creating it I don't know how many key/value pairs I need to create. I have to fetch from the internet the data, but after that I am doing this to populate, but still my dictionary is empty:
for i in 0...Fetching.numberOfAliveListings - 1 {
for _ in 0...AdsCollectionView.listings[i].photos.count - 1 {
AdsCollectionView.pictures[i]?.append(UIImage(named: "noimage")!)
}
}
pictures is initially empty. So any attempt to access a value for a given key will result in a nil value. Since the value (the array) is nil, the optional chaining skips the call to append.
One solution is to provide a default array when looking up the value for a given Int.
AdsCollectionView.pictures[i, default: []].append(UIImage(named: "noimage")!)
You may also wish to consider alternate syntax when declaring pictures:
static var pictures = [Int: [UIImage]]()

Passing Dictionary to Analytics parameters: Urban Airship

I am trying to implement Urban Airship Analytics in my app. I want to track each and every event in my app, for that I have made a different class and passed tracking data as a dictionary.
Following https://docs.urbanairship.com/platform/ios/?swift#ios-screen-tracking link for the same.
I am passing parameters as:
UAirship.shared().analytics.trackScreen("MainScreen")
let event = UACustomEvent()
event.properties = createParamDictionary(paramDict1,paramDict2)
event.track()
As event properties is readonly, I can not assign/add data to it.
And the only option I can see is adding data one by one according to its defined type.
ie.
event.setStringProperty("abcd", forKey: "abcd")
event.setNumberProperty(123, forKey: "xyz")
Which is very tedious in my case.
So My questions are:
Am I doing it correctly?
If Yes, then is there any other variable or some way from which I can directly add parameters?
I also want to add User_id for tracking particular user. Any provision for this?
Thanks.
I think that you can create a custom method to UACustomEvent class which takes a dictionary and sets values using UA defined method, something like this,
extension UACustomEvent {
func setEventProperties<T: Any>(_ values: [String: T]) {
for keyValuePair in values {
if let value = keyValuePair.value as? String {
setStringProperty(value: value, forKey: keyValuePair.key)
} else if let value = keyValuePair.value as? Int {
setNumberProperty(value: value, forKey: keyValuePair.key)
}
}
}
}
That way, you dont have to use setNumberProperty or setStringProperty each time, you want to set events. You can simply do it like this,
event.setEventProperties(["abcd": "abcd", "xyz": 123])

How to convert NSArray to Set?

Most of the posts here are on about how to convert a set into an array.But I would like to know if I could convert an array to a set.I have downloaded my array from parse and want to convert it to a set because I want the user to edit their details and the form builder I used needs to accept a set data type only.
This is what I got.The "Subjects" field is an NSArray in Parse.
let subjects = Set(currentuser?.objectForKey("Subjects"))
Basically the syntax is correct, but the compiler (and me too) doesn't know that the object for key Subjects is supposed to be an array. Use optional binding to check at least for an array of NSObject to conform to the requirement that the items in the array are hashable (thanks to dan for pointing that out):
if let userSubjects = currentuser?.objectForKey("Subjects") as? [NSObject] {
let subjects = Set(userSubjects)
}
If the real type of Subjects is more specific than [NSObject] use that instead

Use Realm with Collection View Data Source Best Practise

I'll make it short as possible.
I have an API request that I fetch data from (i.e. Parse).
When I'm getting the results I'm writing it to Realm and then adding them to a UICollectionView's data source.
There are requests that take a bit more time, which run asynchronous. I'm getting the needed results after the data source and collection view was already reloaded.
I'm writing the needed update from the results to my Realm database.
I have read that it's possible to use Realm's Results. But I honestly didn't understood it. I guess there is a dynamic and safe way working with collection views and Realm. Here is my approach for now.
This is how I populate the collection view's data source at the moment:
Declaration
var dataSource = [Realm_item]()
where Realm_item is a Realm Object type.
Looping and Writing
override func viewDidLoad() {
super.viewDidLoad()
for nowResult in FetchedResultsFromAPI
{
let item = Realm_item()
item.item_Title = nowResult["Title"] as! String
item.item_Price = nowResult["Price"] as! String
// Example - Will write it later after the collectionView Done - Async request
GetFileFromImageAndThanWriteRealm(x.image)
// Example - Will write it later after the collectionView Done - Async request
dataSource.append(item)
}
//After finish running over the results *Before writing the image data*
try! self.realm.write {
self.realm.add(self.dataSource)
}
myCollectionView.reloadData()
}
After I write the image to Realm to an already created "object". Will the same Realm Object (with the same primary key) automatically update over in the data source?
What is the right way to update the object from the data source after I wrote the update to same object from the Realm DB?
Update
Model class
class Realm_item: Object {
dynamic var item_ID : String!
dynamic var item_Title : String!
dynamic var item_Price : String!
dynamic var imgPath : String?
override class func primaryKey() -> String {
return "item_ID"
}
}
First I'm checking whether the "object id" exists in the Realm. If it does, I fetch the object from Realm and append it to the data source. If it doesn't exist, I create a new Realm object, write it and than appending it.
Fetching the data from Parse
This happens in the viewDidLoad method and prepares the data source:
var query = PFQuery(className:"Realm_item")
query.limit = 100
query.findObjectsInBackgroundWithBlock { (respond, error) -> Void in
if error == nil
{
for x in respond!
{
if let FetchedItem = self.realm.objectForPrimaryKey(Realm_item.self, key: x.objectId!)
{
self.dataSource.append(FetchedItem)
}
else
{
let item = Realm_item()
item.item_ID = x.objectId
item.item_Title = x["Title"] as! String
item.item_Price = x["Price"] as! String
let file = x["Images"] as! PFFile
RealmHelper().getAndSaveImageFromPFFile(file, named: x.objectId!)
self.dataSource.append(item)
}
}
try! self.realm.write {
self.realm.add(self.dataSource)
}
self.myCollectionView.reloadData()
print(respond?.count)
}
}
Thank you!
You seem to have a few questions and problems here, so I'll do my best.
I suggest you use the Results type as your data source, something like:
var dataSource: Results<Realm_item>?
Then, in your viewDidLoad():
dataSource = realm.objects(Realm_item).
Be sure to use the relevant error checking before using dataSource. We use an optional Results<Realm_item> because the Realm object you're using it from needs to be initialised first. I.e., you'll get something like "Instance member * cannot be used on type *" if you try declaring the results like let dataSource = realm.objects(Realm_item).
The Realm documentation (a very well-written and useful reference to have when you're using Realm as beginner like myself), has this to say about Results...
Results are live, auto-updating views into the underlying data, which means results never have to be re-fetched. Modifying objects that affect the query will be reflected in the results immediately.
Your mileage may vary depending on how you have everything set up. You could try posting your Realm models and Parse-related code for review and comment.
Your last question:
What is the right way to update the "object" from the Data Source after i wrote the update to same object from the Realm DB?
I gather you're asking the best way to update your UI (CollectionView) when the underlying data has been updated? If so...
You can subscribe to Realm notifications to know when Realm data is updated, indicating when your app’s UI should be refreshed for example, without having to re-fetch your Results.

Resources