mhdhejazi / Dynamic

Call hidden/private API in style! The Swift way.
https://medium.com/@mhdhejazi/calling-ios-and-macos-hidden-api-in-style-1a924f244ad1
Apache License 2.0
695 stars 36 forks source link

Making a C# binding from Dynamic Swift framework #27

Closed noobsoftware closed 1 year ago

noobsoftware commented 2 years ago

I'm trying to use Dynamic in Visual Studio with C# which involves using a tool called sharpie which consumes a .framework's header files, but in the Dynamic source code i see no header files. I am not used to using swift so i don't know if this is conventional, but i was hoping you could assist by helping my construct the header file or if you could provide the headers or even better a constructed .framework file from the source code?

drasticactions commented 1 year ago

There are no header files because this is Swift, and Objective Sharpie, as its name suggests, is for Objective C. You can't bind this framework because it's for Swift. If you needed to get a private API and you're using Objective C, you would just use that, there's no need to use this.

Having said that, you could potentially write your own framework library in Swift, use this library to get the values you want, and write a proxy that does output Objective C headers that Objective Sharpie can use.

https://learn.microsoft.com/en-us/xamarin/ios/platform/binding-swift/walkthrough

This should get you started.

tstephansen commented 1 year ago

Just wanted to pop in and say I ran into a similar problem earlier this year when working on a Maui app. Hopefully this helps anyone else who needs to call something in Swift from Maui. That being said, I do need help making my windows transparent so the first part of this will be help for others and the second part is me asking for help myself. I needed a way to adjust the system volume programatically. I found this library but it was in swift and I needed to call it from C#. The solution to this was to add C declarations to the end of the file. I took the methods from his extension and put it into a new swift file in XCode.

For example, one of the methods is named getSystemVolume:

private func getSystemVolume() -> Float
{
    // Code in the method..
}

I then added the following to the bottom of the file for each method I needed to access.

@_cdecl("getMainVolume")
public func getMainVolume() -> Float {
    return getSystemVolume()
}

I compiled this to a dylib called libMacAudioController.dylib and copied that to /usr/local/lib/.

To call this method from the Maui app I added the following code.

[DllImport("/usr/local/lib/libMacAudioController.dylib")]
private static extern float getMainVolume();

Now I'm back on the hunt for a solution as I need to make one of the windows in my app transparent. I'm hoping this library could help with that but not sure yet. I think the examples in the readme are a great start. I just don't know how to get a reference to the window in maui and pass that to the dylib (once I make it).

// This would change from:
extension UIWindow {
    var nsWindow: NSObject? {
        var nsWindow = Dynamic.NSApplication.sharedApplication.delegate.hostWindowForUIWindow(self)
        if #available(macOS 11, *) {
            nsWindow = nsWindow.attachedWindow
        }
        return nsWindow.asObject
    }
}

// To something like this and I would pass in a reference to the window instead of using self:
function getWindowReference(THIS_WAS_SELF_BEFORE: SomeType) -> NSObject
{
    var nsWindow = Dynamic.NSApplication.sharedApplication.delegate.hostWindowForUIWindow(THIS_WAS_SELF_BEFORE)
    if #available(macOS 11, *) {
        nsWindow = nsWindow.attachedWindow
    }
    return nsWindow.asObject
}

Basically, I need a transparent window so the user can watch something behind it while training. This window fades from transparent to black based on the client's brainwaves (if they are doing at the correct frequency and microvolts the client will be able to see the video on the screen, if not the screen will be black).

If anyone has tried this before or encountered a similar issue and could point me in the right direction I'd greatly appreciate it.