Create an app lifetime object (not possible to be deallocated) in Swift - ios

I want to create an object from a class. And I want it life time to be the app life time. I mean I want it not be deallocated since the app is running.
the class that I want to make an instance from:
extension Post {
#NSManaged var userId: Int
#NSManaged var id: Int
#NSManaged var title: String
#NSManaged var body: String
}
class Post: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
override func awakeFromInsert() {
super.awakeFromInsert()
title = ""
userId = 0
id = 0
body = ""
}
}

An object that keeps a strong pointer to itself cannot be deallocated:
class Permanent {
private var ref: Permanent?
init() {
ref = self
}
deinit {
// This will never be called
print("Permanent deinit")
}
}
func test() {
var a = [Permanent(), Permanent()]
print(a.count)
print("free the items")
a = []
print("end of test")
}
test()
Output:
2
free the items
end of test
If you comment out the ref = self line:
Output:
2
free the items
Permanent deinit
Permanent deinit
end of test

Related

How do I make an Rx subject react to new elements added to the array?

I would like my subject to observe changes on myArray so every time a new element is appended to myArray the subscription fires.
var subject = PublishSubject<[String]>()
var myArray = ["One", "Two"]
subject.flatMap{Observable.from($0)}.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext(myArray)
myArray.append("Three")
subject.onNext(myArray)
it works by adding myArray to onNext every time it changes, but is there a way for the subscription to trigger automatically when myArray gets a new element without using onNext? Perhaps by making myArray into an observable?
This is a great time to take advantage of property wrappers. Be careful that you don't use this in a struct though.
#propertyWrapper
class RxPublished<Element> {
private let subject: BehaviorSubject<Element>
init(wrapped: Element) {
subject = BehaviorSubject(value: wrapped)
}
deinit {
subject.onCompleted()
}
var wrappedValue: Element {
get { try! subject.value() }
set { subject.onNext(newValue) }
}
var projectedValue: Observable<Element> {
subject.asObservable()
}
}
class MyClass {
#RxPublished(wrapped: ["One", "Two"]) var myArray: [String]
}
func example() {
let foo = MyClass()
_ = foo.$myArray
.debug("foo.myArray")
.subscribe()
foo.myArray.append("Three")
}

Private variables in swift

When creating a class, what is the difference between these 2 implementations of creating a custom class in regards to security. They both work the exact same as far as I've used them, but have heard using private variables is the proper way to create classes
class Person {
var name:String
var age:Int
init(name: String, age: Int){
self.name = name
self.age = age
}
}
and
class Person {
private var _name: String
private var _age: Int
var name: String {
set {
self._name = newValue
} get {
return _name
}
}
var age: Int {
set {
self._age = newValue
} get {
return _age
}
}
init(name: String, age: Int){
self._name = name
self._age = age
}
}
private is definitely recommended to use but only in cases when you want that kind of privacy for your properties.
Your second code is not ensuring any kind of privacy. That's just adding more code unnecessarily.
There can be a scenario where you want to keep the write access private to the type (class/struct) and allow read access outside the type. For that you can use private(set) access modifier with your properties, i.e.
class Person {
private(set) var name: String
private(set) var age: Int
init(name: String, age: Int){
self.name = name
self.age = age
}
}

Realm: nested update issue for many to one relation

