Could not init a PFObject subclass - ios

After upgrading to Xcode 6.3 6D570 (and Swift 1.2), the init of a subclassed object does not compile.
Let's say I have a class called Armor, which inherits from PFObject, PFSubclassing (exactly as Parse documentation says).
When I try to create an instance, like var armor = Armor(), I get the following compile error:
Missing argument for parameter 'className' in call
Then I read in Parse docs that I should use the 'object' class method to init a subclassed object. So I tried to init like this: var armor = Armor.object().
But then I get the following compile error:
'object()' is unavailable: use object construction 'PFObject()'
I'm using Parse SDK version 1.7.1.
I also override the parseClassName method as follows:
class func parseClassName() -> String {
return "Armor"
}
I registered the subclass inside the initialise method and on app delegate before I setup Parse:
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
How should I properly init a subclassed object?

=========================================================================
THIS HAS BEEN FIXED IN 1.7.3 PARSE SDK
You can download the new version here:
https://parse.com/docs/downloads
=========================================================================
Though docs are not clear on that, using .object() in Swift is not required anymore.
as said here and in the Swift code snippet found here
Now, this is weird but to make Armor() work you need to reference PFUser class somehow in the same file. Maybe it doesn't have to be PFUser but I havent dug deeper into it.
So, this won't work
import UIKit
import Parse
import Bolts
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "clientKey")
let myArmor = Armor()
return true
}
}
But this will
import UIKit
import Parse
import Bolts
private let fix = PFUser.hash() // here's the weird trick
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "clientKey")
let myArmor = Armor()
return true
}
}
Hope this helps and Parse pushes a fix out soon.
Also reported as a bug

register the class as a subclass in the AppDelegate, but before Parse.initialize is called.
Then you can delete the overwritten function initialize
This would make:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]!) -> Bool {
Armor.registerSubclass()
// Further initialization
return true
}
then just initialize the class by calling the constructor:
var myArmor = Armor()

Related

Swift leaks when using generic closure function with Double

I have a simple array that holds generic functions. If store some listeners in this array I have a strange problem with leaks. I can use it without any problem with generic types of any kind but Optional Numeric types. If I use Double? for example I have a memory leak. Also problem only occurs when I capture unowned/weak self. Can someone explain me why this leak appear and how to fix this?
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var observations = [(Double?) -> Void]()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
observations.append { [unowned self] (new) in
print(self)
}
return true
}
}
If I change observations to [(String?) -> Void](), then there is no problem.

Declaring variable outside the class vs inside

Hey I am trying to initialise a realm object in my app outside the app delegate.
Now, Since a lot of file in my app are accessing the realm file, i decide to declare it globally.
Now, by doing that I got an app rejection, reasoning crash due to this object. My code is as follows
AppDelegate.swift
import UIKit
import RealmSwift
var uiRealm = try! Realm()
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return true
}
In the above code the object is initialised as the app starts and any other methods loads.
Is it possible that I just declare an object or type Realm and the initialise it under didFinishLaunching as follows:
import UIKit
import RealmSwift
var uiRealm : Realm!
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// I initialise it here
uiRealm = try! Realm()
return true
}
Will it make a difference if its declare in such form. I am a little timid about this.
Any help is highly appreciated.
P.S: I already tried declaring the realm variable in app delegate and the calling it in other classes by UIapplication.shared.delegatemethod, and it always crashes.

AppConnect Error : AppConnect cannot be instantiated directly

I am trying to Access the MDM using AppConnect SDK in swift 1.2 but it is giving following error :
[AppConnect:Error] AppConnect cannot be instantiated directly.
Instead, call +initWithDelegate: and then +sharedInstance.
Code Snippet :
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, AppConnectDelegate {
var window: UIWindow?
var appct = AppConnect()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
// Initialize the AppConnect library
AppConnect.initWithDelegate(self)
self.appct = AppConnect.sharedInstance()
self.appct.startWithLaunchOptions(launchOptions)
return true
}
}
Application is crashing while accessing the Keys of MobileIron Backend Config file.
Any other way to implement this?
You are initializing AppConnect without delegate
change
var appct = AppConnect();
to
var appct : AppConnect!;
My solution was to set a new key/value in the plist:
Principal class AppConnectUIApplication
or in source mode:
<key>NSPrincipalClass</key>
<string>AppConnectUIApplication</string>
Hope it help you

Extending UIApplicationDelegate Protocol

I would like to extend UIApplicationDelegate protocol and provide a default implementation for application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool method. However, default implementation I have provided does not get called.
Is it possible at all to extend UIApplicationDelegate protocol (with relation to UIApplication being a singleton, or protocol method being an optional), or am i doing something wrong?
thanks
AppDelegate.swift:
import UIKit
extension UIApplicationDelegate{
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
print("does not print anything on launch.")
return true
}
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
}
turns out you can't provide default implementations for Objective-C protocols via extensions. See below link for detailed list of limitations on protocol extensions.
https://www.captechconsulting.com/blogs/ios-9-tutorial-series-protocol-oriented-programming-with-uikit
What we CAN'T do: Provide default implementations for Objective-C protocols.
I ran into the same problem and for this particular file I reverted to Objective-C to achieve this functionality.
#import <UIKit/UIKit.h>
#interface NSObject (BasicMethods) <UIApplicationDelegate>
#end
with
#import "UIApplicationDelegate+BasicMethods.h"
#implementation NSObject (BasicMethods)
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(#"I'm getting called");
}
#end
works.
There is no use of doing extension for protocols.
Reasons are:
Protocol contains only function declaration but extension needs function definition.
Protocol is nothing but just set of rules(methods). It doesn't allocate any memory.
Protocol function definitions will be in delegate class. So function call will never comes to function definition which you
written in extension.

Chartboost delegate error

I am integrating chartboost into my sprite kit game and have successfully integrated bridging files into my swift code. Now in my app delegate I have the following:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let kChartboostAppID = "5554c8680d60255c6a0f4af4"
let kChartboostAppSignature = "1d0e271cd054c9a63473d2f1212ca33a2922a19f"
Chartboost.startWithAppId(kChartboostAppID, appSignature: kChartboostAppSignature, delegate: self)
Chartboost.cacheMoreApps(CBLocationHomeScreen)
return true
}
class func showChartboostAds()
{
Chartboost.showInterstitial(CBLocationHomeScreen);
}
func didFailToLoadInterstitial(location: String!, withError error: CBLoadError) {
}
the startWithId line gives me an error that it cant invoke this method with these arguments ( String, String, AppDelegate). This used to work fine on my objective c code.. Anyone knows how to fix this?
class AppDelegate: UIResponder, UIApplicationDelegate, ChartboostDelegate
Edit (from Lalit's comment below)
In startWithAppId the delegate is set to self, so you have to set the class AppDelegate as the delegate, which is done using:
ChartboostDelegate(protocol)

Resources