I'm getting the following error:
Type 'TestClass' does not conform to protocol 'NSCoding'
There's only two methods required for NSCoding and both are there. What am I missing?
class TestClass: NSObject, NSCoding {
var Property1:Double? = 0.00
required init(code aDecoder: NSCoder) {
if let priceCoded = aDecoder.decodeObjectForKey("Property1") as? Double {
self.Property1 = priceCoded
}
}
func encodeWithCoder(aCoder: NSCoder){
if let priceEncoded = self.Property1 {
aCoder.encodeObject(priceEncoded, forKey: "Property1")
}
}
}
You missed 'r' symbol in an argument name. Update your initializer name to:
required init(coder aDecoder: NSCoder)
And it will work
I am solving this by using this :-
required init?(coder aDecoder: NSCoder) {
}
func encodeWithCoder(aCoder: NSCoder) {
}
XCode 8.0 (8A218a) , swift 3
Related
I have a macOS storyboard app in which I am having a SwiftUI view which hosted using an NSHostingController. I need to pass an EnvironmentObject to this SwiftUI view from my NSHostingController. I am unable to achieve this. I have currently written this code but it does not work. What could be the issue here?
import Cocoa
import SwiftUI
class SearchText: ObservableObject {
#Published var text = ""
}
class HostingController: NSHostingController<SwiftUIView> {
#objc required dynamic init?(coder: NSCoder) {
super.init(coder: coder, rootView: SwiftUIView().environmentObject(SearchText()))
}
}
The issue is that modifier .environmentObject returns different type than you specify in generics, ie SwiftUIView.
Here is possible approach
class HostingController: NSHostingController<AnyView> {
#objc required dynamic init?(coder: NSCoder) {
super.init(coder: coder, rootView:
AnyView(SwiftUIView().environmentObject(SearchText())))
}
}
Alternate: (Xcode 13.4)
class HostingController: NSHostingController<HostingController.HelperView> {
struct HelperView: View {
var body: some View {
SwiftUIView().environmentObject(SearchText())
}
}
#objc required dynamic init?(coder: NSCoder) {
super.init(coder: coder, rootView: HelperView())
}
}
EXC_BAD_ACCESS occurs when I access (read or rewrite) property of class instance.
class MyUIImageView:UIImageView {
required init?(coder aDecoder: NSCoder) {
fatalError()
}
var hand: String = ""
}
#IBOutlet weak var myInstance: MyUIImageView!
func rewrite() {
...
myInstance.hand = "..." // Error!
}
func read() {
...
var tmp: String = myInstance.hand // Error!
}
Do you know how to fix this error?
・2016/1/31
Unknown class MyUIImageView in Interface Builder was found in log, and Module field of Custom Class is "None".
either myInstance isn't set or myInstance isn't a MyUIImageView
I've just updated my code from Swift 1.2 to Swift 2.1. The project was fully-functioning with previous version of Swift, but now I'm seeing "Ambiguous use of 'init'" errors. Each occurrence of this error seems to be caused by the use of optional arguments in the constructor. I've even managed to reproduce this issue in Xcode Playground with the following simplified code using the same pattern:
class Item : UIView {
override init(frame: CGRect = CGRectZero) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let i = Item() # Ambiguous use of 'init(frame:)'
However, I still don't understand why Swift 2.1 now has a problem with this pattern, or what the alternative should be. I've tried searching for this, but all I've stumbled upon was "ambiguous use" errors for other (non-constructor) methods due to method renaming or signature changing, neither of which is the case here.
It's ambiguous use because when u call let i = Item(), there are 2 options -
the init(frame: CGRect = CGRectZero) and the init()
it's better to do something like this:
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init() {
self.init(frame: CGRectZero)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
I am learning Swift and I have a compile error:
class ListScansVC: UIViewController {
#IBOutlet weak var tableView: UITableView!
internal var scans: [Scan]
internal var dataSource: ListScanDataSource
init(scans: [Scan]){
self.scans = scans
dataSource = ListScanDataSource.init(scans: scans)
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource.registerReusableViewsForTableView(tableView)
}
}
In another ViewController i am doing:
override func viewDidLoad() {
super.viewDidLoad()
let scan = Scan(title : "Ticket", scanDate: NSDate())
let listScanVC = ListScansVC.init(scans: [scan])
self.displayChildContent(ListScansVC)
}
func displayChildContent(content : UIViewController){
self.addChildViewController(content)
self.view.addSubview(content.view)
content.didMoveToParentViewController(self)
}
The error is:
"Cannot convert value of Type 'ListScansVC.Type' to expected argument type 'UIViewController'"
An init method in Swift like
init(scans :[Scan]){)
has be be called with
let listScanVC = ListScansVC(scans: [scan])
in the next line you have to pass the instance (starting with a lowercase letter) rather than the type
self.displayChildContent(listScanVC)
I'd recommended to use more distinctive names to avoid that type/instance confusion.
Say I have a class like this one:
class UniverseViewController: UITableViewController {
var model = createModel()
// blah, blah...
}
When exactly will the createModel function be called? Before the init? After it?
It is called before init and viewDidLoad etc.
The following code:
struct testStruct {
init() {
println("testStruct")
}
}
let tempValue = testStruct()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
println("Coder")
}
override func viewDidLoad() {
super.viewDidLoad()
println("viewDidLoad")
}
will give us the following output:
testStruct
Coder
viewDidLoad