GithubHelp home page GithubHelp logo

polqf / realmresultscontroller Goto Github PK

View Code? Open in Web Editor NEW
188.0 188.0 25.0 584.27 MB

A NSFetchedResultsController implementation for Realm written in Swift

License: MIT License

Swift 99.16% Ruby 0.42% Objective-C 0.41%

realmresultscontroller's People

Contributors

bronenos avatar isaacroldan avatar mariabernis avatar ngs avatar polqf avatar sergigracia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

realmresultscontroller's Issues

Calling delegate methods in other queue delays rendering UITableView

I'm using RealmResultsControllerDelegate as UITableViewDataSource.

When beginning table view while scrolling, I see blank until stop scrolling.

01

I could fix this by updating table view in didChangeObject at once like:

func didChangeResults(controller: AnyObject) {
    guard controller === self.rrc else { return }
    tableView.beginUpdates()
    pendingChanges.forEach { update in
        if let newIndexPath = update.newIndexPath, oldIndexPath = update.oldIndexPath {
            switch update.changeType {
            case .Delete:
                tableView.deleteRowsAtIndexPaths([newIndexPath], withRowAnimation: .Automatic)
                break
            case .Insert:
                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Automatic)
                break
            case .Move:
                tableView.deleteRowsAtIndexPaths([oldIndexPath], withRowAnimation: .Automatic)
                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Automatic)
                break
            case .Update:
                tableView.reloadRowsAtIndexPaths([newIndexPath], withRowAnimation: .Automatic)
                break
            }
        } else if let sectionIndex = update.sectionIndex {
            let indexSet = NSIndexSet(index: sectionIndex)
            switch update.changeType {
            case .Delete:
                tableView.deleteSections(indexSet, withRowAnimation: .Automatic)
                break
            case .Insert:
                tableView.insertSections(indexSet, withRowAnimation: .Automatic)
                break
            case .Update:
                tableView.reloadSections(indexSet, withRowAnimation: .Automatic)
                break
            default:
                break
            }
        }
    }
    pendingChanges.removeAll()
    tableView.endUpdates()
}

source

I think we should not call delegate method callbacks in different queues.

ref: ngs/ci2go#33

When using addNotified() I am getting a 'Object must be from the Realm being queried' error

