Swift Framework Class to Swift Application - ios

Getting problem with adding my Swift Framework to Test Swift Application.
What i have:
Framework class code, Target Called 'Project':
public let Instance = Library()
public class Library {
public class var sharedInstance: Library {
return Instance
}
/* SOME CODE */
}
Than i build it and add Project.framework to Test Swift Application
Usage:
import Project
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
/* NOT WORKING
ERROR: Use of Unresolved Identifier 'Instance' */
Instance.Setup("d573732b9f8b478d",apiKey: "3XmdIY=", enablePush: true)
/* NOT WORKING TOO
ERROR: Use of Unresolved Identifier 'Library' */
let lib = Library()
return true
}
Functions public, DeviredData deleted, what i'm doing wrong?

Answer was very easy:
Adding constructor function
public init(){
}
Problem solved.

Yes, making public constructor will help you, as per my knowledge default constructor has internal scope. It works for me.
public override init() {
}

Related

Typhoon Dependency Injection and Swift 3: Appdelegate isn't AnyObject

This code works with Typhoon Dependency Injection library (Obj-C) in Swift 2.3 but doesn't in Swift 3:
AppDelegate:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var rootViewController: RootViewController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = self.rootViewController
self.window?.makeKeyAndVisible()
return true
}
...
}
Application Assembly:
public class ApplicationAssembly: TyphoonAssembly {
public dynamic func config() -> AnyObject {
return TyphoonDefinition.withConfigName("Configuration.plist")
}
public dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
(definition) in
definition!.injectProperty(#selector(ApplicationAssembly.rootViewController), with: self.rootViewController())
}
}
...
}
However the following error is displayed in ApplicationAssembly for any Swift 3 file expected to return 'AnyObject':
"No 'withClass' candidates produce the expected contextual result type 'AnyObject'
Might anyone have an insight into the incompatibility of the Obj-c Typhoon code base with Swift 3?
Screen capture of error line
You may want to switch the return type from AnyObject to Any.
The withClass function returns an id type in Objective-C, see the source code:
+ (id)withClass:(Class)clazz block:(TyphoonBlockDefinitionInitializerBlock)block;
The id type used to be mapped to AnyObject in Swift 2, but in Swift 3 it's mapped to Any for increased flexibility. You can read more about this change here.

Storyboards + generics = inline initializers not called?

I'm looking for an explanation of why the following prints false when run on iOS. The view controller is instantiated from a dead-simple Storyboard which just contains a single table view.
I'm using the preloading trick suggested by https://stackoverflow.com/a/33658528/1919412 to allow Interface Builder to find the MyTableViewController class. I'm sure that has something to do with the problem, but I'd like to better understand what's going on.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
// If we don't create this dummy instance before our real view controller gets loaded from storyboard, we get this error:
// "Unknown class _TtC21ViewControllerInitBug21MyTableViewController in Interface Builder file."
// See: https://stackoverflow.com/a/33658528/1919412
let foo = MyTableViewController()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
}
class Foo<T>:UITableViewController {
init() {
super.init(style:.Plain)
}
}
class MyTableViewController:Foo<String> {
private var foo = true
override func viewDidLoad() {
super.viewDidLoad()
print(self.foo)
}
}

Subclass of subclass of PFObject not being registered

I have a class called Attendee which inherits from PFObject. I also have another class called Speaker which is a child of Attendee.
Below are the class definition for Attendee & Speaker
class Attendee: PFObject, PFSubclassing {
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return "Attendee"
}
}
class Speaker: Attendee {
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
}
I register both in my applicationDidFinishLaunch method before using any parse features:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Speaker.initialize()
Attendee.initialize()
Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)
...
}
However, when I try to use the Attendee and Speaker classes later on in my code, I get this error:
The class MedConf.Attendee must be registered with registerSubclass before using Parse.
The code that triggers the error is:
var attendee = Attendee()
I don't understand why this is happening, as I clearly register both the subclasses before I do anything with them.
My bet is you can't subclass any class the implements a PFSubclassing protocol. Try making the Speaker it's own class and build the relationship use the relationship API in Parse. If you need a resource to build relational data, check here. https://www.parse.com/docs/ios/guide#objects-relational-data

Parse SDK and Swift 1.2: Can´t subclass PFUser

Before updating to Swift 1.2 subclassing PFUser worked just fine, now I can´t make it work.
My custom PFUser-class:
public class CustomUser: PFUser, PFSubclassing {
#NSManaged var fullName : String!
#NSManaged var phone : String!
public override class func initialize(){
self.registerSubclass()
}
}
When I use this class in my code the method calls still goes to the PFUser class:
reason: '-[PFUser fullName]: unrecognized selector sent to instance
0x17018fbe0'
This behavior started with Swift 1.2. I´ve updated the Parse SDK to the lastest version as well.
I've just been through this. The change in behaviour is a huge pain. You need to register your subclasses before you set your Parse app ID (typically in your application delegate).
So, in your app delegate...
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
CustomUser.registerSubclass()
Parse.setApplicationId("XXX", clientKey: "YYY")
......
return true
}
Another solution seems to be a singleton, provided in the Parse manual as follows, which works without any problems. This code works for all subclasses not only PFUser. If done this way, there is no need to register the subclass in didFinishLaunchingWithOptions.
class User: PFUser, PFSubclassing {
// MARK: PFUser Subclassing
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
// non essential code removed
}

How to pass swift enum with #objc tag

I need to define a protocol which can be called in a class that use some Objective-c type
But doing that doesn't work:
enum NewsCellActionType: Int {
case Vote = 0
case Comments
case Time
}
#objc protocol NewsCellDelegate {
func newsCellDidSelectButton(cell: NewsCell, actionType: NewsCellActionType)
}
You get he error
Swift enums cannot be represented in Objective-C
If I don't put the #objc tag on my protocol it'll crash the app as soon as it's called in a class which adopt the protocol AND inherit from an Objective-C type class (like a UIViewController).
So my question is, how should I declare and pass my enum with the #objc tag?
Apple just announced today that Swift 1.2 (included with xcode 6.3) will support exposing enums to objective-c
https://developer.apple.com/swift/blog/
Swift enums are very different from Obj-C (or C) enums and they can't be passed directly to Obj-C.
As a workaround, you can declare your method with an Int parameter.
func newsCellDidSelectButton(cell: NewsCell, actionType: Int)
and pass it as NewsCellActionType.Vote.toRaw(). You won't be able to access the enum names from Obj-C though and it makes the code much more difficult.
A better solution might be to implement the enum in Obj-C (for example, in your briding header) because then it will be automatically accessible in Swift and it will be possible to pass it as a parameter.
EDIT
It is not required to add #objc simply to use it for an Obj-C class. If your code is pure Swift, you can use enums without problems, see the following example as a proof:
enum NewsCellActionType : Int {
case Vote = 0
case Comments
case Time
}
protocol NewsCellDelegate {
func newsCellDidSelectButton(cell: UITableViewCell?, actionType: NewsCellActionType )
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, NewsCellDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()
test()
return true;
}
func newsCellDidSelectButton(cell: UITableViewCell?, actionType: NewsCellActionType) {
println(actionType.toRaw());
}
func test() {
self.newsCellDidSelectButton(nil, actionType: NewsCellActionType.Vote)
}
}

Resources