I am using Realm notification block for updating messages in a page.
let messageResult = realm.Object(MessageRealm.self)
notificationTokenMessage = messageResult.addNotificationBlock{ [weak self] (changes: RealmCollectionChange) in {
switch changes {
case .initial(_),
.update(_, _, _, _):
self?.tableView.reloadData()
default:
break
}
}
}
In MessageRealm class, there is a property, name author. An author is basically a UserRealm object.
Class MessageRealm extends Object {
dynamic var _id: String? = nil
dynamic var body: String? = nil
dynamic var author: UserRealm? = nil
override class func primaryKey() -> String? { return "_id" }
}
Class UserRealm extends Object {
dynamic var _id: String? = nil
dynamic var fullName: String? = nil
dynamic var status: String? = nil // 'online' or 'offline'
override class func primaryKey() -> String? { return "_id" }
}
When a new message is received from socket, the message page is updated as it gets notifications from Realm. But, when user update notification is received from socket, the Realm updates the message page. I don't want to update message page for an update in author object.
Probable Solutions:
Class MessageRealm extends Object {
dynamic var _id: String? = nil
dynamic var body: String? = nil
dynamic var author: UserRealm? = LinkingObjects(fromType: UserRealm.self, property: "messages")
override class func primaryKey() -> String? { return "_id" }
}
Class UserRealm extends Object {
dynamic var _id: String? = nil
dynamic var fullName: String? = nil
dynamic var status: String? = nil // 'online' or 'offline'
let messages = List<MessageRealm>()
override class func primaryKey() -> String? { return "_id" }
}
We can solve it using LinkingObjects. But, this inverse relation needs a direct relation to map. Am I right? So, need to have a property of List of Messages in User. And from MessageRealm I have to link to User. But this will be complicated to maintain.
Store author's id in MessageRealm as a foreign key like a traditional database.
What do you suggest?
How can we do normalization in Realm to avoid update issue?
Is there any convention or best practices to manage a bigger database? (I am aware of Tim's answer https://stackoverflow.com/a/31594548/2666902 )
In my opinion, the best solution would be keeping the author property as a one-to-one relationship from MessageRealm to UserRealm, since a single message can only have one author and creating an inverse relationship in UserRealm.
class MessageRealm: Object {
dynamic var _id: String? = nil
dynamic var body: String? = nil
dynamic var author: UserRealm? = nil
override class func primaryKey() -> String? { return "_id" }
}
class UserRealm: Object {
dynamic var _id: String? = nil
dynamic var fullName: String? = nil
let messages = LinkingObjects(fromType: MessageRealm.self, property: "author")
override class func primaryKey() -> String? { return "_id" }
}
This way, you only need to keep the author property of your messages updated and the messages property of UserRealm will automatically keep in sync, so any time you try to access it, you will see all MessageRealm objects, where the author equals the specific user.

iOS swift singleton clear data

class ShareData {
class var sharedInstance: ShareData {
struct Static {
static var instance: ShareData?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = ShareData()
}
return Static.instance!
}
var someString : String! //Some String
var selectedTheme : AnyObject! //Some Object
var someBoolValue : Bool!
}
This is my singleton design.However , I want to know how I can clear all its data as and when required?
Also can i have more than one singleton Class??
Since you've only got 3 properties on your singleton it would be far easier just to set up a method that nils each property in turn.
Once you start getting in to how to destroy and recreate your singleton, you get in to the realm of do you actually even want a singleton or should you just be using a regular object.
You are creating a Singleton with the syntax available in... 2014
Today there's a better syntax to define a Singleton class
final class SharedData {
static let sharedInstance = SharedData()
private init() { }
var someString: String?
var selectedTheme: AnyObject?
var someBoolValue: Bool?
func clear() {
someString = nil
selectedTheme = nil
someBoolValue = nil
}
}
As you can see I also added the clearData() method you were looking for.

iOS - Trouble saving subclass to Parse backend

I've been trying to implement Parse in my application and can't seem to get my Subclass to save to the backend. I've been using the guides provided by Parse here and here but still can't get it to work.
My Subclass looks like this:
import Foundation
import Bolts
import Parse
class Fillup : PFObject, PFSubclassing {
#NSManaged var username: String?
#NSManaged var amount: String?
#NSManaged var cost: String?
#NSManaged var date: NSDate?
#NSManaged var location: CLLocation?
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
static func parseClassName() -> String {
return "Fillup"
}
Accessing the variables works fine using let x = fillup.amount as String!.
However, in my save method the variables always end up being nil.
Here's a small example from my save method:
#IBAction func saveTapped(sender: AnyObject) {
// instantiate new Fillup object
var fillup :Fillup?
//check for nil on variables
if let username = PFUser.currentUser()?.username {
println(username)
fillup?.username = username
}else{
println("Username is nil.")
}
println(fillup?.username)
//save object to backend
fillup?.saveInBackgroundWithBlock({ (success, error) -> Void in
if error != nil {
println("Error: " + error!.localizedDescription)
}else{
println("Fillup saved!")
}
})
}
The output always looks like:
mforrest3
nil
and as the variable is nil it doesn't save successfully to the backend.
I've not included the code for the other variables for simplicity's sake however I think this should still work.
If anyone could point me in the direction of a good guide or help me come up with an answer/reason that would be great.
This line
var fillup :Fillup?
Is not creating a new instance, it's just defining an optional local variable of the appropriate type. You should have
var fillup = Fillup.object()
To actually call the constructor for the class (and allow the compiler to determine the class in this case)

Resources