Why is the realm property of a RealmSwift.List nil? - ios

I have been following the following Realm tutorial:
Tutorial: Build iOS App from Scratch
The app is running, the ROS instance as well, but when I add a new task, it doesn't get saved. I have zeroed-in and found that in add(), the write portion of the code doesn't get executed:
let items = self.items
try! items.realm?.write {
items.insert(Task(value: ["text": text]), at: items.filter("completed = false").count)
}
self.realm looks like this:
(lldb) p self.realm
(RealmSwift.Realm?) $R0 = 0x000061800022ff60 {
rlmRealm = 0x00006000000bdd00 {
ObjectiveC.NSObject = {
isa = RLMRealm
}
}
}
items looks like this:
(lldb) p items
(RealmSwift.List<RealmDemo.Task>) $R1 = 0x0000600000026fa0 {
RealmSwift.ListBase = {
Realm.RLMListBase = {
baseNSObject#0 = {
isa = 0x0000600000026fa0
}
__rlmArray = 0x000061000004ee20
}
}
}
items.realm looks like this:
(lldb) p items.realm
(RealmSwift.Realm?) $R2 = nil
That explains why the write op doesn't get executed. What am I missing? I have verified the code and looks the same as in the tutorial (except for the credentials, of course).
Any ideas?

Related

Problems with list manipulation in Swift after iOS update 14.4.2

For some years, I use this simple code to read and manipulate a list in Swift:
if (Helper.hasSubscription()) {
self.allVisitedTrackHandles = Database.getAllCompletedTrackHandles(withDeleted: false, userid: self.userid)
if (self.allVisitedTrackHandles.count > 0) {
var counter = 0
for th: TrackHandle in self.allTrackHandles {
if self.allVisitedTrackHandles.contains(where: { $0.trackid == th.trackid }) {
for thv: TrackHandle in self.allVisitedTrackHandles {
if thv.trackid == th.trackid {
self.allTrackHandles[counter].date_in_milliseconds = thv.date_in_milliseconds
break
}
}
self.allTrackHandles[counter].visited = 1
}
counter += 1
}
}
}
After updating my iOS device to iOS 14.4.2, app is crashing on this line:
for th: TrackHandle in self.allTrackHandles
Only feedback Xcode gives me is this: Thread 79: EXC_BAD_ACCESS (code=1, address=0x12f100010)
I don't know why that line would suddenly start crashing; There is nothing in the code shown that would cause the crash. Are you updating the array somewhere else? Is this, perhaps, a threading issue?
You can refactor this code to make it simpler, clearer and more efficient. This may help;
if Helper.hasSubscription() {
self.allVisitedTrackHandles = Database.getAllCompletedTrackHandles(withDeleted: false, userid: self.userid)
if !self.allVisitedTrackHandles.isEmpty {
for index in 0..<self.allTrackHandles.count {
if let visited = self.allVisitedTrackHandles.first { $0.track id == self.allTrackHandles[index].track id } {
self.allTrackHandles[index].date_in_milliseconds = visited.date_in_milliseconds
}
self.allTrackHandles[index].visited = 1
}
}
}

Cannot convert value of type 'inout NSNumber?' to expected argument type 'AutoreleasingUnsafeMutablePointer<AnyObject?>' error

