# ObjectiveC.jl - Bridge package for using Objective-C in Julia

**URL:** <https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862>\
**Category:** Package Announcements\
**Tags:** package, announcement\
**Created:** [March 10, 2023, 12:04pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862 "2023-03-10T12:04:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [March 10, 2023, 12:04pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/1 "2023-03-10T12:04:09Z")

</div>

I just released [ObjectiveC.jl](https://github.com/JuliaInterop/ObjectiveC.jl) 0.1, a package for working with Objective-C in Julia. The package was created by @MikeInnes back in 2014, but wasn’t registered, or functional anymore on recent versions of Julia. That has been fixed, and you can use ObjectiveC.jl to interface with Objective-C frameworks using Julia 1.6 - 1.10, although for now only macOS is supported.

## Demo

The core feature of the package is the ability to call Objective-C methods from Julia, and to build a Julia type hierarchy that matches Objective-C. For example, you can create an Objective-C NSString object, and then call methods on it:

```julia
julia> using ObjectiveC

# create a wrapper class that will hold an object pointer
julia> @objcwrapper NSString

# call a NSString class method to create an NSString object
julia> str = NSString(@objc [NSString stringWithUTF8String:"test"::Ptr{Cchar}]::id{NSString})
NSStringInstance (object of type NSTaggedPointerString)

# call an instance method to get back the contents of our NSString
julia> unsafe_string(@objc [str::id{NSString} UTF8String]::Ptr{Cchar})
"test"

# or, easier, you can have ObjectiveC.jl generate property methods
julia> @objcproperties NSString begin
           @autoproperty UTF8String::Ptr{Cchar}
       end
julia> unsafe_string(str.UTF8String)
"test"

```

For more examples, see the README. ObjectiveC.jl also provides a Foundation submodule that already contains definitions for NSString and a few other essential types:

```julia
julia> NSArray([str,str])
(
    test,
    test
)

julia> length(ans)
2

# etc

```

People familiar with Objective-C might note that the `@objc` call syntax almost looks like native Objective-C, with the exception of type information (e.g. `id{NSString}`). This is for performance reasons, as it allows us to generate fully static code that performs reasonably well:

```julia
julia> @benchmark @objc [$str::id{NSString} UTF8String]::Ptr{Cchar}
BenchmarkTools.Trial: 10000 samples with 985 evaluations.
 Range (min … max): 57.360 ns … 1.825 μs ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 62.903 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 65.431 ns ± 34.296 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

      ▂▄▆▅▇▇▇▆▇█▂
  ▂▃▄▅████████████▅▅▄▄▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂ ▄
  57.4 ns Histogram: frequency by time 88.8 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

```

There’s a couple of more advanced features, like `@objcblock` to generate callable blocks for Julia functions, but those are also demonstrated in the README.

## Current status

As the package has recently been revamped, APIs may still change, so it’s only at v0.1 right now. However, Metal.jl uses it for all interactions with the Metal APIs, so the functionality seems to be working pretty well.

In the process of revamping the package, some functionality also got lost, like the ability to create Objective-C classes from Julia. I personally don’t have a need for that, so if you’re interested, PRs to reinstate that functionality are most welcome 🙂

---

<div class="post-metadata">

**Author:** ![MikeInnes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikeinnes/32/3656_2.png) [@MikeInnes](https://discourse.julialang.org/u/MikeInnes)\
**Post date:** [March 13, 2023, 4:02pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/2 "2023-03-13T16:02:10Z")

</div>

This is great to see, excellent work Tim! Metal.jl is very exciting too.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [March 13, 2023, 6:30pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/3 "2023-03-13T18:30:02Z")

</div>

Would this help to support iOS (eventually)? I’m not sure if Objective-C is still very relevant there, I even though Swift had also taken over for macOS…

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [March 14, 2023, 8:57am UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/4 "2023-03-14T08:57:12Z")

</div>

This wouldn’t help to make Julia itself iOS compatible (insofar it isn’t), but it would make it possible to call iOS APIs, as AFAIU those are still Objective-C compatible APIs that you can just call from Swift. Native Swift APIs cannot be used with Objective-C.jl, but I’m not sure to what extent those are used in iOS.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 16, 2023, 4:13pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/5 "2023-03-16T16:13:16Z")

</div>

Would this make it possible to interact somehow with objects generated via applescript? I know that one can include objective c APIs in applescripts, but the syntax is so annoying that I often wished I could manipulate objects via Julia 🙂

This is just a far out question, I’m only interested if it could be technically possible with a bridge like this to access the data structures of an applescript. Not if it’s possible now (which I’m sure it’s not)

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [March 16, 2023, 6:04pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/6 "2023-03-16T18:04:42Z")

</div>

I’m not familiar with AppleScript or the ObjC APIs to interact with them, sorry. I found NSAppleScript, but that doesn’t seem to expose a way to interact with AppleScript objects.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 19, 2023, 12:57pm UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/7 "2023-03-19T12:57:02Z")

</div>

I have looked around a little more and there seems to be a way forward. There’s something called the “Scripting Bridge”, which is an Objective C framework which enables one to call some application’s apple script API in Objective C. The headers needed for that can be generated using the binaries `sdef` and `sdp`. `sdef` extracts an XML description of the scripting API defined for a given application. `sdp` creates an Objective C header file from that, which one would normally include in an Objective C application, which also references the ScriptingBridge framework. So I would have to define both elements from `ScriptingBridge` framework and from the `sdp` output of whatever application I was interested in on the Julia side somehow.

Now, I haven’t yet tried anything, only read information here and there on the internet. Is there an automated way, for example using the `Clang.jl` generator to turn the header files I’ll get from `sdp` into Julia code, or is that a manual transformation process? How did you do it for `Foundation` @maleadt?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 20, 2023, 7:25am UTC](https://discourse.julialang.org/t/objectivec-jl-bridge-package-for-using-objective-c-in-julia/95862/8 "2023-03-20T07:25:16Z")

</div>

Ok I’ve managed the start, which is to start an application via the scripting bridge. I think from here on out I should make it work 🙂

```julia
using ObjectiveC
using ObjectiveC.Foundation

load_framework("ScriptingBridge")

@objcwrapper SBObject <: NSObject

@objcwrapper SBApplication <: SBObject

# @objcproperties SBApplication begin
# @autoproperty classNamesForCodes::id{NSDictionary}
# end

function SBApplication(bundle_identifier::String)
    x = @objc [SBApplication applicationWithBundleIdentifier:bundle_identifier::id{NSString}
                    ]::id{SBApplication}
    return SBApplication(x)
end

app = SBApplication("com.captureone.captureone16")

activate(app::SBApplication) = @objc [app::id{SBApplication} activate]::Cvoid

activate(app) # now Capture One starts

```
