Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e57a473
this implements separate wrappers for ObjC classes and instances, and…
hhas Jan 23, 2022
99e2b92
added quick-n-dirty test script (mostly to check that method calling …
hhas Jan 23, 2022
7380fee
* `InOutRef` now works (albeit only for ObjC instances for now, until…
hhas Jan 26, 2022
d6c8e5b
bump
hhas Jan 26, 2022
0e2bd2e
* fixed bugs in `ObjCObject[toPrimitive]`
hhas Jan 27, 2022
685fead
* testing, debugging, rearranging internal APIs
hhas Jan 27, 2022
b16c84c
more testing, debugging, straightening out kinks (of note: `Proxy` pa…
hhas Jan 30, 2022
e007c88
disentangling JS representations of ObjC objects (final representatio…
hhas Jan 30, 2022
70d0785
* moved `objc.types` to `objc.__internal__.types`; decluttering `util…
hhas Jan 31, 2022
1849a67
* fixed [hopefully] `util.inspect.custom` support in ObjCObjects
hhas Feb 4, 2022
dc89010
fixed an error in the neverending whackamole that is trying to make `…
hhas Feb 4, 2022
333f0ca
updated readme
hhas Feb 4, 2022
9707831
* rewrote ObjC type bridging to use ref-napi-compatible type definiti…
hhas Feb 17, 2022
5931adb
* `ns()` should be faster at packing collections (although it's still…
hhas Feb 19, 2022
c826505
fixed regression; method wrapper throws more descriptive error message
hhas Feb 19, 2022
66b1ee4
bug fixes in `isClass`, `isInstance`
hhas Feb 22, 2022
0e8af70
* redesigned `objc.structs` API; this now uses standard `StructType` …
hhas Feb 28, 2022
111147e
* reworked block and struct APIs for consistency and ease of use (the…
hhas Mar 2, 2022
29ee162
unbroke the build
hhas Mar 3, 2022
1d22aa4
* renamed `create-class.js` to `subclass.js`; updated its implementat…
hhas Mar 5, 2022
8be2533
* simplified block and struct API (all types now appear on top-level …
hhas Mar 10, 2022
2166589
tweaking, tidying
hhas Mar 22, 2022
37576ab
* create a new instance of `ObjCTypeEncodingParser` for each use (sha…
hhas May 17, 2022
78c3df3
API tweaks
hhas Jan 15, 2023
d673d79
Merge branch 'master' of https://github.com/hhas/objc
hhas Jan 15, 2023
9bb5c34
remove stray crud that broke package.json
hhas Feb 25, 2023
59b6d12
bugfix in objctypes
hhas Feb 25, 2023
1e809f2
updated version to 0.24.1
hhas Feb 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ build/
yarn-error.log
.nyc_output/
coverage/
~*
93 changes: 0 additions & 93 deletions changelog.md

This file was deleted.

28 changes: 23 additions & 5 deletions examples/applescript.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
#!/usr/bin/env node

const objc = require('../src/index');

const {NSAppleScript} = objc;
const {NSAppleScript, Ref} = objc;

{
const script = NSAppleScript.alloc().initWithSource_(`
tell application "System Events" to get name of current user
`);

const err = new Ref();
const result = script.executeAndReturnError_(err);
console.log('result:', result); // [objc: <NSAppleEventDescriptor: 'utxt'("lukas")>]
console.log('error:', err.deref()); // null
}

const script = NSAppleScript.alloc().initWithSource_(`tell application "System Events" to get name of current user`);
{
const script = NSAppleScript.alloc().initWithSource_(`
this is not valid code
`);

const err = objc.allocRef();
const result = script.executeAndReturnError_(err);
console.log(result, err);
const err = new Ref();
const result = script.executeAndReturnError_(err);
console.log('result:', result); // null
console.log('error:', err.deref()); // [objc { NSAppleScriptErrorBriefMessage = "Expected end of line, etc. but found identifier."; NSAppleScriptErrorMessage = "Expected end of line, etc. but found identifier."; NSAppleScriptErrorNumber = "-2741"; NSAppleScriptErrorRange = "NSRange: {23, 4}"; }]
}
41 changes: 30 additions & 11 deletions examples/blocks.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
const objc = require('../');
#!/usr/bin/env node

const {wrap} = objc;
const {id, NSInteger} = objc.types;
const objc = require('../src/index');

const array = objc.ns(['i', 'am', 'the', 'doctor']);

const block = new objc.Block((arg0, arg1) => {
arg0 = wrap(arg0);
arg1 = wrap(arg1);
// an NSComparator block takes 3 ObjC objects ('@') as arguments: the block itself plus 2 values to compare), and returns an NSComparisonResult (an Int64-based enum, 'q')

return arg0.length() > arg1.length() ? -1 : 1;
}, NSInteger, [id, id]);
// define the NSComparator type, using its ObjC type encoding string (naming the type is optional, but recommended)
// objc.defineBlock('q@@@', 'NSComparator'); // this is already defined in objc

// once the type is defined, it can be referred to by its name...
// console.log(objc.NSComparator); // [class NSComparator extends Block]


// ...and new Block objects of that type created for use as arguments to ObjC methods:

const array = objc.ns(['i','can','hold','up','TWO','books']);


const longestToShortest = new objc.NSComparator(
(thing1, thing2) => {
return thing1.length() > thing2.length() ? -1 : +1;
});

console.log(array.sortedArrayUsingComparator_(longestToShortest)); // [objc ( books, hold, TWO, can, up, i )]



const shortestToLongest = new objc.NSComparator(
(thing1, thing2) => {
return thing1.length() < thing2.length() ? -1 : +1;
});

console.log(array.sortedArrayUsingComparator_(shortestToLongest)); // [objc ( i, up, TWO, can, hold, books )]

const sorted = array.sortedArrayUsingComparator_(block);
console.log(sorted);
57 changes: 37 additions & 20 deletions examples/classes.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
#!/usr/bin/env node

const objc = require('../src/index');
const {runtime, NSObject} = objc;

const LKGreeter_instanceMethods = {
'greet:': (self, cmd, name) => {
name = objc.wrap(name);
return objc.ns(`hello, ${name}!`);
},

_encodings: {
'greet:': ['@', ['@', ':', '@']]
}
};

const LKGreeter_classMethods = {
foo: (self, cmd) => {
console.log('foo');
// the newly created class will be globally available as `objc.LKGreeter`
objc.defineClass('LKGreeter', 'NSObject', {
// ObjC type encodings for the following methods
$foo: 'v@:',
greet_: '@@:@',
description: '@@:',
}, {
// class methods

$foo: (self) => {
console.log(`${self}.foo() class method was called`);
},

// instance methods

greet_: (self, name) => {
return `greeter instance says: "hello, ${name}!"`;
},

description: (self) => {
return `<objc.LKGreeter>`; // ObjC descriptions are typically written as '<...>'
},

});


console.log('LKGreeter class:', objc.LKGreeter); // LKGreeter class: [objc: LKGreeter]


objc.LKGreeter.foo(); // "[ObjCClass: LKGreeter].foo() class method was called"

const greeter = objc.LKGreeter.new(); // instantiate by calling ObjC class method `new`

_encodings: {
'foo': ['v', ['@', ':']]
}
};
console.log('LKGreeter instance:', greeter); // LKGreeter instance: [objc: <LKGreeter: 0x600000b8a220>]

console.log(objc.js(greeter.greet_('lukas'))); // greeter instance says: "hello, lukas!"

const LKGreeter = objc.createClass('LKGreeter', 'NSObject', LKGreeter_instanceMethods, LKGreeter_classMethods);

LKGreeter.foo();
console.log(objc.js(greeter.description())); // '<objc.LKGreeter>'

console.log(LKGreeter.new().greet('lukas'));
console.log(`LKGreeter instance: ${greeter}`); // LKGreeter instance: [<objc.LKGreeter>]
14 changes: 8 additions & 6 deletions examples/clipboard.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env node

'use strict';

const objc = require('../src/index');
Expand All @@ -15,21 +17,21 @@ const {
let pasteboard = NSPasteboard.generalPasteboard();
pasteboard.declareTypes_owner_([NSPasteboardTypeString], null);

const get = () => {
const getClipboard = () => {
return pasteboard.stringForType_(NSPasteboardTypeString);
};

const set = text => {
const setClipboard = text => {
text = NSString.stringWithUTF8String_(text);
console.log(`new text: ${text}`);
let oldValue = get();
let oldValue = getClipboard();
pasteboard.setString_forType_(text, NSPasteboardTypeString);
return oldValue;
};


set('Hello World!');
setClipboard('Hello World!');

let contents = get(); // This is now still an `NSString`
let contents = getClipboard(); // This is now still an `NSString`

console.log(String(contents)); // The `String(...)` call converts the `NSString to a native JavaScript string object`
console.log(String(contents)); // The `String(...)` call converts the `NSString` to a native JavaScript string object
17 changes: 9 additions & 8 deletions examples/date.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env node

'use strict';

const objc = require('../src/');
const util = require('util');
const objc = require('../src/index');

const {
NSDate,
Expand All @@ -11,15 +12,15 @@ const {

let now = NSDate.date();
console.log('LOG DATE')
console.log('now', now);
console.log('now:', now); // e.g. now: [objc: 2022-02-04 12:15:44 +0000]

// Convert the NSDate object to a JavaScript date
let asJSDate = objc.js(now);
console.log('asJSDate', asJSDate);
let jsdate = objc.js(now);
console.log('jsdate:', jsdate); // jsdate: 2022-02-04T12:15:44.862Z

let asNSDate = objc.ns(asJSDate);
console.log('asNSDate', asNSDate);
let nsdate = objc.ns(jsdate);
console.log('nsdate:', nsdate); // nsdate: [objc: 2022-02-04 12:15:44 +0000]


let localizedDate = NSDateFormatter.localizedStringFromDate_dateStyle_timeStyle_(now, 2, 2);
console.log('loc', String(localizedDate)); // -> "19. Apr 2017, 22:41:13"
console.log('localized:', String(localizedDate)); // localized: 4 Feb 2022 at 12:15:44
23 changes: 14 additions & 9 deletions examples/delegate.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env node

const objc = require('../src/index');

const {
Expand All @@ -8,30 +10,33 @@ const {



const FileManagerDelegate = objc.createClass('FileManagerDelegate', 'NSObject', {
'fileManager:shouldMoveItemAtPath:toPath:': (self, cmd, fileManager, srcPath, dstPath) => {
console.log('-[NSFileManagerDelegate fileManager:shouldMoveItemAtPath:toPath:]');
// the newly created ObjC class is available as `objc.FileManagerDelegate`
objc.defineClass('FileManagerDelegate', 'NSObject', {
// type encodings
fileManager_shouldMoveItemAtPath_toPath_: 'c40@0:8@16@24@32',
}, {
// methods

fileManager_shouldMoveItemAtPath_toPath_: (self, cmd, fileManager, srcPath, dstPath) => {
console.log('calling: -[NSFileManagerDelegate fileManager:shouldMoveItemAtPath:toPath:]');
return 1;
},

_encodings: {
'fileManager:shouldMoveItemAtPath:toPath:': ['c40', ['@0', ':8', '@16', '@24', '@32']]
}

});




const fm = NSFileManager.new();
const delegate = FileManagerDelegate.new();
const delegate = objc.FileManagerDelegate.new();
fm.setDelegate_(delegate);


const pathA = 'x.txt';
const pathB = 'y.txt';

// create file

// create file
const data = objc.ns('hello world').dataUsingEncoding_(4);
fm.createFileAtPath_contents_attributes_(pathA, data, null);

Expand Down
Loading