Closed achirkof closed 7 years ago
I'm not sure why this would be happening. From the stack trace, it looks like the problem might your NSDictionary property, not the boolean. Try omitting that property and see if it works. If it does, we know what to focus on.
@siegesmund I think it is not to my NSDictionary property for var workoutExercises: NSDictionary?
because if I change it for String/Dictionary or somthing else I get the same error and stack. I think it might be linked to MeteorDocument
class
public class MeteorDocument : NSObject {
required public init(id: String, fields: NSDictionary?)
public func update(fields: NSDictionary?, cleared: [String]?)
}
What do you think?
So.. After debugging and manipulate variable types in collection I found right combination:
class Workouts: MeteorDocument {
var _id: String?
var createdBy: String?
var createdAt: NSDate?
var workoutName: String?
var workoutDesc: String?
var workoutDuration: String?
var workoutExercises: NSDictionary?
var isPrivate: AnyObject?
var isDeleted: AnyObject?
}
I's interesting because variables isPrivate
and isDeleted
boolean, but then I receive a response these are not.
Glad you got it working. In your subscription, isPrivate and isDeleted are both integers, not bools. It appears Meteor is sending them as integers, if I am understanding what you've posted. Can you just create a handler that corrects for that?
@siegesmund Yes, Meteor return Int value(0 or 1). And I tried to set variable type for isPrivate
& isDeleted
to optional Int, but it didn't help. About handler, I'm novice in swift and don't know how to do it yet.
@achirkof What does the console show when you print isPrivate or isDeleted?
Here is my collection class:
import UIKit
import SwiftDDP
class Workouts: MeteorDocument {
var id: String?
var createdBy: String?
var createdAt: NSDate?
var workoutName: String?
var workoutDesc: String?
var workoutDuration: NSNumber?
var workoutExercises: [[String: AnyObject]]?
var isPrivate: AnyObject?
var isDeleted: AnyObject?
}
Document from MongoDB collection:
{
"_id" : "NRZiZBB8ruGneytFh",
"workoutName" : "Test",
"workoutDesc" : "<p>Description</p>",
"createdBy" : "BeNTtaupkj5JfpJcH",
"createdAt" : ISODate("2016-04-21T11:54:52.949Z"),
"isPrivate" : true,
"isDeleted" : false
}
My ViewController
code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let workouts = MeteorCollection<Workouts>(name: "workouts")
Meteor.subscribe("workouts") {
let workout = workouts.findOne("NRZiZBB8ruGneytFh")
print("WORKOUT: \(workout)")
print("WORKOUT IS DELETED VALUE: \(workout?.isDeleted)")
print("WORKOUT IS PRIVATE VALUE: \(workout?.isPrivate)")
}
}
And message I received:
Subscribing to ID 2a082CB79e7A44ED9E0bA15a93db7b68
[Debug] [DDP] [DDP Background Data Queue :: NSOperation 0x7fe3bc0a0480 (QOS: BACKGROUND)] [260] ddpMessageHandler > Received message: {
msg = ready;
subs = (
2a082CB79e7A44ED9E0bA15a93db7b68
);
}
WORKOUT: nil
WORKOUT IS DELETED VALUE: nil
WORKOUT IS PRIVATE VALUE: nil
[Debug] [DDP] [DDP Background Data Queue :: NSOperation 0x7fe3b9ff1c50 (QOS: BACKGROUND)] [260] ddpMessageHandler > Received message: {
collection = workouts;
fields = {
createdAt = {
"$date" = 1461239692949;
};
createdBy = BeNTtaupkj5JfpJcH;
isDeleted = 0;
isPrivate = 1;
workoutDesc = "<p>Description</p>";
workoutExercises = (
{
"_id" = mQdCocGXeHQhnpKjh;
exerciseDesc = "<li>\U0421\U044f\U0434\U044c\U0442\U0435 \U043d\U0430 \U043f\U043e\U043b. \U0420\U0430\U0441\U0441\U0442\U0430\U0432\U044c\U0442\U0435 \U043d\U043e\U0433\U0438 \U043f\U0435\U0440\U0435\U0434 \U0441\U043e\U0431\U043e\U0439.</li><li>\U0412\U044b\U0442\U044f\U043d\U0443\U0432 \U0440\U0443\U043a\U0438 \U043f\U0430\U0440\U0430\U043b\U043b\U0435\U043b\U044c\U043d\U043e \U043f\U043e\U043b\U0443, \U043d\U0430\U043a\U043b\U043e\U043d\U0438\U0442\U0435\U0441\U044c \U0432\U043f\U0435\U0440\U0435\U0434, \U043d\U0430\U0441\U043a\U043e\U043b\U044c\U043a\U043e \U044d\U0442\U043e \U0432\U043e\U0437\U043c\U043e\U0436\U043d\U043e. \U0417\U0430\U0434\U0435\U0440\U0436\U0438\U0442\U0435\U0441\U044c \U0432 \U044d\U0442\U043e\U043c \U043f\U043e\U043b\U043e\U0436\U0435\U043d\U0438\U0438 \U043d\U0430 10-20 \U0441\U0435\U043a\U0443\U043d\U0434.</li>";
exerciseImgs = (
{
"_collectionName" = exerciseImages;
"_downloadRoute" = "/cdn/storage";
"_id" = g8HBqxNmwjnX2Srws;
"_prefix" = f18fc795aff7bc461588902a7840de5674a3cffabf709dc39af62a6022f4ebd0;
"_storagePath" = "/tmp/uploads/exercise-images";
extension = jpg;
isAudio = 0;
isImage = 1;
isVideo = 0;
meta = {
};
name = "418_1-300x200.jpg";
path = "/tmp/uploads/exercise-images/evBlwkiWRGYiWhqwV.jpg";
size = 14914;
type = "image/jpeg";
versions = {
original = {
extension = jpg;
path = "/tmp/uploads/exercise-images/evBlwkiWRGYiWhqwV.jpg";
size = 14914;
type = "image/jpeg";
};
};
},
{
"_collectionName" = exerciseImages;
"_downloadRoute" = "/cdn/storage";
"_id" = xzhiiuAQ7TwKSS5rq;
"_prefix" = f18fc795aff7bc461588902a7840de5674a3cffabf709dc39af62a6022f4ebd0;
"_storagePath" = "/tmp/uploads/exercise-images";
extension = jpg;
isAudio = 0;
isImage = 1;
isVideo = 0;
meta = {
};
name = "418_2-300x200.jpg";
path = "/tmp/uploads/exercise-images/LEODojbWdxGJAqOcj.jpg";
size = 14914;
type = "image/jpeg";
versions = {
original = {
extension = jpg;
path = "/tmp/uploads/exercise-images/LEODojbWdxGJAqOcj.jpg";
size = 14914;
type = "image/jpeg";
};
};
}
);
exerciseName = "\U0420\U0430\U0441\U0442\U044f\U0436\U043a\U0430 \U043c\U044b\U0448\U0446 \U0432 \U043f\U043e\U043b\U043e\U0436\U0435\U043d\U0438\U0438 \U0441\U0438\U0434\U044f";
mainMuscle = "\U0411\U0435\U0434\U0440\U0430";
mechanicsType = "\U0414\U0440\U0443\U0433\U043e\U0435";
}
);
workoutName = Test;
};
id = NRZiZBB8ruGneytFh;
msg = added;
}
Maybe I'm doing something wrong because I receive nil
.
And you've tried:
class Workouts: MeteorDocument {
var _id: String?
var createdBy: String?
var createdAt: NSDate?
var workoutName: String?
var workoutDesc: String?
var workoutDuration: String?
var workoutExercises: NSDictionary?
var isPrivate: Bool?
var isDeleted: Bool?
}
?
Yes. It was first what i'v tried. But as you can see Meteor return 1 and 0.
Now I receive nil
not only for separate fields but for whole document and I can't understand why.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let workouts = MeteorCollection<Workouts>(name: "workouts")
Meteor.subscribe("workouts") {
let workout = workouts.findOne("NRZiZBB8ruGneytFh")
print("WORKOUT: \(workout)")
print("WORKOUT IS DELETED VALUE: \(workout?.isDeleted)")
print("WORKOUT IS PRIVATE VALUE: \(workout?.isPrivate)")
}
}
and print
Subscribing to ID 2a082CB79e7A44ED9E0bA15a93db7b68
[Debug] [DDP] [DDP Background Data Queue :: NSOperation 0x7fe3bc0a0480 (QOS: BACKGROUND)] [260] ddpMessageHandler > Received message: {
msg = ready;
subs = (
2a082CB79e7A44ED9E0bA15a93db7b68
);
}
WORKOUT: nil
WORKOUT IS DELETED VALUE: nil
WORKOUT IS PRIVATE VALUE: nil
But as you can see in my previous message document with this ID exists.
The same situation for let workout = workouts.sorted
. It returns empty array []
.
Hi @achirkof, is this problem still unsolved?
I think you have to implement the init init(id: String, fields: NSDictionary?) and the override func setValue(value: AnyObject?, forKey key: String) methods in your MeteorDocument to set the variables correctly. Here is an example;
`import Foundation import SwiftDDP
class DocumentUser: MeteorDocument {
var _id: String?
var services: NSMutableDictionary?
var emails: NSMutableArray?
var roles: NSMutableArray?
var profile: [String:AnyObject]?
required init(id: String, fields: NSDictionary?) {
super.init(id: id, fields: fields)
self._id = id
}
override func update(fields: NSDictionary?, cleared: [String]?) {
super.update(fields, cleared: cleared)
}
override func setValue(value: AnyObject?, forKey key: String) {
if (key == "_id") {
self._id = value as? String
}
if (key == "services") {
self.services = value as? NSMutableDictionary
}
if (key == "emails") {
self.emails = value as? NSMutableArray
}
if (key == "roles") {
self.roles = value as? NSMutableArray
}
if (key == "profile") {
self.profile = value as? [String:AnyObject]
}
}
}`
If you still can't get it to work I can help you out via Teamviewer or Screenhero.
Sorry for commenting such an old issue, but I just ran into that too.
However, there is no need to overwrite "setValue" and bloat your code. Just add @objc before the vars of your MeteorDocument, e.g.:
class Workouts : MeteorDocument {
@objc var createdBy? ...
}
This way, the Objective-C setValue mechanism still works with newer Swift versions.
This probably should be added to the README
Hello! I can't subscribe to publication like this: Meteor publication
Swift class:
I trying to get document:
But receive a crush just after call
Meteor.subscribe("workouts")
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFBoolean length]: unrecognized selector sent to instance 0x10300a528'
I thing the reason of crush is in fieldsisPrivate
andisDeleted
because there are boolean in Mongobut subscribtion retun's it as string or integer.
Here the stack trace:
I have tried to change type of fields
isPrivate
andisDeleted
in Swift class to optional Bool/String/Int without any results.