16

I've just spent half a day trying to solve next problem. I am testing the CoreData using Swift language. Follow this tutorial everything works fine.

But after titorial I've tried to modify the structure and my code. The 'src' and groups inside it is folders, not just groups created by xCode.

NSSExpense.swift

import Foundation
import CoreData

class NSSExpense: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var descr: String
    @NSManaged var value: NSNumber
    @NSManaged var isMonthly: NSNumber
    @NSManaged var payDayInMonth: NSNumber

    class func createInManagedObjectContext(moc: NSManagedObjectContext, name: String, value: Double, payDayInMonth: Int16, isMonthly: Bool, descr: String!) -> NSSExpense {
        let newExpense = NSEntityDescription.insertNewObjectForEntityForName("NSSExpense", inManagedObjectContext: moc) as NSSExpense

        newExpense.name = name
        newExpense.value = NSNumber(double: value)
        newExpense.payDayInMonth = NSNumber(short: payDayInMonth)
        newExpense.isMonthly = NSNumber(bool: isMonthly)

        if let expenseDesctiption = descr {
            newExpense.descr = expenseDesctiption
        } else {
            newExpense.descr = ""
        }

        return newExpense
    }
}

NSSDataManager.swift

import UIKit
import CoreData

class NSSDataManager: NSObject {

    class var sharedDataManager: NSSDataManager {
        struct Static {
            static var instance: NSSDataManager?
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            Static.instance = NSSDataManager()
        }

        return Static.instance!
    }

    lazy var managedObjectContext : NSManagedObjectContext? = {
        // Error at the next line "Use of undeclared type 'NSSAppDelegate'"
        let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate

        if let managedObjectContext = appDelegate.managedObjectContext {
            return managedObjectContext
        } else {
            return nil
        }
    }()

    var expensesInMemory : [NSSExpense] {
        get {
            let fetchRequest = NSFetchRequest(entityName: "NSSExpense")
            if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [NSSExpense] {
                return fetchResults
            } else {
                return [NSSExpense]()
            }
        }
    }

    func addExpenseWithName(name: String, value: Double, payDayInMonth: Int16, isMonthly: Bool, descr: String!) -> NSSExpense {
        return NSSExpense.createInManagedObjectContext(managedObjectContext!, name: name, value: value, payDayInMonth: payDayInMonth, isMonthly: isMonthly, descr: descr?)
    }

}

I've tried to solve this problem different ways: 1) Create new project (Swift main language) and make the same structure again (failed) 2) Create new project (Objective-C main language). So I have the AppDelegate.h and AppDelegate.m. Add it to Swift files using Bridging-Header. The same problem. (failed)

Really interesting next thing. If I put next code to the ViewController.swift which creates automatically with new project everything works fine. But when I put this code to any other class. I've code this error.

lazy var managedObjectContext : NSManagedObjectContext? = {
        // Error at the next line "Use of undeclared type 'NSSAppDelegate'"
        let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate

        if let managedObjectContext = appDelegate.managedObjectContext {
            return managedObjectContext
        } else {
            return nil
        }
    }()

[UPDATE 1]

I've tried to create another class right at the same folder as NSSAppDelegate.swift and now everything works fine. However it's still an issue, how can I use the classes which stored in other folders?


[UPDATE 2]

Just tried to do the same thing in other project. If the file structure is like this so the AppDelegate.swift and NGDataManager.swift are in the same folder everything works great. BUT, if I put the NGDataManager.swift inside the 'src' folder like this (not just group, folder) the error occurs. May be I should create the other question for this.


[UPDATE 3]

I don't know how, but you can forget all I've said in UDATE 2. Because Now thats all not work. I even create a new project with CoreData named "Test" and just create a new class named "TestClass". The magic is in the next thing: if I put this code inside the TestClass.swift

import UIKit

class TestClass: NSObject {
    func someFunc() {
        let appDel = UIApplication.sharedApplication().delegate as AppDelegate
    }
}

the error occurs. But if I put this line in viewDidLoad in ViewController.swift which was generated automatically by xCode

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let appDel = UIApplication.sharedApplication().delegate as AppDelegate
    }
}

their is no error and everything works great. I don't know what to say...

