Developers working with Apple’s Cocoa framework often stumble upon the cryptic errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 error. This frustrating error occurs when an application fails to locate a specific shortcut or resource to function correctly.
The Vietnamese error message “không thể tìm thấy phím tắt được chỉ định” translates to “cannot find the specified shortcut,” immediately pinpointing the core issue. This error can cripple your application’s functionality and create a poor user experience. In this article, we’ll dissect this error, explore its root causes, and provide concrete, actionable solutions to get your application running smoothly again.

Breaking Down the errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 Error
When encountering this error, you’ll see something like:
Error Domain=NSCocoaErrorDomain
Code=4
“không thể tìm thấy phím tắt được chỉ định”
UserInfo={NSLocalizedDescription=không thể tìm thấy phím tắt được chỉ định}
Let’s break this down into its components:
- Error Domain: NSCocoaErrorDomain – This indicates the error belongs to Apple’s Cocoa framework, the macOS and iOS development application environment.
- Error Code: 4 – In the NSCocoaErrorDomain, error code 4 corresponds to NSFileNoSuchFileError, which means a file or resource couldn’t be found.
- Error Message: “không thể tìm thấy phím tắt được chỉ định” – Translated from Vietnamese, this means “cannot find the specified shortcut.”
This error typically appears in console logs, crash reports, or debug output when your application attempts to access a resource or shortcut that doesn’t exist at the expected location.
Common Causes of the errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 Error

1. Incorrect File Path References
One of the most common causes is hardcoded file paths that don’t match the actual location of resources in your application bundle.
Problematic Code:
swift
let shortcutPath = “/absolute/path/to/shortcut.json”
let shortcutData = try Data(contentsOf: URL(fileURLWithPath: shortcutPath))
Solution:
swift
// Use bundle-relative paths instead of absolute paths
if let shortcutURL = Bundle.main.url(forResource: “shortcut”, withExtension: “json”) {
let shortcutData = try Data(contentsOf: shortcutURL)
// Process the data
} else {
// Handle the missing resource gracefully
print(“Shortcut resource not found in bundle”)
}
2. Resources Missing from Application Bundle
Sometimes, resources are not adequately included in the application bundle during the build process.
Problematic Code:
swift
// Assuming the file exists without checking
let url = Bundle.main.url(forResource: “CustomShortcuts”, withExtension: “plist”)!
let shortcuts = NSDictionary(contentsOf: url) as! [String: Any]
Solution:
swift
// Verify resource inclusion and handle failure cases
guard let url = Bundle.main.url(forResource: “CustomShortcuts”, withExtension: “plist”),
let shortcuts = NSDictionary(contentsOf: url) as? [String: Any] else {
// Log the error and provide fallback
NSLog(“errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4: Missing CustomShortcuts.plist”)
return fallbackShortcuts()
}
3. Localization Issues
The Vietnamese error message suggests potential localization problems, where the application is looking for resources in a specific localization folder that doesn’t exist.
Problematic Code:
swift
// Trying to access a localized resource without proper setup
let localizedShortcutPath = NSLocalizedString(“SHORTCUT_PATH”, comment: “”)
let shortcutData = try Data(contentsOf: URL(fileURLWithPath: localizedShortcutPath))
Solution:
swift
// Handle localization properly
let localizedShortcutPath = NSLocalizedString(“SHORTCUT_PATH”, comment: “Path to shortcut file”)
if FileManager.default.fileExists(atPath: localizedShortcutPath) {
let shortcutData = try Data(contentsOf: URL(fileURLWithPath: localizedShortcutPath))
// Process the data
} else {
// Fall back to default language or handle the error
NSLog(“Localized shortcut not found for current locale”)
// Use default resource instead
}
4. File System Permission Issues
Lacking proper permissions to access specific files can trigger this error, especially in sandboxed applications.
Problematic Code:
swift
// Attempting to access files outside of sandbox without entitlements
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let shortcutPath = documentsPath + “/shortcuts/custom.shortcut”
let data = try Data(contentsOf: URL(fileURLWithPath: shortcutPath))
Solution:
swift
// Use security-scoped bookmarks for persistent access to user-selected files
func accessUserSelectedShortcut() {
let openPanel = NSOpenPanel()
openPanel.canChooseFiles = true
openPanel.allowedFileTypes = [“shortcut”]
openPanel.begin { result in
if result == .OK, let url = openPanel.url {
// Get security-scoped bookmark data
do {
let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
// Save bookmark data for later use
UserDefaults.standard.set(bookmarkData, forKey: “ShortcutBookmark”)
// Access the file with the bookmark
guard let resolvedURL = try? URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: nil) else {
return
}
resolvedURL.startAccessingSecurityScopedResource()
defer { resolvedURL.stopAccessingSecurityScopedResource() }
// Now you can access the file
let shortcutData = try? Data(contentsOf: resolvedURL)
// Process shortcutData
} catch {
NSLog(“Failed to create bookmark: \(error)”)
}
}
}
}