I have this script use to check whether the *downloaded file from iCloud is available or not. But unfortunately I encountered error Cannot convert value of type 'inout NSNumber?' to expected argument type 'AutoreleasingUnsafeMutablePointer<AnyObject?>' in some lines of code. Please help me to solve this issue because it is my first time to create a code to check whether the downloaded file is available in the icloud or not.
Please refer to the image below as sample of the error and also codes are available below for your reference. Hope you could help me. Thank you.
Sample screenshot of error
//-------------------------------------------------------------------
// ダウンロードできるか判定 Judgment or can be downloaded
//-------------------------------------------------------------------
func downloadFileIfNotAvailable(_ file: URL?) -> Bool {
var isIniCloud: NSNumber? = nil
do {
try (file as NSURL?)?.getResourceValue(&isIniCloud, forKey: .isUbiquitousItemKey)
if try (file as NSURL?)?.getResourceValue(&isIniCloud, forKey: .isUbiquitousItemKey) != nil {
if isIniCloud?.boolValue ?? false {
var isDownloaded: NSNumber? = nil
if try (file as NSURL?)?.getResourceValue(&isDownloaded, forKey: .ubiquitousItemIsDownloadedKey) != nil {
if isDownloaded?.boolValue ?? false {
return true
}
performSelector(inBackground: #selector(startDownLoad(_:)), with: file)
return false
}
}
}
} catch {
}
return true
}
It looks like you copied and pasted some really old code. Besides, this is Swift, not Objective-C. Do not use NSURL or getResourceValue. Your code should look more like this:
if let rv = try file?.resourceValues(forKeys: [.isUbiquitousItemKey]) {
if let isInCloud = rv.isUbiquitousItem {
// and so on
}
}
And so on; the same pattern applied to other keys. Note that there is no .ubiquitousItemIsDownloadKey either. You can condense things like this:
if let rv = try file?.resourceValues(
forKeys: [.isUbiquitousItemKey, .ubiquitousItemDownloadingStatusKey]) {
if let isInCloud = rv.isUbiquitousItem {
if let status = rv.ubiquitousItemDownloadingStatus {
if status == .downloaded {
}
}
}
}

Cannot access more than one value from function using PromiseKit Swift

TemplateClass.m
+ (AnyPromise *) promisefunctionReturnThreeValus:(NSString *)sampleName {
return [self anotherPromiseFunction:sampleName].then(^(NSMutableDictionary *sampleDict) {
DataArray *data = [DataArray dataArrayFromDict:sampleDict];
PropertyArray *property = [PropertyArray PropertyArrayFromDict:sampleDict];
if ([sampleDict objectForKey:NAME])
{
NameModel *name = [[NameModel alloc]initWithDictionary:[responseDict objectForKey:NAME]];
return (PMKManifold(data,property,name));
}
else
{
return (PMKManifold(data,property,nil));
}
});
}
well i can able to access this from objc using the below code
[TemplateClass promisefunctionReturnThreeValus:#"hello"].then(^(DataArray *data,PropertyArray *property,NameModel *name) {
//Here i can able to access the three values data,property and name
}
But when i try to access this from swift
TemplateClass.promisefunctionReturnThreeValus(sampleName: "hello").then{ data,property,name in
// it show me error " Contextual closure type '(Any?) -> AnyPromise' expects 1 argument, but 3 were used in closure body "
}
i can able to access only data but not the other two
i also tried debug it and print through log it show only the data of DataArray Object
lldb output
<DataArray : 0x1c0631340 count:1 value:{
"id" = 3631;
}
>

NSArray of NSRegularExpressions in swift

The fork here has a custom link function but the implementation in the actual code is in objective C.This is the code line and her it is printed again:
- (NSArray<NSRegularExpression*>*)getRegularExpressions
{
return [NSArray arrayWithObject:[NSRegularExpression regularExpressionWithPattern:#"#([a-zA-Z0-9])+" options:0 error:NULL]];
}
I was wondering how i could reproduce this in swift, I have already placed all of the framework code, I just need to know how to do this.
Try this
func getRegularExpressions() -> [NSRegularExpression] {
var arrayOfExpressions = [NSRegularExpression]()
do
{
let expresion = try NSRegularExpression(pattern: "#([a-zA-Z0-9])+", options:.CaseInsensitive)
arrayOfExpressions.append(expresion)
}catch _
{
arrayOfExpressions.removeAll()
return arrayOfExpressions
}
return arrayOfExpressions;
}
I hope this helps you

RLMException when calling callback closure

I am still trying to wrap my mind around on how to perform Realm queries with GDC.
I have this code in one of my classes:
class func placeNameForChatChannel(chatChannel: String, withCompletion handler: (String?)->()) {
dispatch_async(realmQueue) {
var channelEnvPredicate = NSPredicate(format: "channelName = %#", chatChannel)
var channelEnvs = PSTChannelEnvironment.objectsInRealm(realmdb, withPredicate: channelEnvPredicate)
if channelEnvs.count > 0 {
var channelEnvironment = channelEnvs[0] as! PSTChannelEnvironment
let placeName = channelEnvironment.placeName
handler(placeName)
} else {
handler(nil)
}
}
}
These two are declared as globals in my Application Delegate
var realmdb: RLMRealm {
return RLMRealm.defaultRealm()
}
var realmQueue = dispatch_queue_create("com.myapp.realmdb", DISPATCH_QUEUE_SERIAL)
I am getting the now infamous RLMException, reason: 'Realm accessed from incorrect thread when the handler callback is getting called.
What am I doing wrong?
You need to make sure that you recreate the RLMRealm on every dispatch to a GCD queue. If, instead of using that realmdb, you use RLMRealm.defaultRealm(), do things work?

Resources