mhdhejazi / Dynamic

Call hidden/private API in style! The Swift way.

Home Page:https://medium.com/@mhdhejazi/calling-ios-and-macos-hidden-api-in-style-1a924f244ad1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Catalyst NSStatusBar with NSStatusBar not working

tommycarpi opened this issue · comments

Hi guys, I've tried to have the NSStatusBar working with a NSStatusBar on a project developed with React Native and Catalyst, but the icon doesn't appear.

Here is the code, it compiles and the app runs successfully, but no icon appear on the top right corner of the screen

import UIKit
import Dynamic

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  var bridge: RCTBridge!
  
  let statusItem = Dynamic.NSStatusBar.system.statusItem(withLength:Dynamic.NSStatusItem.squareLength)
  
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let jsCodeLocation: URL
    
    jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index", fallbackResource:nil)
    let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "myModule", initialProperties: nil, launchOptions: launchOptions)
    let rootViewController = UIViewController()
    rootViewController.view = rootView

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = rootViewController
    self.window?.makeKeyAndVisible()
        
    statusItem.button.image = Dynamic.NSImage(named:Dynamic.NSImage.Name("iconbar"))

    return true
  }
}

Do you have any idea what I'm missing?

You are using Swift methods. For Dynamic, use Objective-C methods

let statusItem =
Dynamic.NSStatusBar.systemStatusBar.statusItemWithLength(
Dynamic.NSSquareStatusItemLength)

etc.

@polymerchm thanks for the fast answer.
I've tried what you suggested but couldn't have it working too.

I only changed the 2 lines of code affected by Dynamic and simplified the second one.

import UIKit
import Dynamic

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  var bridge: RCTBridge!

 let statusItem = Dynamic.NSStatusBar.systemStatusBar.statusItemWithLength(Dynamic.NSStatusItem.NSSquareStatusItemLength)

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    /* same as before */

    // To simplify I tried
    statusItem.button.title = "Text"
    // option 2: statusItem.button.image = Dynamic.NSImage.imageNamed("iconbar")

    return true
  }

But again nothing shows. Did I forget something?

This actually works:

let statusItem = Dynamic.NSStatusBar.systemStatusBar.statusItemWithLength(-1.0)

Thanks

Thank you @polymerchm for the help! Highly appreciated!

For the last bit, NSSquareStatusItemLength is only part of NSStatusItem in Swift (as NSStatusItem.squareLength), but it's just a global constant in ObjC. That's why you needed to use the actual constant value (-1) as we can't access ObjC constants by name.

P.S. I usually prefer defining those constants in Swift (instead of using the actual values). You know, it makes the code a bit cleaner and easier to understand.

let NSSquareStatusItemLength = -1.0
let statusItem = Dynamic.NSStatusBar.systemStatusBar.statusItemWithLength(NSSquareStatusItemLength)

I found it in a post on StackOverflow, so I guess it should be documented somewhere, but I couldn't find it in the official documentation.

I usually check how it's defined in the SDK headers. In Xcode, File -> Open Quickly... and type the constant name.

This is how NSSquareStatusItemLength is defined:

image

Hi, @tommycarpi, even though it's not completely related to this thread, I'd just like to ask if you're still able to build your React Native app with Catalyst. I'm trying to do exactly the same thing, i.e. use NSStatusBar with a RN app using Catalyst, but the build failed due to the Typedef redefinition with different types ('uint8_t' (aka 'unsigned char') vs 'enum clockid_t') error in RCT-Folly as seen at facebook/flipper#834 None of the solutions posted there seems to work for me. Would really appreciate it if you could help on how you managed to build the app. Thanks!

I was able to make the build pass only after commenting out the line use_flipper!() from the Podfile and removing Flipper from the app, in addition to modifying the Time.h file in RCT-Folly directly, which seems not ideal.

Hello @x-ji, I had to disable flipper too, but did not edit Time.h.
Here is an extract of my podfile, I commented it all:

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  # add_flipper_pods!
  # post_install do |installer|
  # flipper_post_install(installer)
  # end

I'm on RN 0.64.2 in case it helps.

Hi @tommycarpi thanks for the info! Would it be fine for you to take a look at your Podfile.lock and see whether you have RCT-Folly listed there, and if yes, what version it has? I wonder whether the issue could have been caused by a particular version of this pod, as people seemingly have discussed in the aforementioned issue. And I wonder which iOS version your project specifies as the build target (I'm not sure if there is also a MacOS version set as the build target for Catalyst apps). Thanks again!

By the way, the Flipper-related section in my Podfile looks like this:

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable the next line.
  use_flipper!()

  post_install do |installer|
    react_native_post_install(installer)
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end

Guess it has changed in the meanwhile along with the React Native version (I generated my project with RN v0.66.3)

Hi @x-ji ,
iOS 13+
macOS 11+

Here is my Podfile.lock for RCT-Folly

- RCT-Folly (2020.01.13.00):
    - boost-for-react-native
    - DoubleConversion
    - glog
    - RCT-Folly/Default (= 2020.01.13.00)
  - RCT-Folly/Default (2020.01.13.00):
    - boost-for-react-native
    - DoubleConversion
    - glog

let me know if you need anything more specific.

Hi @tommycarpi thanks for the prompt reply. I see that my RCT-Folly has the version 2021.06.28.00-v2 so it seems to be much newer. I tried to specify your version in my Podfile, but the following error occurs:

[!] There are multiple dependencies with different sources for
`RCT-Folly` in `Podfile`:

- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCT-Folly (= 2020.01.13.00)

I guess the version is somewhat locked by React Native itself. Could I know what version of React Native you are using for the project? Guess I'll try to build my project with that version of RN as well. Thanks!

Hello @x-ji, I'm running RN 0.64.2!

Cheers