You may see the AppDelegate code here but I didn't modify anything generated automatically by xCode. I've created a Single View Application with this settings.

Doshipak
  • 211
  • 1
  • 2
  • 9
  • 'NSSAppDelegate' - what is that supposed to be? Surely it's `NSApplicationDelegate`? – Grimxn Nov 19 '14 at 17:39
  • You should not be prefix your classes with `NS` you are going to run into all sorts of problems in the future. – sbarow Nov 19 '14 at 17:43
  • @sbarow this is my company prefix NSS. But sure that you're right, will create the other prefix. However I've tried to use the AppDelegate, without the prefix, just show the last code version here. – Doshipak Nov 19 '14 at 18:12
  • @AlexandrLapshin can you post the code for your `AppDelegate` – sbarow Nov 19 '14 at 19:08
  • @sbarow see the UPDATE 3 – Doshipak Nov 19 '14 at 19:31
  • @Grimxn yes this is NSApplicationDelegate and I've just want to cast it to my NSSAppDelegate. – Doshipak Nov 19 '14 at 19:35
  • 1
    @sbarow OMG! It seems I've found the answer. I've forgot to say that all classes I've created was created for Tests too. And if I remove the mark from Tests target like [this](https://www.dropbox.com/s/gr917bf0c34yr86/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202014-11-20%2001.50.15.png?dl=0) everything works fine! Is it a Swift bug or feature, I really don't know? – Doshipak Nov 19 '14 at 19:51
  • But it seems that I can't see the other project class types from classes I've created for Tests. This is a bad thing I think – Doshipak Nov 19 '14 at 20:00
  • I add all files to both the application target and the test target to avoid this exact problem. It's pretty hard to track down the first time! – Michael Daw Nov 30 '14 at 05:15

7 Answers7

56

Chances are when you created your project you also created a '{ProjectName}Tests' target. The problem is AppDelegate is not assigned membership in the '{ProjectName}Tests' target.

Select AppDelegate.swift then in the right-hand inspector click on the File Inspector (the paper icon) then make sure in the "Target Membership" both your project and the test target checkmarks are set to ON.

Clean, rebuild.

Ramin
  • 13,343
  • 3
  • 33
  • 35
  • @Tieme It's not worked for me( I think that the main reason is because I created the class in the other folder, not in the same folder as AppDelegate.swift file. I have next structure: MyProjFolder:{ AppDelegate.swift srcFolder:{ SomeClass.swift}} SomeClass.swift can't see AppDelegate in it's scope. – Doshipak Dec 19 '14 at 17:56
  • That should not matter – Tieme Dec 23 '14 at 09:11
  • @Tieme but it is. I tried this several times in several projects, and if I put the class in the other folder, this class can't see AppDelegate. – Doshipak Jan 26 '15 at 14:04
  • Thanks a ton @Ramin, spent around 6 hours to get this resolved but your solution works like a charm :) – iLearner Oct 19 '18 at 05:29
27

If trying to access an Objective-C AppDelegate in Swift code, make sure you have #import "AppDelegate.h" in your bridging header file.

This had me stuck for about an hour :-/

Hodson
  • 3,438
  • 1
  • 23
  • 51
4

I had a similar problem that was resolved when I did a "Clean" option in the Product menu

Syed Tariq
  • 2,878
  • 3
  • 27
  • 37
4

Ran into this issue in Xcode 8 and this was the first result when I searched on google so adding my solution.

If your project has UI and Unit Tests, make sure your AppDelegate is added to both target memberships. Once I added it to my Tests I was able to access any variables I had in my AppDelegate without having to use UIApplication.shared regardless of how my files were grouped.

To check, go to your AppDelegate, click on the file inspector, and look at Target Membership.

Christopher Larsen
  • 1,375
  • 15
  • 22
3

Make sure the Target Memberships are set the same in each file. Target memberships can be found in the properties inspector when you click on a specific file.

Jon Vogel
  • 5,244
  • 1
  • 39
  • 54
2

It suppose to be like this.

let appDelegate: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
Nurdin
  • 23,382
  • 43
  • 130
  • 308
0

Instead of:

let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate

try:

let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
Magnas
  • 3,832
  • 5
  • 33
  • 48