I understand the mvc thing kinda, theres an array as a model, a tableview as a control, and the interface as a control (right?)
so like, I drag an array controller on to the form display thing, assign a delegate to it the view and app module/header, add data to it and the tableview updates after I add a function to it? in vs the events are in the event browser, do I just copy and paste the code from the tutorial?
how do I add controls and do all the advanced stuff? the documentation on developer.apple.com isnt that detailed, and most books are outdated or n/a since its objective c
tutorials would be nice, some home grown method would be cool too
thank you
unidef warrell yashizzo
Objective-C
RSS for tagObjective-C is a programming language for writing iOS, iPad OS, and macOS apps.
Posts under Objective-C tag
192 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
For a Cocoa project I have this table view controller:
@interface TableViewController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
@property (nonatomic, strong) NSMutableArray *numbers;
@property (nonatomic, strong) NSMutableArray *letters;
@end
#import "TableViewController.h"
@implementation TableViewController
- (NSMutableArray *)numbers
{
if (!_numbers)
{
_numbers = [NSMutableArray arrayWithArray:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10"]];
}
return _numbers;
}
- (NSMutableArray *)letters
{
if (!_letters)
{
_letters = [NSMutableArray arrayWithArray: @[@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j"]];
}
return _letters;
}
// NSTableViewDataSource Protocol Method
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return self.numbers.count;
}
// NSTableViewDelegate Protocol Method
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSString *identifier = tableColumn.identifier;
NSTableCellView *cell = [tableView makeViewWithIdentifier:identifier owner:self];
if ([identifier isEqualToString:@"numbers"])
{
cell.textField.stringValue = [self.numbers objectAtIndex:row];
}
else
{
cell.textField.stringValue = [self.letters objectAtIndex:row];
}
return cell;
}
In the storyboard I created a NSTableView and set up the connection, after running it I get what I expected:
okay, cool, but I have a question:
why is this working even though I haven't created a NSTableView as a property for my ViewController or for my TableViewController?
Also, there's another problem, now I want to add a button to this window such that, every time I click it, a new item should be added to this table(for now it can be anything)
So I created a button and a method for this and linked the action to the story board:
-(IBAction) addNewNumber:(id)sender
{
[_numbers addObject:@"1234"];
[_letters addObject:@"testing"];
}
Now, every time I click this button I can see that this method is indeed being called and that indeed IT IS adding a new member to these arrays, the thing is, the table is not being updated, what gives? Any advice on how I can fix this behavior?
I understand we can use MPSImageBatch as input to
[MPSNNGraph encodeBatchToCommandBuffer: ...]
method.
That being said, all inputs to the MPSNNGraph need to be encapsulated in a MPSImage(s).
Suppose I have an machine learning application that trains/infers on thousands of input data where each input has 4 feature channels. Metal Performance Shaders is chosen as the primary AI backbone for real-time use.
Due to the nature of encodeBatchToCommandBuffer method, I will have to create a MTLTexture first as a 2D texture array. The texture has pixel width of 1, height of 1 and pixel format being RGBA32f.
The general set up will be:
#define NumInputDims 4
MPSImageBatch * infBatch = @[];
const uint32_t totalFeatureSets = N;
// Each slice is 4 (RGBA) channels.
const uint32_t totalSlices = (totalFeatureSets * NumInputDims + 3) / 4;
MTLTextureDescriptor * descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatRGBA32Float
width: 1
height: 1
mipmapped: NO];
descriptor.textureType = MTLTextureType2DArray
descriptor.arrayLength = totalSlices;
id<MTLTexture> texture = [mDevice newTextureWithDescriptor: descriptor];
// bytes per row is `4 * sizeof(float)` since we're doing one pixel of RGBA32F.
[texture replaceRegion: MTLRegionMake3D(0, 0, 0, 1, 1, totalSlices)
mipmapLevel: 0
withBytes: inputFeatureBuffers[0].data()
bytesPerRow: 4 * sizeof(float)];
MPSImage * infQueryImage = [[MPSImage alloc] initWithTexture: texture
featureChannels: NumInputDims];
infBatch = [infBatch arrayByAddingObject: infQueryImage];
The training/inference will be:
MPSNNGraph * mInferenceGraph = /*some MPSNNGraph setup*/;
MPSImageBatch * returnImage = [mInferenceGraph encodeBatchToCommandBuffer: commandBuffer
sourceImages: @[infBatch]
sourceStates: nil
intermediateImages: nil
destinationStates: nil];
// Commit and wait...
// Read the return image for the inferred result.
As you can see, the setup is really ad hoc - a lot of 1x1 pixels just for this sole purpose.
Is there any better way I can achieve the same result while still on Metal Performance Shaders? I guess a further question will be: can MPS handle general machine learning cases other than CNN? I can see the APIs are revolved around convolution network, both from online documentations and header files.
Any response will be helpful, thank you.
I have a Cocoa application and I'm trying to set up an NSImageView without using story board (using storyboard works just fine tho).
Also, I'm kinda new to Cocoa so any advice is appreciated.
Anyway so here's the deal, I created a class to encapsulate this image:
@interface MyView : NSView
{
@private
NSImageView* imageView;
}
@end
@implementation MyView
-(id) initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if(self)
{
NSRect rect = NSMakeRect(10, 10, 100, 200);
imageView = [[NSImageView alloc] initWithFrame:rect];
NSImage* image = [NSImage imageNamed:@"bob.jpeg"];
[imageView setImageScaling:NSImageScaleNone];
[imageView setImage: image];
[self addSubview: imageView];
}
return self;
}
-(id) init
{
return [self initWithFrame:NSMakeRect(10, 10, 100, 100)];
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
// Drawing code here.
}
@end
Now, in the view controller file, in the viewDidLoad I tried to load add this as a subview to get it to display my image:
- (void)viewDidLoad
{
[super viewDidLoad];
MyView *customView = [[MyView alloc] init];
[self.view addSubview:customView];
}
This kinda works, except that it loads the image twice, I ended up with two images instead of just one like I intended, what gives? what am I doing wrong here?
We're trying to implement a backup/restore data feature in our business productivity iPad app using UIDocumentPickerViewController and AppleArchive, but discovered odd behavior of [UIDocumentPickerViewController initForOpeningContentTypes: asCopy:YES] when reading large archive files from a USB drive.
We've duplicated this behavior with iPadOS 16.6.1 and 17.7 when building our app with Xcode 15.4 targeting minimum deployment of iPadOS 16. We haven't tested this with bleeding edge iPadOS 18.
Here's our Objective-C code which presents the picker:
NSArray* contentTypeArray = @[UTTypeAppleArchive];
UIDocumentPickerViewController* docPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypeArray asCopy:YES];
docPickerVC.delegate = self;
docPickerVC.allowsMultipleSelection = NO;
docPickerVC.shouldShowFileExtensions = YES;
docPickerVC.modalPresentationStyle = UIModalPresentationPopover;
docPickerVC.popoverPresentationController.sourceView = self.view;
[self presentViewController:docPickerVC animated:YES completion:nil];
The UIDocumentPickerViewController remains visible until the selected external archive file has been copied from the USB drive to the app's local tmp sandbox. This may take several seconds due to the slow access speed of the USB drive. During this time the UIDocumentPickerViewController does NOT disable its tableview rows displaying files found on the USB drive. Even the most patient user will tap the desired filename a second (or third or fourth) time since the user's initial tap appears to have been ignored by UIDocumentPickerViewController, which lacks sufficient UI feedback showing it's busy copying the selected file.
When the user taps the file a second time, UIDocumentPickerViewController apparently begins to copy the archive file once again. The end result is a truncated copy of the selected file based on the time between taps. For instance, a 788 MB source archive may be copied as a 56 MB file. Here, the UIDocumentPickerDelegate receives a 56 MB file instead of the original 788 MB of data.
Not surprisingly, AppleArchive fails to decrypt the local copy of the archive because it's missing data. Instead of failing gracefully, AppleArchive crashes in AAArchiveStreamClose() (see forums post 765102 for details).
Does anyone know if there's a workaround for this strange behavior of UIDocumentPickerViewController?
I am trying to set my UITextView as the first responder with [self.textView becomeFirstResponder] when my view controller called viewDidAppear.
But sometimes it will cause crash with the error: [__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
all I did is just:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.textView becomeFirstResponder];
}
So if anyone can tell me what happened and how to do? when I call the [self.textView becomeFirstResponder], what will be insert into the responders list? self.textView itself?
Thanks very much!
I have an object that is an NSRuleEditorDelegate for an NSRuleEditor whose nestingMode is NSRuleEditorNestingModeList. There are 8 different possible criteria. Each criterion is optional but at least 1 is required (ruleEditor.canRemoveAllRows = NO). Each criterion should only be added once. How can I limit adding a criterion for a row if it is already in the editor at a different row?
Thanks!
I've implemented Push Provisioning, but am having trouble testing it.
When I try to add a payment pass with my activationData, encryptedPassData, and ephemeralPublicKey, I see the "Add Card to Apple Pay" screen, but then when I click "Add Card", I get a "Could Not Add Card" message.
When I inspect the error from didFinishAddingPaymentPass, it reads "The operation couldn’t be completed. (PKPassKitErrorDomain error 2.)".
Is this error PKPassKitError.Code.unsupportedVersionError? What does this error means?
Additional context:
We use cordova-apple-wallet to generate certificates and add payment pass.
We have developed an iOS app in objective-C and added integrations for shortcuts app - more specific the "automation" part of the app.
Basically, user opens shortcuts app, select automation and when scanning NFC tag, user can select an action and our app shows 3 different actions. User select action, opens the app and action is executed. That all done in Obj-C and was working very well with no complaints till users start to update to iOS18.
Now, when user starts to add automation, only thing they can do is select "open app". Our app actions are not showing any more. Is there something new in iOS 18 we have to update our app.
I know Obje-C is considered "old", but the cost of upgrading an existing app and time is not available at the moment.
Here's a code snippet of our shortcutIntent:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.lw.grp1</string>
<string>group.lw.grp2</string>
</array>
</dict>
</plist>
Shortcut Info-plist
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsRestrictedWhileLocked</key>
<array/>
<key>IntentsRestrictedWhileProtectedDataUnavailable</key>
<array/>
<key>IntentsSupported</key>
<array>
<string>LockIntent</string>
<string>TrunkIntent</string>
<string>UnlockIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.intents-service</string>
<key>NSExtensionPrincipalClass</key>
<string>IntentHandler</string>
</dict>
</dict>
</plist>
IntentHandler
-(id)init{
self = [super init];
self.started = false;
self.handler = [[AppIntentHandler alloc] init];
self.handler.userInfo = [[NSMutableDictionary alloc] init];
return self;
}
- (id)handlerForIntent:(INIntent *)intent {
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
if(!self.started){
self.started = YES;
if([intent isKindOfClass:[LockIntent class]]){
NSLog(@"*intent lock selected*");
self.handler.userInfo = [self assignUserInfo:@"lock"];
}else if([intent isKindOfClass:[UnlockIntent class]]){
NSLog(@"*intent unlock selected*");
self.handler.userInfo = [self assignUserInfo:@"unlock"];
}else if([intent isKindOfClass:[TrunkIntent class]]){
NSLog(@"*intent trunk selected*");
self.handler.userInfo = [self assignUserInfo:@"trunk"];
}
}else{
self.started = NO;
}
return self.handler;
}
A custom class to handle each intent
@implementation AppIntentHandler
#pragma mark - response handlers
- (void)handleLock:(nonnull LockIntent *)intent completion:(nonnull void (^)(LockIntentResponse * _Nonnull))completion {
LockIntentResponse *response = [[LockIntentResponse alloc] initWithCode:LockIntentResponseCodeContinueInApp userActivity:[self lockUserActivity]];
completion(response);
}
- (void)handleUnlock:(nonnull UnlockIntent *)intent completion:(nonnull void (^)(UnlockIntentResponse * _Nonnull))completion {
UnlockIntentResponse *response = [[UnlockIntentResponse alloc] initWithCode:UnlockIntentResponseCodeContinueInApp userActivity:[self unlockUserActivity]];
completion(response);
}
- (void)handleTrunk:(nonnull TrunkIntent *)intent completion:(nonnull void (^)(TrunkIntentResponse * _Nonnull))completion {
TrunkIntentResponse *response = [[TrunkIntentResponse alloc] initWithCode:TrunkIntentResponseCodeContinueInApp userActivity:[self trunkUserActivity]];
completion(response);
}
What have changed and what needs to be done to make our app's actions show in shortcuts app again. Could anyone point me to the right direction, documentations, blog post or code snippet?
Thanks in advance for taking the time to help!
In Xcode 16.0 and 16.1 beta 2, running on macOS 15.1 beta 4, Developer Documentation for Objective-C is (at least partially) missing in the Navigator. Many of the entries appear to be for Swift.
In Xcode 16.1 beta (i.e. beta 1), the documentation is normal.
I did not find any posts in this forum about this, which is surprising and makes me wonder if the issue is isolated to particular configurations.
In any event, I would appreciate any information anyone may have about this.
My project use manual reference counting and crash with UIAlertController when touch to Action Button:
UIAlertController alert = [[UIAlertController
alertControllerWithTitle:@"fsđs"
message:@"fsđs"
preferredStyle:UIAlertControllerStyleAlert
]autorelease];
UIAlertAction actionOk = [UIAlertAction actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:actionOk];
[self.window.rootViewController presentViewController:alert animated:YES
completion:^{
}];
Hello we have created a function that is expanding copy module to support html format. Everything inside that function works fine but on 17.4+ IOS version copying the html element strike-through tag is not working (other HTML elements are working fine) . Looking the logs seems like are getting stripped. Also list that have indents won't work on paste indent is missing. Here is the code:
void copyToClipboard(NSString *htmlContent) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
[pasteboard setValue:htmlContent forPasteboardType:@"public.html"];
}
Does anyone know fix for this or when this will be fixed or will it be fixed in next update?
I am working with a React Native application that needs CPU usage data for debugging in a Production Release. Currently the module I wrote works for development but when the application is built for release that specific module errors out. I need help with configuring my Xcode project to include this module when building for release
I have a simple cocoa project, it has the default files like AppDelegate.m, AppDelegate.h , ViewController.h and ViewController.m what I want is to set the Window title to the dimension of the current window and update it as the user resizes it.
My Storyboard has an Application Scene, a Window Controller Scene and a test Scene which contains my view:
how do I go about this? should my ViewController or AppController implement NSWindowDelegate ?
I have an application with storyboard and I'm trying to set a constraint for the minimum size of my window (the view), but now matter what I do the constraint window is always grayed out, how do I go about this?
Hello,
PMSessionValidatePrintSettings return always "false" on macOS
PMPrintSettings settings;
PMPrintSession session;
Boolean result;
PMCreateSession(&session);
PMSessionSetCurrentPMPrinter(session, printer);
PMCreatePrintSettings(&settings);
PMSessionDefaultPrintSettings(session, settings);
PMSetDuplex(settings, kPMDuplexTumble);
PMSessionValidatePrintSettings(session, settings, &result);
PMRelease(session);
PMRelease(settings);
if (result) NSLog (@"%@", @"changed");
else NSLog (@"%@", @"not changed");
Thanks
After upgrading to Xcode16RC, in an old project based on ObjC, I directly used the following controller code in AppDelegate:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UIButton *b = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 44, 44)];
[b setTitle:@"title" forState:UIControlStateNormal];
[self.view addSubview:b];
[b addTarget:self action:@selector(onB:) forControlEvents:UIControlEventTouchUpInside];
}
- (IBAction)onB:(id)sender{
PHPickerConfiguration *config = [[PHPickerConfiguration alloc]initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
config.preferredAssetRepresentationMode = PHPickerConfigurationAssetRepresentationModeCurrent;
config.selectionLimit = 1;
config.filter = nil;
PHPickerViewController *picker = [[PHPickerViewController alloc]initWithConfiguration:config];
picker.modalPresentationStyle = UIModalPresentationFullScreen;
picker.delegate = self;
[self presentViewController:picker animated:true completion:nil];
}
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results{
}
Environment: Simulator iPhone 15 Pro (iOS18)
Before this version (iOS17.4), clicking the button to pop up the system photo picker interface was normal (the top boundary was within the SafeAreaGuide area), but now the top boundary of the interface aligns directly to the top of the window, and clicking the photo cell is unresponsive.
If I create a new Target, using the same codes, the photo picker page does not have the above problem.
Therefore, I suspect it may be due to the old project’s .proj file’s info.plist, buildSetting, or buildPhase lacking some default configuration key value required by the new version, (My project was built years ago may be from iOS13 or earlier ) but I cannot confirm the final cause.
iOS18.0 has the additional messages:
objc[79039]: Class UIAccessibilityLoaderWebShared is implemented in both /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/AccessibilityBundles/WebCore.axbundle/WebCore (0x198028328) and /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/AccessibilityBundles/WebKit.axbundle/WebKit (0x1980fc398). One of the two will be used. Which one is undefined.
AX Safe category class 'SLHighlightDisambiguationPillViewAccessibility' was not found!
Has anyone encountered the same issue as me?
So I have this program that displays events on the window using NSWindow and a NSTextField. Basically it tracks the mouse position and the keyboard state.
I created a simple class named MyEventWindow:
//
// MyEventWindow.h
// AppTest
#ifndef MyEventWindow_h
#define MyEventWindow_h
@interface MyEventWindow : NSWindow
{
}
@property(nonatomic, strong) NSTextField* label;
@property(nonatomic, strong) NSString* labelText;
- (BOOL)windowShouldClose:(id)sender;
- (instancetype) init;
- (void) setLabelText:(NSString *)labelText;
@end
@implementation MyEventWindow
-(instancetype) init
{
self = [super initWithContentRect:NSMakeRect(100, 100, 300, 300)
styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable)
backing:NSBackingStoreBuffered
defer:NO];
if( !self )
{
return nil;
}
[self setTitle: @"Event tracker"];
[self setIsVisible: YES];
_label = [[NSTextField alloc] initWithFrame:NSMakeRect(5, 100, 290, 100)];
[_label setBezeled: NO];
[_label setDrawsBackground: NO];
[_label setEditable: NO];
[_label setSelectable: YES];
NSFont *currentFont = [_label font];
NSFont *resizedFont = [NSFont fontWithName:[currentFont fontName] size:18];
NSFont *boldFont = [[NSFontManager sharedFontManager] convertFont:resizedFont toHaveTrait:NSFontBoldTrait];
// convert the bold font to have the italic trait
NSFont *boldItalicFont = [[NSFontManager sharedFontManager] convertFont:boldFont toHaveTrait:NSFontItalicTrait];
[_label setFont:boldItalicFont];
[_label setTextColor:[NSColor colorWithSRGBRed:0.0 green:0.5 blue:0.0 alpha:1.0]];
// attach label to the damn window
[[self contentView] addSubview: _label];
return self;
}
-(BOOL)windowShouldClose:(id)sender
{
return YES;
}
-(void) setLabelText:(NSString *)newText
{
[_label setStringValue: newText];
}
@end
#endif /* MyEventWindow_h */
Then in the main file I try to handle event loop manually:
//
// main.m
#import <Cocoa/Cocoa.h>
#import "MyEventWindow.h"
NSString* NSEventTypeToNSString(NSEventType eventType);
NSString* NSEventModifierFlagsToNSString(NSEventModifierFlags modifierFlags);
int main(int argc, char* argv[])
{
@autoreleasepool
{
[NSApplication sharedApplication];
MyEventWindow* eventWindow = [[MyEventWindow alloc] init];
[eventWindow makeKeyAndOrderFront:nil];
NSString* log = [NSString string];
// my own message loop
[NSApp finishLaunching];
while (true)
{
@autoreleasepool
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate: [NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
log = [NSString stringWithFormat:@"Event [type=%@ location={%d, %d} modifierFlags={%@}]", NSEventTypeToNSString([event type]), (int)[event locationInWindow].x, (int)[event locationInWindow].y, NSEventModifierFlagsToNSString([event modifierFlags])];
//NSLog(@"log: %@", log);
[eventWindow setLabelText: log];
[NSApp sendEvent:event];
//[NSApp updateWindows]; // redundant?
}
}
}
return 0;
}
NSString* NSEventTypeToNSString(NSEventType eventType)
{
switch (eventType)
{
case NSEventTypeLeftMouseDown: return @"LeftMouseDown";
case NSEventTypeLeftMouseUp: return @"LeftMouseUp";
case NSEventTypeRightMouseDown: return @"RightMouseDown";
case NSEventTypeRightMouseUp: return @"RightMouseUp";
case NSEventTypeMouseMoved: return @"MouseMoved";
case NSEventTypeLeftMouseDragged: return @"LeftMouseDragged";
case NSEventTypeRightMouseDragged: return @"RightMouseDragged";
case NSEventTypeMouseEntered: return @"MouseEntered";
case NSEventTypeMouseExited: return @"MouseExited";
case NSEventTypeKeyDown: return @"KeyDown";
case NSEventTypeKeyUp: return @"KeyUp";
case NSEventTypeFlagsChanged: return @"FlagsChanged";
case NSEventTypeAppKitDefined: return @"AppKitDefined";
case NSEventTypeSystemDefined: return @"SystemDefined";
case NSEventTypeApplicationDefined: return @"ApplicationDefined";
case NSEventTypePeriodic: return @"Periodic";
case NSEventTypeCursorUpdate: return @"CursorUpdate";
case NSEventTypeScrollWheel: return @"ScrollWheel";
case NSEventTypeTabletPoint: return @"TabletPoint";
case NSEventTypeTabletProximity: return @"TabletProximity";
case NSEventTypeOtherMouseDown: return @"OtherMouseDown";
case NSEventTypeOtherMouseUp: return @"OtherMouseUp";
case NSEventTypeOtherMouseDragged: return @"OtherMouseDragged";
default:
return [NSString stringWithFormat:@"%lu", eventType];
}
}
NSString* NSEventModifierFlagsToNSString(NSEventModifierFlags modifierFlags)
{
NSString* result = @"";
if ((modifierFlags & NSEventModifierFlagCapsLock) == NSEventModifierFlagCapsLock)
result = [result stringByAppendingString:@"CapsLock, "];
if ((modifierFlags & NSEventModifierFlagShift) == NSEventModifierFlagShift)
result = [result stringByAppendingString:@"NShift, "];
if ((modifierFlags & NSEventModifierFlagControl) == NSEventModifierFlagControl)
result = [result stringByAppendingString:@"Control, "];
if ((modifierFlags & NSEventModifierFlagOption) == NSEventModifierFlagOption)
result = [result stringByAppendingString:@"Option, "];
if ((modifierFlags & NSEventModifierFlagCommand) == NSEventModifierFlagCommand)
result = [result stringByAppendingString:@"Command, "];
if ((modifierFlags & NSEventModifierFlagNumericPad) == NSEventModifierFlagNumericPad)
result = [result stringByAppendingString:@"NumericPad, "];
if ((modifierFlags & NSEventModifierFlagHelp) == NSEventModifierFlagHelp)
result = [result stringByAppendingString:@"Help, "];
if ((modifierFlags & NSEventModifierFlagFunction) == NSEventModifierFlagFunction)
result = [result stringByAppendingString:@"Function, "];
return result;
}
in main I added a second @autoreleasepool inside the while loop it seemed to decrease memory usage significanly, however if I keep moving my mouse a lot the memory usage will still increase.
I don't think this should be happening since the labelText is being destroying and recreated each iteration, is something wrong with my code? Why do I have a memory leak here?
Any feedback regarding the code is also appreciated
Cheers
I created a simple application which displays a window with a sample text and I'm supposed to use an alert when the user chooses to close the application, if he presses ok in the alert the application will close, if he presses cancel it goes on.
So pretty simple code, I have a window class:
//
// MyWindow.h
// AppTest
//
// Created by sanya on 11/09/24.
//
#ifndef MyWindow_h
#define MyWindow_h
@interface Window : NSWindow
{
NSTextField* label;
}
- (instancetype)init;
- (BOOL)windowShouldClose:(id)sender;
@end
@implementation Window
-(instancetype)init
{
label = [[[NSTextField alloc] initWithFrame:NSMakeRect(5, 100, 290, 100)] autorelease];
[label setStringValue:@"Hello, World!"];
[label setBezeled:NO];
[label setDrawsBackground:NO];
[label setEditable:YES];
[label setSelectable:YES];
[label setTextColor:[NSColor colorWithSRGBRed:0.0 green:0.5 blue:0.0 alpha:1.0]];
[label setFont:[[NSFontManager sharedFontManager] convertFont:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:[[label font] fontName] size:45] toHaveTrait:NSFontBoldTrait] toHaveTrait:NSFontItalicTrait]];
[super initWithContentRect:NSMakeRect(0, 0, 300, 300) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO];
[self setTitle:@"Hello world (label)"];
[[self contentView] addSubview:label];
[self center];
[self setIsVisible:YES];
return self;
}
- (BOOL)windowShouldClose:(id)sender
{
BOOL bClose = NO;
CFOptionFlags responseFlags = 0;
// Display the alert
CFUserNotificationDisplayAlert(
0,
kCFUserNotificationNoteAlertLevel,
NULL,
NULL,
NULL,
CFSTR("Alert Title"),
CFSTR("This is a message displayed in the alert."),
CFSTR("OK"),
CFSTR("Cancel"),
NULL,
&responseFlags
);
if (responseFlags == kCFUserNotificationDefaultResponse)
{
NSLog(@"User clicked OK");
bClose = YES;
}
else if (responseFlags == kCFUserNotificationAlternateResponse)
{
NSLog(@"User clicked Cancel");
}
if( bClose )
[NSApp terminate:sender];
return bClose;
}
@end
#endif /* MyWindow_h */
And in the main function I just initialize it:
int main(int argc, const char * argv[])
{
[NSApplication sharedApplication];
[[[[Window alloc] init] autorelease] makeMainWindow];
[NSApp run];
}
It seems to work but if click 'Cancel' on the dialog , xcode gives me the following warning:
CLIENT ERROR: TUINSRemoteViewController does not override -viewServiceDidTerminateWithError: and thus cannot react to catastrophic errors beyond logging them
So i'm obviously not doing this in the correct way, how can I fix this?
Also, any feedback on this code as a whole is highly appreciated.
So I wanted to get my hands dirty with objective-c so I decided to create a project to list all outbound traffic, after digging a little I found that I could use the Network Extension API. I created a simple command line project with xcode and tried to load this extension but for some reason I can't get it to work.
I don't have a developer license yet and I'm not sure if it has anything to do with the problem I'm facing.
This is just some test code so there are 2 free functions, one for loading the system extension and another for checking its status:
// activates the extension?
BOOL toggleNetworkExtension(NSUInteger action)
{
BOOL toggled = NO;
__block BOOL wasError = NO;
__block NEFilterProviderConfiguration* config = nil;
dispatch_semaphore_t semaphore = 0;
semaphore = dispatch_semaphore_create(0);
NSLog(@"toggling the network extension");
[NEFilterManager.sharedManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if(nil != error)
{
wasError = YES;
NSLog(@"loadFromPreferencesWithCompletionHandler error");
}
dispatch_semaphore_signal(semaphore);
}];
NSLog(@"waiting for the network extension configuration...");
if(YES == wasError) goto fail;
NSLog(@"loaded current filter configuration for the network extension");
if(1 == action)
{
NSLog(@"activating network extension...") ;
if(nil == NEFilterManager.sharedManager.providerConfiguration)
{
config = [[NEFilterProviderConfiguration alloc] init];
config.filterPackets = NO;
config.filterSockets = YES;
NEFilterManager.sharedManager.providerConfiguration = config;
}
NEFilterManager.sharedManager.enabled = YES;
}
else
{
NSLog(@"deactivating the network extension...");
NEFilterManager.sharedManager.enabled = NO;
}
{ [NEFilterManager.sharedManager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if(nil != error)
{
wasError = YES;
NSLog(@"saveToPreferencesWithCompletionHandler error!");
}
dispatch_semaphore_signal(semaphore);
}]; }
NSLog(@"waiting for network extension configuration to save...");
if(YES == wasError) goto fail;
NSLog(@"saved current filter configuration for the network extension");
toggled = YES;
fail:
return toggled;
}
Then there's this function to check if the extension is enabled which for some reason always returns false.
BOOL isNetworkExtensionEnabled(void)
{
__block BOOL isEnabled = NO;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[NEFilterManager.sharedManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if (error != nil)
{
NSLog(@"Error with loadFromPreferencesWithCompletionHandler");
}
else
{
isEnabled = NEFilterManager.sharedManager.enabled;
}
dispatch_semaphore_signal(semaphore);
}];
return isEnabled;
}
Is something wrong is this code or is this related to entitlements or the developer license?
As a side note I have already disabled SIP not sure if it matters in this case.
Thanks in advance.