2

I am having issues with (I think) the namespace after changing the project name. Here is the error:

Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '* -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Apple.Document) for key (NS.objects); the class may be defined in source code or a library that is not linked'

There is a similar question addressed here, but this is referring to iOS. For Mac, simply changing the display bundle name will not change the name displayed under the icon in the dock.

After changing the project name from "Apple" to "Pear", I am having issues when getting Document objects from CoreData:

    // Document
    @objc(Document)
    class Document: NSManagedObject {
        @NSManaged var content: NSAttributedString
    }

The Document's content contains SpecialTextAttachments.

    // SpecialTextAttachment
    class SpecialTextAttachment: NSTextAttachment {
        //
    }

When printing the Document's content, it gives me the error addressed above. How would I go about converting Apple.SpecialTextAttachment to Pear.SpecialTextAttachment? It seems like I need to convert it before I iterate through the array of Documents, because just referring to the Document class causes a crash. I also cannot create another project simply for this class as suggested here.

    // in ViewController
    func getDocuments() {
        let fetchRequest = NSFetchRequest()
        fetchRequest.entity = NSEntityDescription.entityForName("Document", inManagedObjectContext: managedObjectContext!)
        fetchRequest.fetchBatchSize = 20
        let docs = (try? managedObjectContext!.executeFetchRequest(fetchRequest)) as! [Document]

    }
Community
  • 1
  • 1
Naoto Ida
  • 1,275
  • 1
  • 14
  • 29

3 Answers3

3

I sort of gave up on this and continued to go with my decision to rename the project.

So in init() of my class which contains all the methods for handling data from CoreData, I placed the following code:

class CoreDataHelper {
    init() {
        NSKeyedUnarchiver.setClass(SpecialTextAttachment.self, forClassName: "Apple.SpecialTextAttachment")
    }
}

This will convert any Apple.SpecialTextAttachment to Pear.SpecialTextAttachment in any upcoming operations in which SpecialTextAttachment may come up.

Naoto Ida
  • 1,275
  • 1
  • 14
  • 29
1

You can change the displayed name of the app on OS X without changing the bundle name. The procedure is a little different than on iOS.

First, if you haven't already, you need to create an InfoPlist.strings file for your app. Use the “OS X > Resource > Strings File” template:

Creating InfoPlist.strings

Then localize InfoPlist.strings to the Base localization:

Creating InfoPlist.strings Base localization

In the strings file, assign your new name to the CFBundleName key, like this:

CFBundleName = "Pear";

Setting CFBundleName in InfoPlist.strings

If you have set the CFBundleDisplayName key in Info.plist, you should assign your new name to CFBundleDisplayName in InfoPlist.strings. If you haven't set the CFBundleDisplayName key in Info.plist, you don't have to set it in InfoPlist.strings.

That is sufficient to make your app show its new name in its menu bar and in the Finder. However, your old name still appears, hardcoded, in several places in your MainMenu.xib or Main.storyboard. You can find them by choosing menu bar > Find > Find… (default shortcut: ⌘F) like this:

finding Apple in MainMenu.xib

You need to change these to “Pear”. (Technically you don't have to change the “Apple” menu title, because AppKit will change it at runtime to the localized string in InfoPlist.strings, but it's simpler if you just change all instances of “Apple” to “Pear”.)

If you have actual localizations to other languages, and you want the app name to be localized, you'll need to localize InfoPlist.strings to each of your localizations and set the CFBundleName (and maybe CFBundleDisplayName) in each of them.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thanks, but setting the CFBundleDisplayName did not change anything. Even after a clean. – Naoto Ida Dec 15 '15 at 04:21
  • You don't need to set `CFBundleDisplayName` in your `Info.plist` (and I didn't suggest you should). I only said you need to set it in your `InfoPlist.strings` **if** you have (for some reason) set it in your `Info.plist` and want to keep it set there. – rob mayoff Dec 15 '15 at 05:47
0

It happens because your *.xcodeproj (project.pbxproj) by default use $(TARGET_NAME) for Product Name and $(PRODUCT_NAME) in another fields. For example, Product Module Name by default setted as $(PRODUCT_NAME:c99extidentifier). All you need is replace all PRODUCT_NAME to TARGET_NAME in Build Settings.

Srj0x0
  • 458
  • 3
  • 12