Solutions Comparison Table
Prevention Techniques | Recovery Strategies |
Use bundle-relative paths instead of absolute paths | Implement robust error handling with fallback resources |
Add resources to your Xcode project with the “Copy Bundle Resources” build phase | Create a recovery mechanism to download missing resources at runtime |
Verify resource existence before attempting access | Implement a diagnostic tool that lists all available resources |
Use proper localization techniques with fallbacks | Add a mechanism to recreate default shortcuts when missing |
Implement proper file system permissions and entitlements | Use security-scoped bookmarks for user-selected files |
Diagnosing the errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 Error
Follow these steps to diagnose the root cause of the error systematically:
- Enable verbose logging for resource loading
swift
// Add this early in your application lifecycle
func enableVerboseResourceLogging() {
UserDefaults.standard.set(true, forKey: “NSTraceForResourceNotFound”)
UserDefaults.standard.set(true, forKey: “NSTraceResourceAllocation”)
}
- Create a resource verification utility
swift
func verifyBundleResources(resourceNames: [String], extensions: [String]) -> [String: Bool] {
var results = [String: Bool]()
for resourceName in resourceNames {
for ext in extensions {
let resourceExists = Bundle.main.url(forResource: resourceName, withExtension: ext) != nil
results[“\(resourceName).\(ext)”] = resourceExists
NSLog(“Resource \(resourceName).\(ext): \(resourceExists ? “FOUND” : “MISSING”)”)
}
}
return results
}
// Usage:
let shortcutResources = verifyBundleResources(
resourceNames: [“DefaultShortcuts”, “CustomShortcuts”, “UserShortcuts”],
extensions: [“plist”, “json”, “shortcut”]
)
- Check file system permissions
swift
func checkFilePermissions(at path: String) -> (readable: Bool, writable: Bool, error: Error?) {
let fileManager = FileManager.default
var isReadable = false
var isWritable = false
var accessError: Error? = nil
do {
let fileAttributes = try fileManager.attributesOfItem(atPath: path)
// Get file permissions
if let posixPermissions = fileAttributes[.posixPermissions] as? NSNumber {
let permissions = posixPermissions.intValue
// Check read permission (4 in octal)
isReadable = (permissions & 0o400) != 0
// Check write permission (2 in octal)
isWritable = (permissions & 0o200) != 0
}
} catch {
accessError = error
}
NSLog(“File at \(path) – Readable: \(isReadable), Writable: \(isWritable), Error: \(String(describing: accessError))”)
return (isReadable, isWritable, accessError)
}
- Create a test case that reproduces the error
swift
func testResourceAccess() {
// Test case 1: Access a known existing resource
if let existingURL = Bundle.main.url(forResource: “DefaultShortcuts”, withExtension: “plist”) {
NSLog(“TEST PASS: Found DefaultShortcuts.plist at \(existingURL.path)”)
} else {
NSLog(“TEST FAIL: DefaultShortcuts.plist not found in bundle”)
}
// Test case 2: Deliberately access a non-existent resource to compare error
do {
let nonExistentURL = Bundle.main.bundleURL.appendingPathComponent(“NonExistentShortcut.plist”)
let _ = try Data(contentsOf: nonExistentURL)
NSLog(“TEST UNEXPECTED: No error thrown for non-existent resource”)
} catch {
NSLog(“TEST EXPECTED ERROR: \(error.localizedDescription)”)
// Check if error matches our target error
if let nsError = error as NSError?,
nsError.domain == NSCocoaErrorDomain,
nsError.code == 4 {
NSLog(“TEST PASS: Error matches errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4”)
}
}
}
- Examine real error logs
When you encounter the error in your application, look for entries like:
2024-04-09 15:32:47.123 YourApp[12345:67890] [error] Failed to load resource ‘CustomShortcuts.plist’: Error Domain=NSCocoaErrorDomain Code=4 “không thể tìm thấy phím tắt được chỉ định” UserInfo={NSLocalizedDescription=không thể tìm thấy phím tắt được chỉ định}
The specific file name in the log will help pinpoint exactly which resource is missing.

