How to load thousands records to Realm correctly?
Try the way in official demo to save large amounts of data:
DispatchQueue(label: "background").async {
autoreleasepool {
// Get realm and table instances for this thread
let realm = try! Realm()
// Break up the writing blocks into smaller portions
// by starting a new transaction
for idx1 in 0..<1000 {
realm.beginWrite()
// Add row via dictionary. Property order is ignored.
for idx2 in 0..<1000 {
realm.create(Person.self, value: [
"name": "\(idx1)",
"birthdate": Date(timeIntervalSince1970: TimeInterval(idx2))
])
}
// Commit the write transaction
// to make this data available to other threads
try! realm.commitWrite()
}
}
}
How to add 1 milion items in Realm correctly?
You have to be aware that SQLite and Realm are two very different things. Realm is an object store and you are creating a lot of objects in the code shown above. Depending on your model class and the number of rows/objects, you will often see that Realm is a bit slower on inserts. To do a fair comparison, you could compare Realm with one of the many excellent ORMs out there.
Said that, Realm offers a low-level interface (io.realm.internal). I wouldn't recommend you to use it as it is currently undocumented. Your example would look like this:
long numberOfObjects = 1000000;
SharedGroup sharedGroup = new SharedGroup("default.realm");
WriteTransaction writeTransaction = sharedGroup.beginWrite();
Table table = writeTransaction.getTable("class_Product");
table.addEmptyRows(numberOfObjects);
for (int i = 0; i < numberOfObjects; i++) {
table.setLong(0, i, i); // id
table.setString(1, i, "Product_"+i); // name
table.setString(2, i, "SKU__"+i); // sku
table.SetDate(3, i, new Date()); // date
}
writeTransaction.commit();
sharedGroup.close();
You can now compare two table/row oriented data stores, and you will probably find that Realm is a bit faster than SQLite.
At Realm, we have a few ideas on how to get our object interface to run faster, and we hope to be able to implement them in the near future.
How to properly use Realm objects in a UITableViewController?
No cast needed
It seems that casting to Site is not needed. This works fine:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
let site: AnyObject! = allSites[UInt(indexPath.row)]
cell.textLabel!.text = site.name
println("Site is: \(site.id)")
return cell
}
Seems to be a bug with either Swift or Realm. I'm guessing one of them gets confused when downcasting AnyObject!
to something.
Initializing a new instance with correct type
However, if you really need to use the Site
model class you can initialize a new RLMObject
from the result:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
let site = Site(object: allSites[UInt(indexPath.row)])
cell.textLabel!.text = site.name
println("Site is: \(site.id)")
return cell
}
First try
It is unfortunate to hear that you are having issues with Realm and Swift. I am by no means a Swift pro, but it looks like you are casting site
to an optional, and the result of using the optional cast operator site?.name
is also an optional. Hence getting Optional("")
.
Can you try to see if you have any better luck with the following?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
if var site = allSites[UInt(indexPath.row)] as? Site {
println("Site is: \(site.name)")
} else {
println("it not castable to Site. It is: \(toString(allSites[UInt(indexPath.row)].dynamicType))")
}
return cell
}
Also, you can use yourObject.dynamicType
to get a reference to the objects real class type.
Best of luck
Realm query sometimes return no data
Realm writes are transactional - the transaction is a list of read and write operations that Realm treats as a single indivisible operation.
The reads and writes within the closure {} following the write are part of the transaction; the data is not committed until all of those complete. Transactions are also all or nothing - either all operations complete or none.
Most importantly for this case, transactions are synchronous so adding a callback within the transaction is going to present intermittent results.
Move the callback outside the write transaction
try realm.write {
realm.add(list)
}
completion(.success(()))
It can be illustrated by how we used to write realm transactions:
realm.beginWrite()
write some data
// Commit the write transaction to make this data available to other threads
try! realm.commitWrite() <- data is not valid until after it's been committed
//data has been committed
Swift - How to update objects in bulk with out iterating over a collection of realm objects
Short answer:
It is not possible without iterating over a collection of realm
objects.
Long answer:
The realm is a model class based database. It does not support any
query (Predicates or Filter mostly used to retrieve data with a specific condition) like SQLite means We can't update all record in a single query by using therealm
. So answer of your question is pretty
straightforward, Without iterating we can not update the value.
You can improve performance if you want to change the value of some object.
Code:
let persons = realm.objects(Person.self).filter("id IN %@", ids)
try! realm.write {
persons.first?.setValue(true, forKeyPath: "isFirst")
// set each person's planet property to "Earth"
persons.setValue("Earth", forKeyPath: "planet")
}
How to store groups of booleans in Realm for Android?
Option 1: One field per boolean
public class Restaurant extends RealmObject {
private boolean wifi;
private boolean listedOnYelp;
/* getter, setter, etc.*/
}
- Easy to implement
- Easy to understand
- RealmQueries based on the booleans are possible
Option 2: Flag field
64 booleans per long, the masks go from 21, 22, 23 to 264
public class Restaurant extends RealmObject {
private long booleanFlags;
private boolean getFlag(long mask) {
return (booleanFlags & mask) == mask;
}
private void setFlag(long mask, boolean value) {
if (value) {
booleanFlags |= mask;
} else {
booleanFlags &= ~mask;
}
}
public boolean hasWifi() {
return getFlag(1);
}
public void setWifi(boolean hasWifi) {
setFlag(1, hasWifi);
}
public boolean isListedOnYelp() {
return getFlag(2);
}
public boolean isTippingEncouraged() {
return getFlag(4);
}
}
- Super memory efficient (unless Realm does not do the same in its core)
- Not so easy to read or understand
- No RealmQueries based on the booleans
Option 3: Extra class
public class Restaurant extends RealmObject {
/*...*/
}
public class RestaurantPropertyStore extends RealmObject {
private RealmList<Restaurant> restaurantsWithWifi;
private RealmList<Restaurant> restaurantsListedOnYelp;
}
- Not object-oriented
- Queries on one boolean at a time are possible
Option 1 is the object-oriented, Java-like and Realm-like way
Option 2 is the C, C++ way
Option 3 is the SQL, RDBMS way
Related Topics
Convert Nsdate to String with a Specific Timezone in Swift
How to Detect Which Image Has Been Tapped in Swift
Nsclassfromstring Returning Nil for Nested Class
Uitableviewcell Initwithstyle:Uitableviewcellstylesubtitle Is Not Working
Indexing into Array of Functions: Expression Resolves to an Unused L-Value
Binary Operator + Cannot Be Applied to Operands of Type Cgfloat Int
How to Integrate Fitbit API in iOS App Using Swift
iOS How to Restart App for Changing Language Swift 4
How to Remove Single Object in Array from Multiple Matching Object
Adding Firebase Data to an Array in iOS Swift
How to Turn Off Core Data Write-Ahead Logging in Swift Using Options Dictionary
I Cannot Access My Array Objects Anywhere, How to Access Them in Swift
How to Work with Udp Sockets in iOS, Swift
Swift Computed Properties Cannot Be Used in Init