2016-04-06 16:01:02.347 XXX[27792:268230] *** Terminating app due to uncaught exception 'Invalid value origin', reason: 'Object must be from the Realm being queried'
*** First throw call stack:
(
0 CoreFoundation 0x000000010956ee65 exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000108fe7deb objc_exception_throw + 48
2 Realm 0x0000000105dce2b1 _ZL15RLMPreconditionbP8NSStringS0_z + 657
3 Realm 0x0000000105df82ca _ZN12_GLOBAL__N_128add_link_constraint_to_queryERN5realm5QueryE23NSPredicateOperatorTypeRKNS_15ColumnReferenceEP9RLMObject + 1370
4 Realm 0x0000000105df5c79 ZN12_GLOBAL__N_126do_add_constraint_to_queryIJNS_15ColumnReferenceEU8__strongP11objc_objectEEEvRN5realm5QueryE15RLMPropertyType23NSPredicateOperatorTypemDpT + 1353
5 Realm 0x0000000105de9532 ZN12_GLOBAL__N_123add_constraint_to_queryINS_15ColumnReferenceEU8__strongP11objc_objectEEvRN5realm5QueryE15RLMPropertyType23NSPredicateOperatorTypemT_T0 + 658
6 Realm 0x0000000105dd2f47 _ZN12_GLOBAL__N_134update_query_with_value_expressionEP9RLMSchemaP15RLMObjectSchemaRN5realm5QueryEP8NSStringP11objc_objectP21NSComparisonPredicate + 967
7 Realm 0x0000000105dcfcf6 _ZN12_GLOBAL__N_127update_query_with_predicateEP11NSPredicateP9RLMSchemaP15RLMObjectSchemaRN5realm5QueryE + 5286
8 Realm 0x0000000105dcec22 _ZN12_GLOBAL__N_127update_query_with_predicateEP11NSPredicateP9RLMSchemaP15RLMObjectSchemaRN5realm5QueryE + 978
9 Realm 0x0000000105dce460 _Z27RLMUpdateQueryWithPredicatePN5realm5QueryEP11NSPredicateP9RLMSchemaP15RLMObjectSchema + 336
10 Realm 0x0000000105ed515d _ZZ35-[RLMResults objectsWithPredicate:]ENK4$_10clEv + 269
11 Realm 0x0000000105ed2a86 _ZL15translateErrorsIZ35-[RLMResults objectsWithPredicate:]E4$_10EDaOT_P8NSString + 38
12 Realm 0x0000000105ed29f8 -[RLMResults objectsWithPredicate:] + 72
13 RBQFetchedResultsController 0x0000000105cdd5df -[RBQFetchRequest fetchObjects] + 271
14 RBQFetchedResultsController 0x0000000105cd1781 -[RBQFetchedResultsController createStateObjectWithFetchRequest:realm:cache:cacheRealm:] + 1489
15 RBQFetchedResultsController 0x0000000105ccdc50 -[RBQFetchedResultsController calculateChangesWithAddedSafeObjects:deletedSafeObjects:changedSafeObjects:realm:] + 2208
16 RBQFetchedResultsController 0x0000000105ccd1d4 __58-[RBQFetchedResultsController registerChangeNotifications]_block_invoke + 1396
17 RBQFetchedResultsController 0x0000000105ce0376 -[RBQRealmNotificationManager sendNotificationsWithRealm:entityChanges:] + 518
18 RBQFetchedResultsController 0x0000000105ce2550 __50-[RBQRealmChangeLogger registerChangeNotification]_block_invoke + 256
19 Realm 0x0000000105ec08b9 -[RLMRealm sendNotifications:] + 1065
20 Realm 0x0000000105ecc7fb _ZN12_GLOBAL__N_121RLMNotificationHelper10did_changeERKNSt3__16vectorIN5realm14BindingContext13ObserverStateENS1_9allocatorIS5_EEEERKNS2_IPvNS6_ISB_EEEE + 107
21 Realm 0x0000000105ef698b _ZN5realm5_impl11transaction6commitERNS_11SharedGroupEPNS_14BindingContextE + 395
22 Realm 0x0000000105eefac8 _ZN5realm5Realm18commit_transactionEv + 456
23 Realm 0x0000000105ec0c95 -[RLMRealm commitWriteTransaction:] + 53
24 Realm 0x0000000105ec0f4e -[RLMRealm transactionWithBlock:error:] + 158
25 RealmSwift 0x00000001063784b1 TFC10RealmSwift5Realm5writefS0_FzFT_T_T + 209
26 XXX 0x000000010528b190 _TZFC6XXX18PersistenceManager3addfMS0_FTC10RealmSwift6Object14fromWriteBlockSb_CS1_5Realm + 480
27 XXX 0x00000001052453f0 _TZFC6XXX7Message11saveMessagefMS0_FTV10SwiftyJSON4JSON10chatThreadCS_10ChatThread_GSqS0
+ 7952
28 XXX 0x000000010541e59b TZFC6XXX7Message23messagesFromAPIResponsefMS0_FCS_11APIResponseT + 5755
29 XXX 0x00000001052107b6 TZFC6XXX14APISyncManagerP33_56FDCEDBD7F938B6203CBE93E62664E123populateMessagesFromAPIfMS0_FCS_11APIResponsePSs9AnyObject + 294
30 XXX 0x000000010536359f TFZFC6XXX9APIClient23performTaskInBackgroundFMS0_FVS_21APIBackgroundableTaskFT_T_U_FCS_11APIResponseT + 511
31 XXX 0x000000010535be9c TPA__TFZFC6XXX9APIClient23performTaskInBackgroundFMS0_FVS_21APIBackgroundableTaskFT_T_U_FCS_11APIResponseT + 172
32 XXX 0x0000000105363297 TTRXFo_oC6XXX11APIResponse_dT__XFo_iS0__iT_ + 23
33 XXX 0x000000010535bf41 TPA__TTRXFo_oC6XXX11APIResponse_dT__XFo_iS0__iT__13 + 81
34 XXX 0x0000000105363b30 TTRXFo_iC6XXX11APIResponse_iT__XFo_oS0__dT
+ 32
35 XXX 0x0000000105363c63 TFFC6XXX9APIClientP33_632183BA90AB5BFCA689BD5720141B8C20handleSocketResponseFS0_FTGSaPSs9AnyObject__3ackGSqC22Socket_IO_Client_Swift16SocketAckEmitter__T_U_FT_T + 291
36 XXX 0x00000001051f9b67 TTRXFo__dT__XFdCb__dT_ + 39
37 libdispatch.dylib 0x000000010a835e5d _dispatch_call_block_and_release + 12
38 libdispatch.dylib 0x000000010a85649b _dispatch_client_callout + 8
39 libdispatch.dylib 0x000000010a83c8ec _dispatch_queue_drain + 2215
40 libdispatch.dylib 0x000000010a83be0d _dispatch_queue_invoke + 601
41 libdispatch.dylib 0x000000010a83ea56 _dispatch_root_queue_drain + 1420
42 libdispatch.dylib 0x000000010a83e4c5 _dispatch_worker_thread3 + 111
43 libsystem_pthread.dylib 0x000000010ab8e4de _pthread_wqthread + 1129
44 libsystem_pthread.dylib 0x000000010ab8c341 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Support for Realm 1.0?

Realm released 1.0 today.

I'll take a look and see if RRC is compatible with 1.0 out of the box. If it is, I'll open up a PR.

Sections Not Updating Correctly

've discovered a small bug with the library:

  1. Suppose there are two objects in our current Realm objects array [ A : { "name" = "John"}, B : {"name" = "Sam"} ]. The sectionKeyPath = "name".
  2. At this point, there will be 2 sections in the UITableView: John and Sam.
  3. Now if we change object B's name to "John" it'll put object A and B in the section "John". This is fine.
  4. However, once we change object B's name back to "Sam" it still remains in the section "John" rather than deleting itself from the existing section and creating a new one called "Sam" (like in the beginning).

The current workaround seems to be to check if the old object and new object's sectionKeyPath value has changed (via an if statement) and then calling then forcing the RealmResultsController to re-execute the query via fetch().

Good job with the library, though, love its design!

RealmResultsController causes SegFault #11 in Xcode 7.3.1

Hi,

I'ver attached a sample Swift project that installs RealmResultsController using CocoaPods 0.39.0 in Xcode 7.3.1.

It SegFaults when compiling. I've been able to deduce one of the issues that's visible in two source files;

`realm.path` is deprecated. Use `configuration.fileURL` instead. 

However, even after fixing these issues, there are other issues that are stilling causing the project to Seg Fault.

The same error can be reproduced in the sample project that is installed when running

pod try RealmResultsController

Seg11.zip

Cannot pass RealmRequest to RealmResultController

Hi guys,

I have encountered weird problem. I added to my Podfile pod 'RealmResultsController', '~> 0.4.2'

Installing Realm (0.99.0)
Installing RealmResultsController (0.4.2)
Installing RealmSwift (0.99.0)

It actually instaled newer vesion of Realm, than is in your release notes and I cannot get RealmResultsController (0.4.2) and Realm (0.98.6) to install together.

And in my humble opinion due having newer Realm it causes this:

LeagueTableViewController.swift:40:68: Cannot convert value of type 'RealmRequest<APIUnit>' to expected argument type 'RealmRequest<_>'

My code is:

realm = try! Realm()
let request = RealmRequest<APIUnit>(predicate: NSPredicate(value: true),
                                    realm: realm,
                                    sortDescriptors: [
                                        SortDescriptor(property: "projectID"),
                                        SortDescriptor(property: "name")
    ])

rrc = try! RealmResultsController<APIUnit, APIUnitPOSO>(request: request,
                                                        sectionKeyPath: "projectID",
                                                        mapper: APIUnit.map)
rrc!.delegate = self
rrc!.performFetch()

Or I might be wrong and do something seriously wrong.... here is screenshot:

screenshot 2016-04-23 04 16 03

Thanks for any help or clarification.

attempt to delete and reload the same index path

Here is my code:

let carsObjects : [CarObject] = carsDictionaries.map({CarObject(value: $0)})

let query : QueryModel = QueryModel(startDate: startDate, untilDate: untilDate, location: location)

carsObjects.forEach({$0.searchQueries.append(query)})

query.cars.appendContentsOf(carsObjects)

let realm : Realm = try! Realm()

try! realm.write({ () -> Void in
      realm.addNotified(carsObjects, update: true)
})

As mentioned in the title I receive the tableview error "attempt to delete and reload the same index path". It happens with the default RealmResultsController code inside the "didChangeObject". Which is like this:

func didChangeObject<U>(controller: AnyObject, object: U, oldIndexPath: NSIndexPath, newIndexPath: NSIndexPath, changeType: RealmResultsChangeType) {
        switch changeType {
        case .Delete:
            resultsTableView.deleteRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Insert:
            resultsTableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Move:
            resultsTableView.deleteRowsAtIndexPaths([oldIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
            resultsTableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Update:
            resultsTableView.reloadRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        }
    }

And the error occurs when this delegate function is executed:

func didChangeResults(controller: AnyObject) {
        resultsTableView.endUpdates()
    }

Below is my CarObject model class:

class CarObject : Object
{
    dynamic var pictureURL : String = ""
    dynamic var modelName : String = ""
    dynamic var manufacturerName : String = ""
    dynamic var userName : String = ""
    dynamic var href : String = ""

    let distance : RealmOptional<Float> = RealmOptional<Float>()
    let price : RealmOptional<Float> = RealmOptional<Float>()

    let searchQueries : List<QueryModel> = List<QueryModel>()

    override static func primaryKey() -> String?
    {
        return "href"
    }

    class func resultsController() -> RealmResultsController<CarObject, CarObject>?
    {
        var resultsController : RealmResultsController<CarObject, CarObject>? = nil

        do
        {
            let realm : Realm = try Realm()
            let predicate : NSPredicate = NSPredicate(format: "href!=''")
            let request : RealmRequest = RealmRequest<CarObject>(predicate: predicate, realm: realm, sortDescriptors: [SortDescriptor(property: "manufacturerName")])

            resultsController = try RealmResultsController<CarObject, CarObject>(request: request, sectionKeyPath: nil)
        }
        catch
        {
            print("failed to create car object realm results controller")
        }

        return resultsController
    }
}

And the query model class:

class QueryModel : Object
{
    dynamic var startDate : NSDate?
    dynamic var untilDate : NSDate?
    dynamic var location : String = ""

    dynamic var uniqueKey : String = ""

    let cars : List<CarObject> = List<CarObject>()

    convenience init(startDate : NSDate?, untilDate : NSDate?, location : String?)
    {
        self.init()
        self.startDate = startDate
        self.untilDate = untilDate
        self.location = location ?? ""
        self.uniqueKey = (startDate?.completeDateString() ?? "") + (untilDate?.completeDateString() ?? "") + (location ?? "")
    }

    override static func primaryKey() -> String?
    {
        return "uniqueKey"
    }

Detecting changes introduced in an object saved through a relationship of another object

For the moment, RRC is not capable of detecting changes introduced in an object saved through a relationship of another object.

Example:

let user = User()
user.id = 123
user.name = "John"
realm.addNotified(user)

let task = Task()
user.name = "Steven" //This change is not going to be notified
task.assignedUser = user
realm.addNotified(task)

// There will be only one notification for the Task object

have you considered extending this to all RealmCollection types?

RealmResultsController displays a list of filtered objects based on type.

I was wondering if you've looked into creating a way to do this for all RealmCollection types, though. Anything that's a RealmCollection implements addNotificationBlock. If RealmResultsController could take an init that could pass in a RealmCollection, that would be pretty cool. Then it could handle List and LinkingObjects, too.

feature request: find indexPath of an object in the results

I'm sure there are other use cases for this, but here's my current one. I have a list where one item is selected and I have to remember which one it is. So I stash the object id in NSUserDefaults, and every time I fetch my results, I need to know the indexPath of my selected item so I can tell the table it's selected.

For now, I've implemented this extension to do it for me. One method to find it by id, and more general purpose one that can take any NSPredicate to find the first object that matches some condition(s).

In my case, I only have one section, so I'm only searching a single section. Someone else might want to search all sections.

import RealmResultsController

extension RealmResultsController {

  func indexPathOf(sectionIndex: Int, id: AnyObject) -> NSIndexPath? {
    return indexPathOf(sectionIndex, predicate: NSPredicate(format: "id == %@", argumentArray: [id]))
  }

  func indexPathOf(sectionIndex: Int, predicate: NSPredicate) -> NSIndexPath? {
    for row in 0..<numberOfObjectsAt(sectionIndex) {
      let indexPath = NSIndexPath(forRow: row, inSection: sectionIndex)
      let object = objectAt(indexPath)
      if predicate.evaluateWithObject(object as? AnyObject) {
        return indexPath
      }
    }
    return nil
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.