🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
macOS Desktop Features Objective-C Samples
macOS Objective-C desktop features examples including file dialogs, message boxes, and system tray
💻 Message Boxes objectivec
🟢 simple
⭐⭐
Display alert and confirmation dialogs using NSAlert
⏱️ 20 min
🏷️ objectivec, macos, desktop, gui
Prerequisites:
Objective-C basics, AppKit framework
// macOS Objective-C Message Boxes Examples
// Using AppKit framework
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
// MARK: - 1. Basic Alert Dialogs
@interface MessageBoxHelper : NSObject
+ (void)showAlert:(NSString *)title
message:(NSString *)message;
+ (void)showInformationalAlert:(NSString *)title
message:(NSString *)message;
+ (void)showWarningAlert:(NSString *)title
message:(NSString *)message;
+ (void)showErrorAlert:(NSString *)title
message:(NSString *)message;
@end
@implementation MessageBoxHelper
+ (void)showAlert:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
[alert runModal];
NSLog(@"Alert shown: %@", title);
}
+ (void)showInformationalAlert:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
alert.icon = [NSImage imageNamed:NSImageNameInfo];
[alert runModal];
NSLog(@"Informational alert shown: %@", title);
}
+ (void)showWarningAlert:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleWarning;
alert.icon = [NSImage imageNamed:NSImageNameCaution];
[alert runModal];
NSLog(@"Warning alert shown: %@", title);
}
+ (void)showErrorAlert:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleCritical;
alert.icon = [NSImage imageNamed:NSImageNameStopProgressTemplate];
[alert runModal];
NSLog(@"Error alert shown: %@", title);
}
@end
// MARK: - 2. Confirmation Dialogs
@interface ConfirmationDialogHelper : NSObject
+ (BOOL)showConfirmation:(NSString *)title
message:(NSString *)message;
+ (NSModalResponse)showYesNoDialog:(NSString *)title
message:(NSString *)message;
+ (BOOL)showYesNoCancelDialog:(NSString *)title
message:(NSString *)message;
@end
@implementation ConfirmationDialogHelper
+ (BOOL)showConfirmation:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
NSModalResponse response = [alert runModal];
BOOL confirmed = (response == NSAlertFirstButtonReturn);
NSLog(@"Confirmation dialog result: %@", confirmed ? @"YES" : @"NO");
return confirmed;
}
+ (NSModalResponse)showYesNoDialog:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleWarning;
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
NSModalResponse response = [alert runModal];
if (response == NSAlertFirstButtonReturn) {
NSLog(@"Yes/No dialog result: Yes");
} else {
NSLog(@"Yes/No dialog result: No");
}
return response;
}
+ (BOOL)showYesNoCancelDialog:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
[alert addButtonWithTitle:@"Cancel"];
NSModalResponse response = [alert runModal];
if (response == NSAlertFirstButtonReturn) {
NSLog(@"Yes/No/Cancel dialog result: Yes");
return YES;
} else if (response == NSAlertSecondButtonReturn) {
NSLog(@"Yes/No/Cancel dialog result: No");
return NO;
} else {
NSLog(@"Yes/No/Cancel dialog result: Cancel");
return NO; // Cancel returns NO
}
}
@end
// MARK: - 3. Custom Button Dialogs
@interface CustomDialogHelper : NSObject
+ (NSInteger)showCustomButtonDialog:(NSString *)title
message:(NSString *)message
buttons:(NSArray<NSString *> *)buttons;
+ (NSString *)showCustomButtonDialogWithReturn:(NSString *)title
message:(NSString *)message
buttons:(NSArray<NSString *> *)buttons;
@end
@implementation CustomDialogHelper
+ (NSInteger)showCustomButtonDialog:(NSString *)title
message:(NSString *)message
buttons:(NSArray<NSString *> *)buttons {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
// Add custom buttons
for (NSString *buttonTitle in buttons) {
[alert addButtonWithTitle:buttonTitle];
}
NSModalResponse response = [alert runModal];
NSInteger buttonIndex = response - NSAlertFirstButtonReturn;
NSLog(@"Custom button dialog: Selected button index: %ld", (long)buttonIndex);
return buttonIndex;
}
+ (NSString *)showCustomButtonDialogWithReturn:(NSString *)title
message:(NSString *)message
buttons:(NSArray<NSString *> *)buttons {
NSInteger index = [self showCustomButtonDialog:title
message:message
buttons:buttons];
if (index >= 0 && index < buttons.count) {
NSString *selectedButton = buttons[index];
NSLog(@"Selected button: %@", selectedButton);
return selectedButton;
}
return nil;
}
@end
// MARK: - 4. Input Dialogs
@interface InputDialogHelper : NSObject
+ (NSString *)showTextInputDialog:(NSString *)title
message:(NSString *)message
defaultValue:(NSString *)defaultValue;
+ (NSString *)showPasswordDialog:(NSString *)title
message:(NSString *)message;
@end
@implementation InputDialogHelper
+ (NSString *)showTextInputDialog:(NSString *)title
message:(NSString *)message
defaultValue:(NSString *)defaultValue {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
// Create text field
NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 24)];
input.stringValue = defaultValue ?: @"";
[alert setAccessoryView:input];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert.window setInitialFirstResponder:input];
NSModalResponse response = [alert runModal];
if (response == NSAlertFirstButtonReturn) {
NSString *text = input.stringValue;
NSLog(@"Text input: %@", text);
return text;
}
NSLog(@"Text input cancelled");
return nil;
}
+ (NSString *)showPasswordDialog:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
// Create secure text field
NSSecureTextField *passwordInput = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 24)];
[alert setAccessoryView:passwordInput];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert.window setInitialFirstResponder:passwordInput];
NSModalResponse response = [alert runModal];
if (response == NSAlertFirstButtonReturn) {
NSString *password = passwordInput.stringValue;
NSLog(@"Password entered (length: %lu)", (unsigned long)password.length);
return password;
}
NSLog(@"Password input cancelled");
return nil;
}
@end
// MARK: - 5. Detailed Dialogs with Suppression
@interface DetailedDialogHelper : NSObject
+ (void)showDetailedAlert:(NSString *)title
message:(NSString *)message
detailText:(NSString *)detailText;
+ (BOOL)showSuppressibleAlert:(NSString *)title
message:(NSString *)message
suppressionKey:(NSString *)key;
@end
@implementation DetailedDialogHelper
+ (void)showDetailedAlert:(NSString *)title
message:(NSString *)message
detailText:(NSString *)detailText {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
if (detailText) {
// Add accessory view with detail text
NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 400, 150)];
scrollView.hasVerticalScroller = YES;
scrollView.hasHorizontalScroller = NO;
scrollView.borderType = NSBezelBorder;
NSTextView *textView = [[NSTextView alloc] initWithFrame:scrollView.bounds];
textView.string = detailText;
textView.editable = NO;
textView.font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
scrollView.documentView = textView;
[alert setAccessoryView:scrollView];
}
[alert addButtonWithTitle:@"OK"];
[alert runModal];
NSLog(@"Detailed alert shown: %@", title);
}
+ (BOOL)showSuppressibleAlert:(NSString *)title
message:(NSString *)message
suppressionKey:(NSString *)key {
// Check if alert was previously suppressed
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL suppressed = [defaults boolForKey:key];
if (suppressed) {
NSLog(@"Alert was previously suppressed");
return NO;
}
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
[alert setShowsSuppressionButton:YES];
alert.suppressionButton.title = @"Don't show this again";
[alert addButtonWithTitle:@"OK"];
[alert runModal];
// Save suppression state
if (alert.suppressionButton.state == NSControlStateValueOn) {
[defaults setBool:YES forKey:key];
NSLog(@"Alert suppression enabled for key: %@", key);
}
return YES;
}
@end
// MARK: - 6. Sheet Dialogs (Attached to Windows)
@interface SheetDialogHelper : NSObject
+ (void)showSheetInWindow:(NSWindow *)window
title:(NSString *)title
message:(NSString *)message
completion:(void (^)(NSModalResponse response))completion;
@end
@implementation SheetDialogHelper
+ (void)showSheetInWindow:(NSWindow *)window
title:(NSString *)title
message:(NSString *)message
completion:(void (^)(NSModalResponse))completion {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
alert.alertStyle = NSAlertStyleInformational;
[alert beginSheetModalForWindow:window completionHandler:^(NSModalResponse response) {
NSLog(@"Sheet dialog closed with response: %ld", (long)response);
if (completion) {
completion(response);
}
}];
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C Message Boxes Examples ===\n");
// Note: Message boxes require a running application with a window
// These examples demonstrate the API usage patterns
NSLog(@"--- Message Box API Examples ---\n");
// 1. Basic alerts
NSLog(@"1. Basic Alert");
NSLog(@" [MessageBoxHelper showAlert:@\"Title\" message:@\"Message\"]\n");
NSLog(@"2. Informational Alert");
NSLog(@" [MessageBoxHelper showInformationalAlert:@\"Info\" message:@\"Details\"]\n");
NSLog(@"3. Warning Alert");
NSLog(@" [MessageBoxHelper showWarningAlert:@\"Warning\" message:@\"Caution\"]\n");
NSLog(@"4. Error Alert");
NSLog(@" [MessageBoxHelper showErrorAlert:@\"Error\" message:@\"Failure\"]\n");
// 2. Confirmation dialogs
NSLog(@"5. OK/Cancel Confirmation");
NSLog(@" BOOL confirmed = [ConfirmationDialogHelper showConfirmation:@\"Confirm\" message:@\"Are you sure?\"]\n");
NSLog(@"6. Yes/No Dialog");
NSLog(@" NSModalResponse response = [ConfirmationDialogHelper showYesNoDialog:@\"Proceed\" message:@\"Continue?\"]\n");
NSLog(@"7. Yes/No/Cancel Dialog");
NSLog(@" BOOL result = [ConfirmationDialogHelper showYesNoCancelDialog:@\"Save\" message:@\"Save changes?\"]\n");
// 3. Custom buttons
NSLog(@"8. Custom Button Dialog");
NSLog(@" NSArray *buttons = @[\"Retry\", \"Ignore\", \"Abort\"];");
NSLog(@" NSInteger index = [CustomDialogHelper showCustomButtonDialog:@\"Error\" message:@\"Action failed\" buttons:buttons]\n");
// 4. Input dialogs
NSLog(@"9. Text Input Dialog");
NSLog(@" NSString *text = [InputDialogHelper showTextInputDialog:@\"Input\" message:@\"Enter name:\" defaultValue:@\"John\"]\n");
NSLog(@"10. Password Input Dialog");
NSLog(@" NSString *password = [InputDialogHelper showPasswordDialog:@\"Login\" message:@\"Enter password:\"]\n");
// 5. Detailed dialogs
NSLog(@"11. Detailed Alert");
NSLog(@" [DetailedDialogHelper showDetailedAlert:@\"Error\" message:@\"Operation failed\" detailText:@\"Stack trace...\"]\n");
NSLog(@"12. Suppressible Alert");
NSLog(@" [DetailedDialogHelper showSuppressibleAlert:@\"Update Available\" message:@\"New version ready\" suppressionKey:@"updateAlert\"]\n");
// 6. Sheet dialogs
NSLog(@"13. Sheet Dialog");
NSLog(@" [SheetDialogHelper showSheetInWindow:window title:@\"Confirm\" message:@\"Delete?\"]\n");
// Usage examples
NSLog(@"--- Usage Examples ---\n");
NSLog(@"// Confirm before destructive action:");
NSLog(@"BOOL confirmed = [ConfirmationDialogHelper showConfirmation:@\"Delete File\"");
NSLog(@" message:@\"This cannot be undone.\"]");
NSLog(@"if (confirmed) {");
NSLog(@" // Perform deletion");
NSLog(@"}\n");
NSLog(@"// Get user input:");
NSLog(@"NSString *name = [InputDialogHelper showTextInputDialog:@\"User Name\"");
NSLog(@" message:@\"Enter your name:\"");
NSLog(@" defaultValue:@"\"A"");
NSLog(@"if (name) {");
NSLog(@" NSLog(@\"Hello, %@\", name);");
NSLog(@"}\n");
NSLog(@"// Show detailed error:");
NSLog(@"NSString *errorDetails = @\"Error code: 404\\nFile not found on server\\nPlease check connection\";");
NSLog(@"[DetailedDialogHelper showDetailedAlert:@\"Download Failed\"");
NSLog(@" message:@\"Could not download file\"");
NSLog(@" detailText:errorDetails]\n");
NSLog(@"=== Message Boxes Examples Completed ===");
NSLog(@"\nNote: To see actual message boxes, run this code in a GUI application");
}
return 0;
}
💻 File Dialogs objectivec
🟡 intermediate
⭐⭐⭐
Open and save file dialogs using NSOpenPanel and NSSavePanel
⏱️ 25 min
🏷️ objectivec, macos, desktop, gui
Prerequisites:
Objective-C basics, AppKit framework
// macOS Objective-C File Dialogs Examples
// Using AppKit framework
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
// MARK: - 1. Open File Dialog
@interface FileDialogHelper : NSObject
+ (NSURL *)showOpenFileDialog;
+ (NSURL *)showOpenFileDialogWithTypes:(NSArray<NSString *> *)fileTypes;
+ (NSArray<NSURL *> *)showOpenMultipleFilesDialog;
+ (NSURL *)showOpenDirectoryDialog;
@end
@implementation FileDialogHelper
+ (NSURL *)showOpenFileDialog {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select a file";
panel.prompt = @"Open";
panel.canChooseFiles = YES;
panel.canChooseDirectories = NO;
panel.allowsMultipleSelection = NO;
if ([panel runModal] == NSModalResponseOK) {
NSURL *selectedURL = panel.URLs.firstObject;
NSLog(@"Selected file: %@", selectedURL.path);
return selectedURL;
}
NSLog(@"File selection cancelled");
return nil;
}
+ (NSURL *)showOpenFileDialogWithTypes:(NSArray<NSString *> *)fileTypes {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select a file";
panel.prompt = @"Open";
panel.canChooseFiles = YES;
panel.canChooseDirectories = NO;
panel.allowsMultipleSelection = NO;
// Set allowed file types
if (fileTypes) {
panel.allowedFileTypes = fileTypes;
NSLog(@"Allowed file types: %@", fileTypes);
}
if ([panel runModal] == NSModalResponseOK) {
NSURL *selectedURL = panel.URLs.firstObject;
NSLog(@"Selected file: %@", selectedURL.path);
return selectedURL;
}
NSLog(@"File selection cancelled");
return nil;
}
+ (NSArray<NSURL *> *)showOpenMultipleFilesDialog {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select one or more files";
panel.prompt = @"Open";
panel.canChooseFiles = YES;
panel.canChooseDirectories = NO;
panel.allowsMultipleSelection = YES;
if ([panel runModal] == NSModalResponseOK) {
NSArray<NSURL *> *selectedURLs = panel.URLs;
NSLog(@"Selected %lu files", (unsigned long)selectedURLs.count);
for (NSURL *url in selectedURLs) {
NSLog(@" - %@", url.path);
}
return selectedURLs;
}
NSLog(@"Multiple file selection cancelled");
return nil;
}
+ (NSURL *)showOpenDirectoryDialog {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select a folder";
panel.prompt = @"Open";
panel.canChooseFiles = NO;
panel.canChooseDirectories = YES;
panel.allowsMultipleSelection = NO;
if ([panel runModal] == NSModalResponseOK) {
NSURL *selectedURL = panel.URLs.firstObject;
NSLog(@"Selected directory: %@", selectedURL.path);
return selectedURL;
}
NSLog(@"Directory selection cancelled");
return nil;
}
@end
// MARK: - 2. Save File Dialog
@interface SaveFileDialogHelper : NSObject
+ (NSURL *)showSaveFileDialog;
+ (NSURL *)showSaveFileDialogWithName:(NSString *)defaultName;
+ (NSURL *)showSaveFileDialogWithName:(NSString *)defaultName
fileType:(NSString *)fileType;
@end
@implementation SaveFileDialogHelper
+ (NSURL *)showSaveFileDialog {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = @"Untitled";
if ([panel runModal] == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Save to: %@", saveURL.path);
return saveURL;
}
NSLog(@"Save file dialog cancelled");
return nil;
}
+ (NSURL *)showSaveFileDialogWithName:(NSString *)defaultName {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = defaultName ?: @"Untitled";
if ([panel runModal] == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Save to: %@", saveURL.path);
return saveURL;
}
NSLog(@"Save file dialog cancelled");
return nil;
}
+ (NSURL *)showSaveFileDialogWithName:(NSString *)defaultName
fileType:(NSString *)fileType {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = defaultName ?: @"Untitled";
// Set allowed file type
if (fileType) {
panel.allowedFileTypes = @[fileType];
NSLog(@"File type: %@", fileType);
}
if ([panel runModal] == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Save to: %@", saveURL.path);
return saveURL;
}
NSLog(@"Save file dialog cancelled");
return nil;
}
@end
// MARK: - 3. Advanced File Dialog Options
@interface AdvancedFileDialogHelper : NSObject
+ (NSURL *)showOpenDialogWithDirectory:(NSString *)directoryPath
allowedTypes:(NSArray<NSString *> *)types;
+ (NSURL *)showSaveDialogInDirectory:(NSString *)directoryPath
defaultName:(NSString *)defaultName
fileType:(NSString *)fileType;
+ (NSURL *)showSaveDialogWithAccessory:(NSString *)defaultName;
@end
@implementation AdvancedFileDialogHelper
+ (NSURL *)showOpenDialogWithDirectory:(NSString *)directoryPath
allowedTypes:(NSArray<NSString *> *)types {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select a file";
panel.prompt = @"Open";
panel.canChooseFiles = YES;
panel.canChooseDirectories = NO;
panel.allowsMultipleSelection = NO;
// Set starting directory
if (directoryPath) {
NSURL *directoryURL = [NSURL fileURLWithPath:directoryPath];
panel.directoryURL = directoryURL;
NSLog(@"Starting directory: %@", directoryPath);
}
// Set allowed file types
if (types) {
panel.allowedFileTypes = types;
}
if ([panel runModal] == NSModalResponseOK) {
NSURL *selectedURL = panel.URLs.firstObject;
NSLog(@"Selected file: %@", selectedURL.path);
return selectedURL;
}
return nil;
}
+ (NSURL *)showSaveDialogInDirectory:(NSString *)directoryPath
defaultName:(NSString *)defaultName
fileType:(NSString *)fileType {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = defaultName ?: @"Untitled";
// Set starting directory
if (directoryPath) {
NSURL *directoryURL = [NSURL fileURLWithPath:directoryPath];
panel.directoryURL = directoryURL;
}
// Set file type
if (fileType) {
panel.allowedFileTypes = @[fileType];
}
if ([panel runModal] == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Save to: %@", saveURL.path);
return saveURL;
}
return nil;
}
+ (NSURL *)showSaveDialogWithAccessory:(NSString *)defaultName {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = defaultName ?: @"Untitled";
// Add accessory view
NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 300, 60)];
NSButton *checkbox = [[NSButton alloc] initWithFrame:NSMakeRect(10, 35, 280, 20)];
checkbox.buttonType = NSSwitchButton;
checkbox.title = @"Add file extension";
checkbox.state = NSControlStateValueOn;
[accessoryView addSubview:checkbox];
NSTextField *infoLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 280, 20)];
infoLabel.stringValue = @"Choose save location and name";
infoLabel.editable = NO;
infoLabel.drawsBackground = NO;
infoLabel.bordered = NO;
[accessoryView addSubview:infoLabel];
panel.accessoryView = accessoryView;
if ([panel runModal] == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Extension checkbox state: %ld", (long)checkbox.state);
NSLog(@"Save to: %@", saveURL.path);
return saveURL;
}
return nil;
}
@end
// MARK: - 4. File Dialog Completion Handlers
@interface ModernFileDialogHelper : NSObject
+ (void)showOpenFileDialogWithCompletion:(void (^)(NSURL *selectedURL))completion;
+ (void)showSaveFileDialogWithCompletion:(void (^)(NSURL *saveURL))completion;
@end
@implementation ModernFileDialogHelper
+ (void)showOpenFileDialogWithCompletion:(void (^)(NSURL *selectedURL))completion {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.title = @"Select a file";
panel.prompt = @"Open";
panel.canChooseFiles = YES;
panel.canChooseDirectories = NO;
panel.allowsMultipleSelection = NO;
[panel beginSheetModalForWindow:nil completionHandler:^(NSModalResponse result) {
if (result == NSModalResponseOK) {
NSURL *selectedURL = panel.URLs.firstObject;
NSLog(@"Selected file: %@", selectedURL.path);
if (completion) {
completion(selectedURL);
}
} else {
NSLog(@"File selection cancelled");
if (completion) {
completion(nil);
}
}
}];
}
+ (void)showSaveFileDialogWithCompletion:(void (^)(NSURL *saveURL))completion {
NSSavePanel *panel = [NSSavePanel savePanel];
panel.title = @"Save file";
panel.prompt = @"Save";
panel.canCreateDirectories = YES;
panel.nameFieldStringValue = @"Untitled";
[panel beginSheetModalForWindow:nil completionHandler:^(NSModalResponse result) {
if (result == NSModalResponseOK) {
NSURL *saveURL = panel.URL;
NSLog(@"Save to: %@", saveURL.path);
if (completion) {
completion(saveURL);
}
} else {
NSLog(@"Save dialog cancelled");
if (completion) {
completion(nil);
}
}
}];
}
@end
// MARK: - 5. Common File Type Filters
@interface FileTypeFilter : NSObject
+ (NSArray<NSString *> *)imageTypes;
+ (NSArray<NSString *> *)textTypes;
+ (NSArray<NSString *> *)documentTypes;
+ (NSArray<NSString *> *)audioTypes;
+ (NSArray<NSString *> *)videoTypes;
@end
@implementation FileTypeFilter
+ (NSArray<NSString *> *)imageTypes {
return @[@"png", @"jpg", @"jpeg", @"gif", @"bmp", @"tiff", @"webp", @"ico"];
}
+ (NSArray<NSString *> *)textTypes {
return @[@"txt", @"md", @"rtf", @"csv", @"json", @"xml", @"html", @"css", @"js"];
}
+ (NSArray<NSString *> *)documentTypes {
return @[@"pdf", @"doc", @"docx", @"xls", @"xlsx", @"ppt", @"pptx", @"pages", @"numbers", @"key"];
}
+ (NSArray<NSString *> *)audioTypes {
return @[@"mp3", @"wav",aac", @"m4a", @"flac", @"ogg", @"wma"];
}
+ (NSArray<NSString *> *)videoTypes {
return @[@"mp4", @"mov", @"avi", @"mkv", @"m4v", @"flv", @"wmv"];
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C File Dialogs Examples ===\n");
// Note: File dialogs require a running application with a window
// These examples demonstrate the API usage patterns
NSLog(@"--- File Dialog API Examples ---\n");
// 1. Open file dialog
NSLog(@"1. Open File Dialog");
NSLog(@" - [FileDialogHelper showOpenFileDialog]");
NSLog(@" Usage: Selects a single file\n");
// 2. Open file with type filter
NSLog(@"2. Open File with Type Filter");
NSLog(@" - [FileDialogHelper showOpenFileDialogWithTypes:[FileTypeFilter imageTypes]]");
NSLog(@" Usage: Selects only image files\n");
// 3. Open multiple files
NSLog(@"3. Open Multiple Files");
NSLog(@" - [FileDialogHelper showOpenMultipleFilesDialog]");
NSLog(@" Usage: Selects multiple files\n");
// 4. Open directory
NSLog(@"4. Open Directory");
NSLog(@" - [FileDialogHelper showOpenDirectoryDialog]");
NSLog(@" Usage: Selects a folder\n");
// 5. Save file dialog
NSLog(@"5. Save File Dialog");
NSLog(@" - [SaveFileDialogHelper showSaveFileDialog]");
NSLog(@" Usage: Prompts for save location\n");
// 6. Save file with name
NSLog(@"6. Save File with Name");
NSLog(@" - [SaveFileDialogHelper showSaveFileDialogWithName:@\"document.txt\"]");
NSLog(@" Usage: Sets default filename\n");
// 7. Save with file type
NSLog(@"7. Save with File Type");
NSLog(@" - [SaveFileDialogHelper showSaveFileDialogWithName:@\"image\" fileType:@\"png\"]");
NSLog(@" Usage: Restricts to specific file type\n");
// 8. Advanced options
NSLog(@"8. Advanced Options");
NSLog(@" - [AdvancedFileDialogHelper showOpenDialogWithDirectory:@\"/Users\" allowedTypes:types]");
NSLog(@" Usage: Sets starting directory and file types\n");
// 9. Modern async handlers
NSLog(@"9. Modern Completion Handlers");
NSLog(@" - [ModernFileDialogHelper showOpenFileDialogWithCompletion:^(NSURL *url) { ... }]");
NSLog(@" Usage: Asynchronous dialog with completion block\n");
// 10. Common file type filters
NSLog(@"10. Common File Type Filters");
NSLog(@" - [FileTypeFilter imageTypes]: %@\n", [FileTypeFilter imageTypes]);
NSLog(@" - [FileTypeFilter textTypes]: %@\n", [FileTypeFilter textTypes]);
NSLog(@" - [FileTypeFilter documentTypes]: %@\n", [FileTypeFilter documentTypes]);
// Example code snippets
NSLog(@"--- Example Code Snippets ---\n");
NSLog(@"// Open and read a text file:");
NSLog(@"NSURL *fileURL = [FileDialogHelper showOpenFileDialogWithTypes:[FileTypeFilter textTypes]];");
NSLog(@"if (fileURL) {");
NSLog(@" NSString *content = [NSString stringWithContentsOfURL:fileURL");
NSLog(@" encoding:NSUTF8StringEncoding");
NSLog(@" error:nil];");
NSLog(@" NSLog(@\"Content: %@\", content);");
NSLog(@"}\n");
NSLog(@"// Save content to file:");
NSLog(@"NSURL *saveURL = [SaveFileDialogHelper showSaveFileDialogWithName:@\"output\"]");
NSLog(@"if (saveURL) {");
NSLog(@" NSString *content = @\"Hello, World!\";");
NSLog(@" [content writeToURL:saveURL");
NSLog(@" atomically:YES");
NSLog(@" encoding:NSUTF8StringEncoding");
NSLog(@" error:nil];");
NSLog(@"}\n");
NSLog(@"=== File Dialogs Examples Completed ===");
NSLog(@"\nNote: To see actual dialogs, run this code in a GUI application");
}
return 0;
}
💻 System Tray / Status Bar objectivec
🟡 intermediate
⭐⭐⭐
Create and manage status bar items with menus and notifications
⏱️ 30 min
🏷️ objectivec, macos, desktop, status bar
Prerequisites:
Objective-C basics, AppKit framework
// macOS Objective-C System Tray / Status Bar Examples
// Using AppKit framework
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
// MARK: - 1. Basic Status Bar Item
@interface StatusBarItemController : NSObject
@property (nonatomic, strong) NSStatusItem *statusItem;
- (instancetype)initWithTitle:(NSString *)title;
- (void)showMenu;
- (void)hide;
- (void)setTooltip:(NSString *)tooltip;
- (void)setTitle:(NSString *)title;
- (void)setImage:(NSImage *)image;
@end
@implementation StatusBarItemController
- (instancetype)initWithTitle:(NSString *)title {
self = [super init];
if (self) {
// Create status item in system status bar
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
_statusItem.button.title = title;
NSLog(@"Status bar item created with title: %@", title);
}
return self;
}
- (void)showMenu:(NSMenu *)menu {
self.statusItem.menu = menu;
NSLog(@"Menu attached to status bar item");
}
- (void)hide {
[[NSStatusBar systemStatusBar] removeStatusItem:self.statusItem];
NSLog(@"Status bar item removed");
}
- (void)setTooltip:(NSString *)tooltip {
self.statusItem.button.toolTip = tooltip;
NSLog(@"Tooltip set: %@", tooltip);
}
- (void)setTitle:(NSString *)title {
self.statusItem.button.title = title;
NSLog(@"Title set: %@", title);
}
- (void)setImage:(NSImage *)image {
self.statusItem.button.image = image;
NSLog(@"Image set");
}
@end
// MARK: - 2. Status Bar with Menu
@interface MenuStatusBarController : StatusBarItemController
- (void)setupDefaultMenu;
@end
@implementation MenuStatusBarController
- (void)setupDefaultMenu {
// Create menu
NSMenu *menu = [[NSMenu alloc] init];
// Add menu items
[menu addItem:[self createMenuItem:@"About"
action:@selector(showAbout:)
keyEquivalent:@""]];
[menu addItem:[NSMenuItem separatorItem]];
[menu addItem:[self createMenuItem:@"Preferences"
action:@selector(showPreferences:)
keyEquivalent:@","]];
[menu addItem:[self createMenuItem:@"Check for Updates"
action:@selector(checkForUpdates:)
keyEquivalent:@""]];
[menu addItem:[NSMenuItem separatorItem]];
[menu addItem:[self createMenuItem:@"Hide"
action:@selector(hide:)
keyEquivalent:@"h"]];
[menu addItem:[self createMenuItem:@"Quit"
action:@selector(quit:)
keyEquivalent:@"q"]];
[self showMenu:menu];
NSLog(@"Default menu setup completed");
}
- (NSMenuItem *)createMenuItem:(NSString *)title
action:(SEL)action
keyEquivalent:(NSString *)keyEquivalent {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title
action:action
keyEquivalent:keyEquivalent];
item.target = self;
return item;
}
- (void)showAbout:(id)sender {
NSLog(@"Menu action: Show About");
[self showAlert:@"About"
message:@"Status Bar Application\nVersion 1.0"];
}
- (void)showPreferences:(id)sender {
NSLog(@"Menu action: Show Preferences");
[self showAlert:@"Preferences"
message:@"Preferences panel would open here"];
}
- (void)checkForUpdates:(id)sender {
NSLog(@"Menu action: Check for Updates");
[self showAlert:@"Updates"
message:@"No updates available"];
}
- (void)hide:(id)sender {
NSLog(@"Menu action: Hide");
[NSApp hide:nil];
}
- (void)quit:(id)sender {
NSLog(@"Menu action: Quit");
[NSApp terminate:nil];
}
- (void)showAlert:(NSString *)title
message:(NSString *)message {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = title;
alert.informativeText = message;
[alert runModal];
}
@end
// MARK: - 3. Status Bar with Custom View
@interface CustomViewStatusBarController : StatusBarItemController
- (void)setupCustomView;
@end
@implementation CustomViewStatusBarController
- (void)setupCustomView {
// Create custom view
NSView *customView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)];
// Create progress indicator
NSProgressIndicator *progress = [[NSProgressIndicator alloc]
initWithFrame:NSMakeRect(0, 2, 20, 16)];
progress.style = NSProgressIndicatorSpinningStyle;
[customView addSubview:progress];
[progress startAnimation:nil];
// Create text label
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(25, 2, 75, 16)];
label.stringValue = @"Active";
label.editable = NO;
label.drawsBackground = NO;
label.bordered = NO;
[customView addSubview:label];
// Set custom view
self.statusItem.button.view = customView;
NSLog(@"Custom view setup completed");
}
@end
// MARK: - 4. Status Bar with Click Action
@interface ClickableStatusBarController : StatusBarItemController
- (void)setupClickAction;
@end
@implementation ClickableStatusBarController
- (void)setupClickAction {
// Create action for click
self.statusItem.button.action = @selector(statusBarButtonClicked:);
self.statusItem.button.target = self;
// Create menu for right-click
NSMenu *menu = [[NSMenu alloc] init];
[menu addItem:[self createMenuItem:@"Open"
action:@selector(openApp:)
keyEquivalent:@"o"]];
[menu addItem:[self createMenuItem:@"Quit"
action:@selector(quit:)
keyEquivalent:@"q"]];
[self showMenu:menu];
NSLog(@"Click action setup completed");
}
- (NSMenuItem *)createMenuItem:(NSString *)title
action:(SEL)action
keyEquivalent:(NSString *)keyEquivalent {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title
action:action
keyEquivalent:keyEquivalent];
item.target = self;
return item;
}
- (void)statusBarButtonClicked:(id)sender {
NSLog(@"Status bar button clicked");
// Show alert or perform action
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = @"Status Bar Clicked";
alert.informativeText = @"You clicked the status bar icon";
[alert runModal];
}
- (void)openApp:(id)sender {
NSLog(@"Menu action: Open");
}
- (void)quit:(id)sender {
NSLog(@"Menu action: Quit");
[NSApp terminate:nil];
}
@end
// MARK: - 5. Dynamic Menu Updates
@interface DynamicMenuStatusBarController : MenuStatusBarController
@property (nonatomic, strong) NSMenuItem *toggleItem;
@property (nonatomic, assign) BOOL isEnabled;
- (void)setupDynamicMenu;
@end
@implementation DynamicMenuStatusBarController
- (void)setupDynamicMenu {
[super setupDefaultMenu];
// Add dynamic items
NSMenu *menu = self.statusItem.menu;
[menu insertItem:[NSMenuItem separatorItem] atIndex:2];
// Toggle item
self.toggleItem = [[NSMenuItem alloc] initWithTitle:@"Enable Feature"
action:@selector(toggleFeature:)
keyEquivalent:@"f"];
self.toggleItem.target = self;
self.toggleItem.state = NSControlStateValueOff;
[menu insertItem:self.toggleItem atIndex:3];
// Status item
NSMenuItem *statusItem = [[NSMenuItem alloc] initWithTitle:@"Status: Active"
action:nil
keyEquivalent:@""];
statusItem.enabled = NO;
[menu insertItem:statusItem atIndex:4];
NSLog(@"Dynamic menu setup completed");
}
- (void)toggleFeature:(id)sender {
self.isEnabled = !self.isEnabled;
if (self.isEnabled) {
self.toggleItem.state = NSControlStateValueOn;
self.toggleItem.title = @"Disable Feature";
NSLog(@"Feature enabled");
} else {
self.toggleItem.state = NSControlStateValueOff;
self.toggleItem.title = @"Enable Feature";
NSLog(@"Feature disabled");
}
}
@end
// MARK: - 6. Status Bar with Notification
@interface NotificationStatusBarController : StatusBarItemController
- (void)showNotification:(NSString *)title
message:(NSString *)message;
- (void)showNotificationWithSound:(NSString *)title
message:(NSString *)message;
@end
@implementation NotificationStatusBarController
- (void)showNotification:(NSString *)title
message:(NSString *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title;
notification.informativeText = message;
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
NSLog(@"Notification shown: %@", title);
}
- (void)showNotificationWithSound:(NSString *)title
message:(NSString *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title;
notification.informativeText = message;
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
// Also update status bar
[self setTitle:@"🔔"];
// Reset after delay
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
[self setTitle:@"App"];
});
NSLog(@"Notification with sound shown: %@", title);
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C System Tray / Status Bar Examples ===\n");
// Note: Status bar items require a running application
// These examples demonstrate the API usage patterns
NSLog(@"--- Status Bar API Examples ---\n");
// 1. Basic status bar item
NSLog(@"1. Basic Status Bar Item");
NSLog(@" StatusBarItemController *controller = [[StatusBarItemController alloc] initWithTitle:@\"App\"]");
NSLog(@" // Creates a status bar item with title\n");
// 2. Status bar with menu
NSLog(@"2. Status Bar with Menu");
NSLog(@" MenuStatusBarController *menuController = [[MenuStatusBarController alloc] initWithTitle:@\"App\"]");
NSLog(@" [menuController setupDefaultMenu];");
NSLog(@" // Creates menu with About, Preferences, Quit, etc.\n");
// 3. Status bar with custom view
NSLog(@"3. Status Bar with Custom View");
NSLog(@" CustomViewStatusBarController *customController = [[CustomViewStatusBarController alloc] initWithTitle:@"\"\"]");
NSLog(@" [customController setupCustomView];");
NSLog(@" // Adds custom view with progress indicator\n");
// 4. Status bar with click action
NSLog(@"4. Status Bar with Click Action");
NSLog(@" ClickableStatusBarController *clickController = [[ClickableStatusBarController alloc] initWithTitle:@\"App\"]");
NSLog(@" [clickController setupClickAction];");
NSLog(@" // Shows alert on left-click, menu on right-click\n");
// 5. Dynamic menu updates
NSLog(@"5. Dynamic Menu Updates");
NSLog(@" DynamicMenuStatusBarController *dynamicController = [[DynamicMenuStatusBarController alloc] initWithTitle:@\"App\"]");
NSLog(@" [dynamicController setupDynamicMenu];");
NSLog(@" // Menu items can change state dynamically\n");
// 6. Status bar with notifications
NSLog(@"6. Status Bar with Notifications");
NSLog(@" NotificationStatusBarController *notifController = [[NotificationStatusBarController alloc] initWithTitle:@\"App\"]");
NSLog(@" [notifController showNotification:@\"Update Available\" message:@\"Version 2.0 is ready\"]");
NSLog(@" // Shows system notification\n");
// Usage examples
NSLog(@"--- Usage Examples ---\n");
NSLog(@"// Create a simple status bar app:");
NSLog(@"StatusBarItemController *controller = [[StatusBarItemController alloc] initWithTitle:@\"MyApp\"]");
NSLog(@"[controller setTooltip:@\"My Status Bar App\"]\n");
NSLog(@"// Setup menu:");
NSLog(@"NSMenu *menu = [[NSMenu alloc] init];");
NSLog(@"[menu addItemWithTitle:@\"Open\" action:@selector(open:) keyEquivalent:@\"o\"]");
NSLog(@"[menu addItem:[NSMenuItem separatorItem]];");
NSLog(@"[menu addItemWithTitle:@\"Quit\" action:@selector(quit:) keyEquivalent:@\"q\"]");
NSLog(@"[controller showMenu:menu]\n");
NSLog(@"// Handle menu actions:");
NSLog(@"- (void)open:(id)sender {");
NSLog(@" NSLog(@\"Open menu item clicked\");");
NSLog(@" // Open main window");
NSLog(@"}\n");
NSLog(@"- (void)quit:(id)sender {");
NSLog(@" [NSApp terminate:nil];");
NSLog(@"}\n");
NSLog(@"// Show notification:");
NSLog(@"[controller showNotification:@\"Download Complete\"");
NSLog(@" message:@\"Your file is ready\"]\n");
NSLog(@"=== System Tray / Status Bar Examples Completed ===");
NSLog(@"\nNote: To see actual status bar items, run this code in a GUI application");
}
return 0;
}