Implementation: Robust Resource Handling
Here’s a comprehensive solution for handling shortcuts that prevent the errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 error:
swift
import Foundation
/**
* ShortcutManager: A robust class for managing application shortcuts
* with built-in error handling for missing resources.
*
* Prevents the errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 error
* by implementing fallbacks and proper resource checking.
*/
class ShortcutManager {
// Singleton instance
static let shared = ShortcutManager()
// Types of shortcut collections
enum ShortcutType: String {
case system = “SystemShortcuts”
case user = “UserShortcuts”
case custom = “CustomShortcuts”
}
// Storage for loaded shortcuts
private var shortcuts: [ShortcutType: [String: Any]] = [:]
// Error tracking
private var loadErrors: [ShortcutType: Error] = [:]
/**
* Initialize the shortcut manager and attempt to load all shortcuts
*/
private init() {
loadAllShortcuts()
}
/**
* Attempts to load all shortcut types
*/
private func loadAllShortcuts() {
for type in [ShortcutType.system, .user, .custom] {
loadShortcuts(type: type)
}
}
/**
* Loads a specific type of shortcuts with robust error handling
*/
private func loadShortcuts(type: ShortcutType) {
// First try plist format
if let shortcuts = loadPlistShortcuts(type: type) {
self.shortcuts[type] = shortcuts
return
}
// Then try JSON format as fallback
if let shortcuts = loadJSONShortcuts(type: type) {
self.shortcuts[type] = shortcuts
return
}
// If both fail, create default shortcuts
NSLog(“WARNING: Failed to load \(type.rawValue) – Creating defaults”)
self.shortcuts[type] = createDefaultShortcuts(for: type)
}
/**
* Attempts to load shortcuts from a plist file
*/
private func loadPlistShortcuts(type: ShortcutType) -> [String: Any]? {
guard let url = Bundle.main.url(forResource: type.rawValue, withExtension: “plist”) else {
NSLog(“Plist resource not found for \(type.rawValue)”)
return nil
}
do {
let data = try Data(contentsOf: url)
let plist = try PropertyListSerialization.propertyList(from: data, options: [], format: nil)
guard let shortcuts = plist as? [String: Any] else {
NSLog(“Invalid plist format for \(type.rawValue)”)
return nil
}
return shortcuts
} catch {
loadErrors[type] = error
NSLog(“Error loading plist for \(type.rawValue): \(error.localizedDescription)”)
return nil
}
}
/**
* Attempts to load shortcuts from a JSON file
*/
private func loadJSONShortcuts(type: ShortcutType) -> [String: Any]? {
guard let url = Bundle.main.url(forResource: type.rawValue, withExtension: “json”) else {
NSLog(“JSON resource not found for \(type.rawValue)”)
return nil
}
do {
let data = try Data(contentsOf: url)
guard let shortcuts = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
NSLog(“Invalid JSON format for \(type.rawValue)”)
return nil
}
return shortcuts
} catch {
loadErrors[type] = error
NSLog(“Error loading JSON for \(type.rawValue): \(error.localizedDescription)”)
return nil
}
}
/**
* Creates default shortcuts when resource files can’t be found
*/
private func createDefaultShortcuts(for type: ShortcutType) -> [String: Any] {
switch type {
case .system:
return [
“copy”: “cmd+c”,
“paste”: “cmd+v”,
“cut”: “cmd+x”,
“save”: “cmd+s”
]
case .user:
return [:] // Empty defaults for user shortcuts
case .custom:
return [:] // Empty defaults for custom shortcuts
}
}
/**
* Returns a shortcut safely with fallbacks to prevent errors
*/
func getShortcut(name: String, type: ShortcutType = .system) -> String? {
// Ensure shortcuts are loaded
if shortcuts[type] == nil {
loadShortcuts(type: type)
}
// Get the shortcut from the loaded collection
if let typeShortcuts = shortcuts[type],
let shortcut = typeShortcuts[name] as? String {
return shortcut
}
// Try to find in other shortcut types as fallback
for fallbackType in [ShortcutType.system, .user, .custom] {
if fallbackType == type { continue } // Skip the one we already checked
if let typeShortcuts = shortcuts[fallbackType],
let shortcut = typeShortcuts[name] as? String {
NSLog(“Found shortcut ‘\(name)’ in fallback \(fallbackType.rawValue)”)
return shortcut
}
}
NSLog(“WARNING: Shortcut ‘\(name)’ not found in any collection”)
return nil
}
/**
* Saves a custom shortcut to persistent storage
*/
func saveCustomShortcut(name: String, value: String) throws {
// Update in-memory collection
var customShortcuts = shortcuts[.custom] ?? [:]
customShortcuts[name] = value
shortcuts[.custom] = customShortcuts
// Get the documents directory
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsDirectory.appendingPathComponent(“CustomShortcuts.json”)
// Convert to JSON and save
let data = try JSONSerialization.data(withJSONObject: customShortcuts, options: .prettyPrinted)
try data.write(to: fileURL)
NSLog(“Saved custom shortcut ‘\(name)'”)
}
/**
* Reloads shortcuts from disk, useful after external changes
*/
func reloadShortcuts() {
shortcuts.removeAll()
loadErrors.removeAll()
loadAllShortcuts()
}
/**
* Diagnostic method that lists all available shortcuts
*/
func listAllShortcuts() -> [String: [String: String]] {
var result: [String: [String: String]] = [:]
for type in [ShortcutType.system, .user, .custom] {
if let typeShortcuts = shortcuts[type] {
var typeDictionary: [String: String] = [:]
for (key, value) in typeShortcuts {
if let stringValue = value as? String {
typeDictionary[key] = stringValue
}
}
result[type.rawValue] = typeDictionary
}
}
return result
}
}
// Example usage:
// let copyShortcut = ShortcutManager.shared.getShortcut(name: “copy”)
// print(“Copy shortcut: \(copyShortcut ?? “Not found”)”)
Test Cases:
swift
func testShortcutManager() {
let manager = ShortcutManager.shared
// Test 1: Get an existing system shortcut
if let copyShortcut = manager.getShortcut(name: “copy”) {
assert(copyShortcut == “cmd+c”, “Expected cmd+c for copy”)
NSLog(“TEST PASS: Retrieved system shortcut ‘copy'”)
} else {
NSLog(“TEST FAIL: Could not retrieve system shortcut ‘copy'”)
}
// Test 2: Try to get a non-existent shortcut (should not crash)
let nonExistentShortcut = manager.getShortcut(name: “nonexistent_shortcut”)
assert(nonExistentShortcut == nil, “Expected nil for non-existent shortcut”)
NSLog(“TEST PASS: Handled non-existent shortcut gracefully”)
// Test 3: Save and retrieve a custom shortcut
do {
try manager.saveCustomShortcut(name: “test_shortcut”, value: “cmd+shift+t”)
if let testShortcut = manager.getShortcut(name: “test_shortcut”, type: .custom) {
assert(testShortcut == “cmd+shift+t”, “Expected cmd+shift+t for test_shortcut”)
NSLog(“TEST PASS: Saved and retrieved custom shortcut”)
} else {
NSLog(“TEST FAIL: Could not retrieve saved custom shortcut”)
}
} catch {
NSLog(“TEST FAIL: Could not save custom shortcut: \(error)”)
}
}
Conclusion
The errordomainnscocoaerrordomainerrormessagekhong-the-tim-thay-phim-tat-duoc-chi-dinh-errorcode4 error occurs when your application can’t find a required shortcut resource. You can prevent this error from disrupting your application by implementing proper resource checking, robust error handling, and fallback mechanisms.
The most critical implementation advice is never to assume resources exist—always verify their presence and have a recovery strategy ready. Remember that relative paths and proper bundle integration are your first defense against this persistent Cocoa error.