Hello,
I'm currently working on an authorization plugin for macOS. I have a custom UI implemented using SFAuthorizationPluginView (NameAndPassword), which prompts the user to input their password. The plugin is running in non-privileged mode, and I want to store the password securely in the system keychain.
However, I came across this article that states the system keychain can only be accessed in privileged mode. At the same time, I read that custom UIs, like mine, cannot be displayed in privileged mode.
This presents a dilemma:
In non-privileged mode: I can show my custom UI but can't access the system keychain.
In privileged mode: I can access the system keychain but can't display my custom UI.
Is there any workaround to achieve both? Can I securely store the password in the system keychain while still using my custom UI, or am I missing something here?
Any advice or suggestions are highly appreciated!
Thanks in advance!
Objective-C
RSS for tagObjective-C is a programming language for writing iOS, iPad OS, and macOS apps.
Posts under Objective-C tag
190 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello developers,
I'm currently working on an authorization plugin for macOS. I have a custom UI implemented using SFAuthorizationPluginView, which prompts the user to input their password. The plugin is running in non-privileged mode, and I want to store the password securely in the system keychain.
However, I came across an article that states the system keychain can only be accessed in privileged mode. At the same time, I read that custom UIs, like mine, cannot be displayed in privileged mode.
This presents a dilemma:
In non-privileged mode: I can show my custom UI but can't access the system keychain.
In privileged mode: I can access the system keychain but can't display my custom UI.
Is there any workaround to achieve both? Can I securely store the password in the system keychain while still using my custom UI, or am I missing something here?
Any advice or suggestions are highly appreciated!
Thanks in advance! 😊
I want to understand how it manages memory allocation if i need more memory later than the memory i specified during initialisation . Does it allocates new chunk of memory and dellocate older memory or does it already allocated more memory than i asked for in first place? Just want to understand how exactly this calculation is done ?
And i do initialisation of NSMutableString in swift , will these same principle of expension applied there ?
I'm developing an authorization plugin for macOS and encountering a problem while trying to store a password in the system keychain (file-based keychain). The error message I'm receiving is:
Failed to add password: Write permissions error.
Operation status: -61
Here’s the code snippet I’m using:
import Foundation
import Security
@objc class KeychainHelper: NSObject {
@objc static func systemKeychain() -> SecKeychain? {
var searchListQ: CFArray? = nil
let err = SecKeychainCopyDomainSearchList(.system, &searchListQ)
guard err == errSecSuccess else {
return nil
}
let searchList = searchListQ! as! [SecKeychain]
return searchList.first
}
@objc static func storePasswordInSpecificKeychain(service: String, account: String, password: String) -> OSStatus {
guard let systemKeychainRef = systemKeychain() else {
print("Error: Could not get a reference to the system keychain.")
return errSecNoSuchKeychain
}
guard let passwordData = password.data(using: .utf8) else {
print("Failed to convert password to data.")
return errSecParam
}
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecValueData as String: passwordData,
kSecUseKeychain as String: systemKeychainRef // Specify the System Keychain
]
let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecSuccess {
print("Password successfully added to the System Keychain.")
} else if status == errSecDuplicateItem {
print("Item already exists. Consider updating it instead.")
} else {
print("Failed to add password: \(SecCopyErrorMessageString(status, nil) ?? "Unknown error" as CFString)")
}
return status
}
}
I am callling storePasswordInSpecificKeychain through the objective-c code. I also used privileged in the authorizationDb (system.login.console).
Are there specific permissions that need to be granted for an authorization plugin to modify the system keychain?
So I'm following this code here where I'm using a tableview to display the files contained in a folder along with a group cell to display the name of the current folder:
Here's my tableView:isGroupRow method: method which basically turns every row with the folder name into a group row (which is displayed in red in the previous image ).
-(BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row
{
DesktopEntity *entity = _tableContents[row];
if ([entity isKindOfClass:[DesktopFolderEntity class]])
{
return YES;
}
return NO;
}
and here's my tableView:viewForTableColumn:row: method where I have two if statements to decide whether the current row is a group row (meaning it's a folder) or an image:
-(NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
{
DesktopEntity *entity = _tableContents[row];
if ([entity isKindOfClass:[DesktopFolderEntity class]])
{
NSTextField *groupCell = [tableView makeViewWithIdentifier:@"GroupCell" owner:self];
[groupCell setStringValue: entity.name];
[groupCell setFont:[NSFont fontWithName:@"Arial" size:40]];
[groupCell setTextColor:[NSColor magentaColor]];
return groupCell;
}
else if ([entity isKindOfClass:[DesktopImageEntity class]])
{
NSTableCellView *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self];
[cellView.textField setStringValue: entity.name];
[cellView.textField setFont:[NSFont fontWithName:@"Impact" size:20]];
[cellView.imageView setImage: [(DesktopImageEntity *)entity image]];
return cellView;
}
return nil;
}
Now, if the current row is an image, I change its font to Impact with a size of 40 and that works perfectly, the problem here is with the first IF statement, for a group row I wanted to change the font size to arial with a size of 40 with a magenta color but for some reason I can only get the color to work:
You can see that my changes to the font size didn't work here, what gives?
How can I change the font size for the group row ?
Hi,
I have configured the stream as interleaved, but I am unsure if the function produces interleaved samples. So here my question:
Does AudioDeviceCreateIOProcID produce interleaved samples with microphone input?
Hi everyone,
I’m currently developing an MFA authorization plugin for macOS and am looking to implement a passwordless feature. The goal is to store the user's password securely when they log into the system through the authorization plugin.
However, I’m facing an issue with using the system's login keychain (Data Protection Keychain), as it runs in the user context, which isn’t suitable for my case. Therefore, I need to store the password in a file-based keychain instead.
Does anyone have experience or code snippets for objective-c for securely storing passwords in a file-based keychain (outside of the login keychain) on macOS? Specifically, I'm looking for a solution that would work within the context of a system-level authorization plugin.
Any advice or sample code would be greatly appreciated!
Thanks in advance!
Hi everyone,
I'm working on a macOS authorization plugin (NameAndPassword) to enable users to log into their system using only MFA, effectively making it passwordless. To achieve this, I'm attempting to store the user's password securely in the Keychain so it can be used when necessary without user input.
However, when I attempt to store the password, I encounter error code -25308. Below is the code I'm using to save the password to the Keychain:
objc code
(void)storePasswordInKeychain:(NSString *)password forAccount:(NSString *)accountName {
NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"com.miniOrange.nameandpassword",
(__bridge id)kSecAttrAccount: accountName,
(__bridge id)kSecValueData: passwordData,
(__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleAfterFirstUnlock
};
// Delete any existing password for the account
OSStatus deleteStatus = SecItemDelete((__bridge CFDictionaryRef)query);
if (deleteStatus == errSecSuccess || deleteStatus == errSecItemNotFound) {
[Logger debug:@"Old password entry deleted or not found."];
} else {
[Logger error:@"Failed to delete existing password: %d", (int)deleteStatus];
}
// Add the new password
OSStatus addStatus = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
if (addStatus == errSecSuccess) {
[Logger debug:@"Password successfully saved to the Keychain."];
} else {
[Logger error:@"Failed to save password: %d", (int)addStatus];
}
}
Any insights or suggestions would be greatly appreciated!
Hi,
I use AudioQueueNewInput() with my very own run loop and dedicated thread. But now it doesn't show the mic alert window.
Howto fix this?
AudioQueueNewInput(&(core_audio_port->record_format),
ags_core_audio_port_handle_input_buffer,
core_audio_port,
ags_core_audio_port_input_run_loop, kCFRunLoopDefaultMode,
0,
&(core_audio_port->record_aq_ref));
Hello,
I am currently working on a project that involves periodically querying OSLog to forward system log entries to a backend. While the functionality generally operates as expected, I have encountered a memory leak in my application. Through testing, I have isolated the issue to the following simplified code example:
#import <Foundation/Foundation.h>
#import <OSLog/OSLog.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
while(1) {
NSError *error = nil;
OSLogStore *logStore = [OSLogStore storeWithScope:OSLogStoreSystem error:&error];
if (!logStore)
NSLog(@"Failed to create log store: %@", error);
sleep(1);
}
}
return 0;
}
When running this example, the application exhibits increasing memory usage, consuming an additional 100 to 200 KB per iteration, depending on whether the build is Debug or Release.
Given that Automatic Reference Counting is enabled, I anticipated that the resources utilized by logStore would be automatically released at the end of each iteration. However, this does not appear to be the case.
Am I using the API wrong?
I would appreciate any insights or suggestions on how to resolve this issue.
Thank you.
I have an iPad app, written in objective-c and distributed through Enterprise developer, as it is not for public use but specific to some large companies.
The app has a local database and works offline
For some functions of the app I need to display images (not edit or cut them, just display them)
Right now there is integrated MWPhotoBrowser viewer, which has not been maintained for almost 10 years, so in addition to warnings in compilation I have to fight with some historical bugs especially on high resolution images. https://github.com/mwaterfall/MWPhotoBrowser
Do you know of a modern and maintained OFFLINE photo viewer? I evaluate both free and paid (maybe an SDK). My needs are very basic
I have found this one https://github.com/TimOliver/TOCropViewController, but I need to disable the photos edit features and especially I would lose the useful feature of displaying multiple images (mwphoto for multiple images showed a gallery)
We are developing remote desktop app on macOS and recently got user's report about unexpected app crash on macOS 15.2 beta.
On macOS 15.2, there's strange app crash on NSDictionary extension method.
We have narrowed down the steps and create the sample code to duplicate this issue.
Create a cocoa app project in objective-c
Try to access [NSNull null] value in NSDictionary
Use specific method name for NSDictionary extension - (long long)longLongValueForKey:(NSString*)key withDefault:(long long)defaultValue;
The console output for the example app is like below, the method pointer seems to be wrong when trying to get value with longLongValueForKey:withDefault: method to a [NSNull null] object.
********* longLongValueForKey: a: 0
********* longLongValueForKey: b: 100
********* longLongValueForKey: c: 0
********* longLongValueForKey:withDefault: a: -1
********* longLongValueForKey:withDefault: b: 100
********* exception: -[NSNull longLongValue]: unrecognized selector sent to instance 0x7ff8528d9760
********* longLongValueForKey:withDefault1: a: -1
********* longLongValueForKey:withDefault1: b: 100
********* longLongValueForKey:withDefault1: c: -1
Please create an objective-c app project and add below code to reproduce this issue.
//
// AppDelegate.m
// DictionaryTest
//
// Created by splashtop on 2024/11/13.
//
#import "AppDelegate.h"
#define IsNullObject(id) ((!id) || [id isKindOfClass:[NSNull class]])
@interface NSDictionary (extension)
(long long)longLongValueForKey:(NSString*)key;
(long long)longLongValueForKey:(NSString*)key withDefault:(long long)defaultValue;
(long long)longLongValueForKey:(NSString*)key withDefault1:(long long)defaultValue;
@end
@interface AppDelegate ()
@property (strong) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
NSDictionary* dict = @{
@"b" : @(100),
@"c" : [NSNull null],
};
@try {
long long a = [dict longLongValueForKey:@"a"];
NSLog(@"********* longLongValueForKey: a: %lld", a);
long long b = [dict longLongValueForKey:@"b"];
NSLog(@"********* longLongValueForKey: b: %lld", b);
long long c = [dict longLongValueForKey:@"c"];
NSLog(@"********* longLongValueForKey: c: %lld", c);
}
@catch(NSException* e) {
NSLog(@"********* exception: %@", e);
}
@try {
long long a = [dict longLongValueForKey:@"a" withDefault:-1];
NSLog(@"********* longLongValueForKey:withDefault: a: %lld", a);
long long b = [dict longLongValueForKey:@"b" withDefault:-1];
NSLog(@"********* longLongValueForKey:withDefault: b: %lld", b);
long long c = [dict longLongValueForKey:@"c" withDefault:-1];
NSLog(@"********* longLongValueForKey:withDefault: c: %lld", c);
}
@catch(NSException* e) {
NSLog(@"********* exception: %@", e);
}
@try {
long long a = [dict longLongValueForKey:@"a" withDefault1:-1];
NSLog(@"********* longLongValueForKey:withDefault1: a: %lld", a);
long long b = [dict longLongValueForKey:@"b" withDefault1:-1];
NSLog(@"********* longLongValueForKey:withDefault1: b: %lld", b);
long long c = [dict longLongValueForKey:@"c" withDefault1:-1];
NSLog(@"********* longLongValueForKey:withDefault1: c: %lld", c);
}
@catch(NSException* e) {
NSLog(@"********* exception: %@", e);
}
}
@end
@implementation NSDictionary (extension)
(long long)longLongValueForKey:(NSString*)key {
long long defaultValue = 0;
id value = [self objectForKey:key];
if (IsNullObject(value) || value == [NSNull null]) {
return defaultValue;
}
if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
return [value longLongValue];
}
return defaultValue;
}
(long long)longLongValueForKey:(NSString*)key withDefault:(long long)defaultValue {
id value = [self objectForKey:key];
if (IsNullObject(value) || value == [NSNull null]) {
return defaultValue;
}
if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
return [value longLongValue];
}
return defaultValue;
}
(long long)longLongValueForKey:(NSString*)key withDefault1:(long long)defaultValue {
id value = [self objectForKey:key];
if (IsNullObject(value) || value == [NSNull null]) {
return defaultValue;
}
if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
return [value longLongValue];
}
return defaultValue;
}
@end
In Xcode 16, even if Objective-C is selected, the Navigator in the documentation viewer displays Swift information.
I don't know when this bug was introduced, but it's there in the last Xcode 16 betas at least.
I hope as many developers as possible submit this bug to Apple to get their attention.
P.S. Yes, I know there's Dash. For many years, Dash was a much better option than Xcode's built-in viewer. However, in version 5, the Dash developer introduced some unfortunate UI changes that made Xcode a better option to view the documentation in certain cases. Unfortunately, the Dash developer doesn't seem to be interested in user feedback anymore. He's been ignoring suggestions and user requests for years by now.
I have an old Objective-C app that has been running for several years. The last compilation was in February 2024. I just upgraded to Sequoia 15.1.
The app has four subviews on its main view. When I run the app only the subview that was the last one instantiated is visible. I know the other subviews are there, because a random mouse click in one invisible view causes the expected change in the visible view.
What changed in 15.1 to cause this?
This is a post down memory lane for you AppKit developers and Apple engineers...
TL;DR:
When did the default implementation of NSViewController.loadView start making an NSView when there's no matching nib file? (I'm sure that used to return nil at some point way back when...)
If you override NSViewController.loadView and call [super loadView] to have that default NSView created, is it safe to then call self.view within loadView?
I'm refactoring some old Objective-C code that makes extensive use of NSViewController without any use of nibs. It overrides loadView, instantiates all properties that are views, then assigns a view to the view controller's view property. This seems inline with the documentation and related commentary in the header. I also (vaguely) recall this being a necessary pattern when not using nibs:
@interface MyViewController: NSViewController
// No nibs
// No nibName
@end
@implementation MyViewController
- (void)loadView {
NSView *hostView = [[NSView alloc] initWithFrame:NSZeroRect];
self.button = [NSButton alloc...];
self.slider = [NSSlider alloc...];
[hostView addSubview:self.button];
[hostView addSubview:self.slider];
self.view = hostView;
}
@end
While refactoring, I was surprised to find that if you don't override loadView and do all of the setup in viewDidLoad instead, then self.view on a view controller is non-nil, even though there was no nib file that could have provided the view. Clearly NSViewController has realized that:
There's no nib file that matches nibName.
loadView is not overridden.
Created an empty NSView and assigned it to self.view anyways.
Has this always been the behaviour or did it change at some point? I could have sworn that if there as no matching nib file and you didn't override loadView, then self.view would be nil.
I realize some of this behaviour changed in 10.10, as noted in the header, but there's no mention of a default NSView being created.
Because there are some warnings in the header and documentation around being careful when overriding methods related to view loading, I'm curious if the following pattern is considered "safe" in macOS 15:
- (void)loadView {
// Have NSViewController create a default view.
[super loadView];
self.button = [NSButton...];
self.slider = [NSSlider...];
// Is it safe to call self.view within this method?
[self.view addSubview:self.button];
[self.view addSubview:self.slider];
}
Finally, if I can rely on NSViewController always creating an NSView for me, even when a nib is not present, then is there any recommendation on whether one should continue using loadView or instead move code the above into viewDidLoad?
- (void)viewDidLoad {
self.button = [NSButton...];
self.slider = [NSSlider...];
// Since self.view always seems to be non-nil, then what
// does loadView offer over just using viewDidLoad?
[self.view addSubview:self.button];
[self.view addSubview:self.slider];
}
This application will have macOS 15 as a minimum requirement.
I'll describe my crash with an example, looking for some insights into the reason why this is happening.
@objc public protocol LauncherContainer {
var launcher: Launcher { get }
}
@objc public protocol Launcher: UIViewControllerTransitioningDelegate {
func initiateLaunch(url: URL, launchingHotInstance: Bool)
}
@objc final class LauncherContainer: NSObject, LauncherContainer, TabsContentCellTapHandler {
...
init(
...
) {
...
super.init()
}
...
//
// ContentCellTapHandler
//
public func tabContentCellItemDidTap(
tabId: String
) {
...
launcher.initiateNewTabNavigation(
tabId: tabId // Crash happens here
)
}
public class Launcher: NSObject, Launcher, FooterPillTapHandler {
public func initiateNewTabNavigation(tabId: String) {
...
}
}
public protocol TabsContentCellTapHandler: NSObject {
func tabContentCellItemDidTap(
tabId: String,
}
Crash stack last 2 lines are- libswiftCore.dylib swift_unknownObjectRetain libswiftCore.dylib String._bridgeToObjectiveCImpl()
String._bridgeToObjectiveCImpl() gets called when the caller and implementation is in Swift file
I believe due to @objc class LauncherContainer there'd be bridging header generated. Does that mean tabId passed to tabContentCellItemDidTap is a String but the one passed to initiateNewTabNavigation is NSString?
TabId is UUID().uuidString if that helps. Wondering if UUID().uuidString has something to do with this.
Thanks a ton for helping. Please find attached screenshot of the stack trace.
So I was trying to use an NSArrayController to bind the contents of a property , first I tried using NSDictionary and it worked great, here's what I did:
@interface ViewController : NSViewController
@property IBOutlet ArrayController * tableCities;
@end
...
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString* filePath = @"/tmp/city_test.jpeg";
NSDictionary *obj = @{@"image": [[NSImage alloc] initByReferencingFile:filePath],
@"name": @"NYC",
@"filePath": filePath};
NSDictionary *obj2 = @{@"image": [[NSImage alloc] initByReferencingFile:filePath],
@"name": @"Chicago",
@"filePath": filePath};
NSDictionary *obj3 = @{@"image": [[NSImage alloc] initByReferencingFile:filePath],
@"name": @"Little Rock",
@"filePath": filePath};
[_tableCities addObjects:@[obj, obj2, obj3]];
}
@end
Now for an NSPopUpButton, binding the Controller Key to the ArrayController and the ModelKeyPath to "name" works perfectly and the popupbutton will show the cities as I expected.
But now, instead of using an NSDictionary I wanted to use a custom class for these cities along with an NSMutableArray which holds the objects of this custom class. I'm having some trouble going about this.
There are different microphones that can be connected via a 3.5-inch jack or via USB or via Bluetooth, the behavior is the same.
There is a code that gets access to the microphone (connected to the 3.5-inch audio jack) and starts an audio capture session. At the same time, the microphone use icon starts to be displayed. The capture of the audio device (microphone) continues for a few seconds, then the session stops, the microphone use icon disappears, then there is a pause of a few seconds, and then a second attempt is made to access the same microphone and start an audio capture session. At the same time, the microphone use icon is displayed again. After a few seconds, access to the microphone stops and the audio capture session stops, after which the microphone access icon disappears.
Next, we will try to perform the same actions, but after the first stop of access to the microphone, we will try to pull the microphone plug out of the connector and insert it back before trying to start the second session. In this case, the second attempt to access begins, the running part of the program does not return errors, but the microphone access icon is not displayed, and this is the problem. After the program is completed and restarted, this icon is displayed again.
This problem is only the tip of the iceberg, since it manifests itself in the fact that it is not possible to record sound from the audio microphone after reconnecting the microphone until the program is restarted.
Is this normal behavior of the AVFoundation framework? Is it possible to somehow make it so that after reconnecting the microphone, access to it occurs correctly and the usage indicator is displayed? What additional actions should the programmer perform in this case? Is there a description of this behavior somewhere in the documentation?
Below is the code to demonstrate the described behavior.
I am also attaching an example of the microphone usage indicator icon.
Computer description: MacBook Pro 13-inch 2020 Intel Core i7 macOS Sequoia 15.1.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <AVFoundation/AVFoundation.h>
#include <Foundation/NSString.h>
#include <Foundation/NSURL.h>
AVCaptureSession* m_captureSession = nullptr;
AVCaptureDeviceInput* m_audioInput = nullptr;
AVCaptureAudioDataOutput* m_audioOutput = nullptr;
std::condition_variable conditionVariable;
std::mutex mutex;
bool responseToAccessRequestReceived = false;
void receiveResponse()
{
std::lock_guard<std::mutex> lock(mutex);
responseToAccessRequestReceived = true;
conditionVariable.notify_one();
}
void waitForResponse()
{
std::unique_lock<std::mutex> lock(mutex);
conditionVariable.wait(lock, [] { return responseToAccessRequestReceived; });
}
void requestPermissions()
{
responseToAccessRequestReceived = false;
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted)
{
const auto status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
std::cout << "Request completion handler granted: " << (int)granted << ", status: " << status << std::endl;
receiveResponse();
}];
waitForResponse();
}
void timer(int timeSec)
{
for (auto timeRemaining = timeSec; timeRemaining > 0; --timeRemaining)
{
std::cout << "Timer, remaining time: " << timeRemaining << "s" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
bool updateAudioInput()
{
[m_captureSession beginConfiguration];
if (m_audioOutput)
{
AVCaptureConnection *lastConnection = [m_audioOutput connectionWithMediaType:AVMediaTypeAudio];
[m_captureSession removeConnection:lastConnection];
}
if (m_audioInput)
{
[m_captureSession removeInput:m_audioInput];
[m_audioInput release];
m_audioInput = nullptr;
}
AVCaptureDevice* audioInputDevice = [AVCaptureDevice deviceWithUniqueID: [NSString stringWithUTF8String: "BuiltInHeadphoneInputDevice"]];
if (!audioInputDevice)
{
std::cout << "Error input audio device creating" << std::endl;
return false;
}
// m_audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioInputDevice error:nil];
// NSError *error = nil;
NSError *error = [[NSError alloc] init];
m_audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioInputDevice error:&error];
if (error)
{
const auto code = [error code];
const auto domain = [error domain];
const char* domainC = domain ? [domain UTF8String] : nullptr;
std::cout << code << " " << domainC << std::endl;
}
if (m_audioInput && [m_captureSession canAddInput:m_audioInput]) {
[m_audioInput retain];
[m_captureSession addInput:m_audioInput];
}
else
{
std::cout << "Failed to create audio device input" << std::endl;
return false;
}
if (!m_audioOutput)
{
m_audioOutput = [[AVCaptureAudioDataOutput alloc] init];
if (m_audioOutput && [m_captureSession canAddOutput:m_audioOutput])
{
[m_captureSession addOutput:m_audioOutput];
}
else
{
std::cout << "Failed to add audio output" << std::endl;
return false;
}
}
[m_captureSession commitConfiguration];
return true;
}
void start()
{
std::cout << "Starting..." << std::endl;
const bool updatingResult = updateAudioInput();
if (!updatingResult)
{
std::cout << "Error, while updating audio input" << std::endl;
return;
}
[m_captureSession startRunning];
}
void stop()
{
std::cout << "Stopping..." << std::endl;
[m_captureSession stopRunning];
}
int main()
{
requestPermissions();
m_captureSession = [[AVCaptureSession alloc] init];
start();
timer(5);
stop();
timer(10);
start();
timer(5);
stop();
}
For a personal project, I have been writing some library to interface the CoreBluetooth API with the go language. Because of what it does, that library is written in objective-C with ARC disabled.
One function I had to write takes a memory buffer (allocated with malloc() on the go side), creates an NSData object out of it to pass the data to the writeValue:forCharacteristic:type: CoreBluetooth method, and then releases the NSData as well as the original memory buffer:
void Write(CBPeripheral *p, CBCharacteristic *c, void *bytes, int len) {
NSData *data = [NSData dataWithBytesNoCopy:bytes length:len freeWhenDone:true];
[p writeValue:data forCharacteristic:c type:CBCharacteristicWriteWithoutResponse];
[data release];
}
One thing I noticed is that the retainCount for data increases during the writeValue:forCharacteristic:type: API call. It is 1 before, and 2 after. This is surprising to me, because the documentation says "This method copies the data passed into the data parameter, and you can dispose of it after the method returns."
I suspects this results in a memory leak. Am I missing something here ?
I have an NSMutableArray defined as a property in my ViewController class:
@interface ViewController ()
@property NSMutableArray *tableCities;
@end
When the "Add" button is clicked, a new city is added:
NSString* filePath = @"/tmp/city_test.jpeg";
NSDictionary *obj = @{@"image": [[NSImage alloc] initByReferencingFile:filePath],
@"name": @"testCity",
@"filePath": filePath};
[_tableCities addObject: obj];
Okay, this is fine, it is adding a new element to this NSMutableArray, now what I want is to somehow bind the "name" field of each city to my NSPopUpButton.
So in storyboard I created an NSArrayController and tried to set its "Model Key Path" to my NSMutableArray as shown below:
Then I tried to bind the NSPopUpButton to the NSArrayController as follows:
but it doesn't work either, a city is added but the NSPopUpButton isn't displaying anything, what gives?