Where are the system-wide Objective-C modules defined in macOS? - objective-c

I was interested to inspect globally available modulemaps of Objective-C language under macOS and was wondering if it's possible to add one myself. Is there a way to know where a particular module (e.g. Foundation) is located?
#import Foundation; // Where this comes from?
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"Hello, world!");
}
return 0;
}

Almost all modules are embedded to the corresponding frameworks in the system. For the latest version of macOS at the time of writing (macOS Monterey 12.6 (21G115)) the frameworks can be found under this directory:
/Library/Developer/CommandLineTools/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks
E.g. Foundation modulemap is located at the path /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Modules/module.modulemap and looks like this:
framework module Foundation [extern_c] [system] {
umbrella header "Foundation.h"
export *
module * {
export *
}
explicit module NSDebug {
header "NSDebug.h"
export *
}
// Use NSItemProvider.h
exclude header "NSItemProviderReadingWriting.h"
}
The dependencies which were not part of any framework (e.g. libobjc), however, also have modulemaps defined and available under different directory:
/Library/Developer/CommandLineTools/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include

Related

How to import node-java and use it correctly?

Now I am trying to call our APIs in our own Jar.
In VS Code extension example project, I tried to npm install java to install it in modules dir.
In my extension.ts it looks like below:
import * as vscode from "vscode";
import * as java from "java";
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log(
'Congratulations, your extension "test-ext" is now active!'
);
context.subscriptions.push(
vscode.commands.registerCommand("test-ext.callLocalJar", async () => {
console.log('test caller start.');
java.classpath.push("testapis.jar");
console.log('test caller start.');
}
)
);
}
// this method is called when your extension is deactivated
export function deactivate() {}
But now I got a failure in the very beginning when activating it...
error:
Activating extension 'boyka.test-ext' failed:
Cannot find module 'c:\Users\boyka\Workspaces\test-ext\build\Release\nodejavabridge_bindings.node'.
My package.json is like
"dependencies": {
"java": "^0.12.2"
}
I am not sure of the root cause, tried to research and add Java home to PATH but luck.
Anyone has this node-java usage experience that could help? Will appreciate that!
https://github.com/joeferner/node-java
Thanks
b.

Can my react-native application use xcode swift libraries? and How?

I'm currently quite new to react-native and xcode. So basically, I made a program on xcode using swift and importing a library, but now I need to use this code in my react native application. I don't know if it is possible and how to go about doing it.
Unfortunately it really depends on how you want to use your swift code, because React Native provides different methods for different circumstances, but I will try to give you an example of an basic "Event Bridge".
First of all every React Native Application automatically generates an iOS and Android project. Navigate to the iOS folder and open the Xcode workspace. Afterwards just drag your swift source file into the project (like in every other native application).
As React Native uses an Objective-C Bridge we cannot directly use the Swift code so we need to bridge Swift -> Objc -> Javascript.
Lets first dive into your Swift class:
You need to be able to communicate with objc and export the methods to the react native runtime, here is an example of the swift file
// CustomObject.swift
import Foundation
#objc(CustomObject)
class CustomObject: NSObject {
#objc static var isSelected = false // our state
#objc
func selectObject() {
CustomObject.isSelected.toggle()
print(CustomObject.isSelected ? "selected" : "not selected")
}
#objc
func getState(_ callback: RCTResponseSenderBlock) {
callback([NSNull(), CustomObject.isSelected]) // this will return into a
// javascript callback to retrieve the current state
}
// this is needed to make sure that this will run on the main thread
#objc
static func requiresMainQueueSetup() -> Bool {
return true
}
}
Now we need to call these methods from Objc and expose it to JavaScript.
// CustomObject.m
#import "React/RCTBridgeModule.h"
#interface RCT_EXTERN_MODULE(CustomObject, NSObject)
RCT_EXTERN_METHOD(selectObject)
RCT_EXTERN_METHOD(getState: (RCTResponseSenderBlock)callback)
#end
This is all you have to do.
Now you can navigate back to your JavaScript Application and import NativeModules.
import React, {useState} from 'react';
import {View, NativeModules, Button, Text} from 'react-native';
const TestComponent = () => {
const [selected, setSelected] = useState(false);
const triggerSelection = () => {
NativeModules.CustomObject.selectObject()
NativeModules.CustomObject.getState( (err, isSelected) => { // Edited
setSelected(isSelected);
});
}
return (
<View>
<Button title="Button" onPress={triggerSelection} />
<Text>{selected}</Text>
</View>
);
}
To pass more complex structures from native to javascript, just take a look at this documentation, it is actually not that bad.
React Native - Native Modules

React Native doesn't pick up native iOS module

I'm trying to set up a native iOS module for React Native with Swift.
Here's my Swift file:
// SwiftManager.swift
import Foundation
#objc(SwitchManager)
class SwitchManager: NSObject {
#objc func addEvent(_ name: String) -> Void {
NSLog("It works!")
}
}
And here is my implementation file:
// SwiftManager.m
#import <React/RCTBridgeModule.h>
#interface RCT_EXTERN_MODULE(SwitchManager, NSObject)
RCT_EXTERN_METHOD(addEvent:(NSString *)name)
#end
Then, I try to use it in my React Native code like so:
// index.ios.js
import React, { Component } from 'react';
import { NativeModules } from 'react-native';
const SwitchManager = NativeModules.SwitchManager;
SwitchManager.addEvent('Birthday Party');
// ...
But SwitchManager ends up being undefined. In another project I put together, I have successfully created a native module and I can't recall doing anything different. Do you have any ideas on why RN wouldn't pick up this native module?
I reverted all changes to a clean version of my repo and created the files from scratch again in Xcode. React Native is able to pick up the native module now. I think the problem could have been related to renaming things around and Xcode not keeping references properly, although I can't say for sure because I had several changes in my working tree.

react-native : Native modules with same name for both android and iOS

I'm trying to build a react-native wrapper around our existing native android and ios SDK. I want to know if I can use the same class name and class methods for both the Android and iOS bridge modules? And how do I map the right module to be called for the right device?
For instance, for iOS :
// CalendarManager.h
#import "RCTBridgeModule.h"
#interface CalendarManager : NSObject <RCTBridgeModule>
#end
// CalendarManager.m
#implementation CalendarManager
RCT_EXPORT_MODULE();
#end
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
//Some work
}
For Android :
public class CalendarManager extends ReactContextBaseJavaModule {
public CalendarManager(ReactApplicationContext reactContext) {
super(reactContext);
}
#Override
public String getName() {
return "CalendarManager";
}
#ReactMethod
public void addEvent(String name, String location) {
//Some work
}
}
And in my js file, if I have something like this :
import { NativeModules } from 'react-native';
NativeModules.CalendarManager.addEvent("Name", "Location")
Which one will be executed? Is there a way where I could route it to the right function based on the device?
Thanks.
You don't have to do that routing yourself. That is build into React-Native. It knows which type of device you're on.
React Native packages a different version of the code that you have in your project according to the target platform that you set when you create the application APK or IPA. That is, when you do react native run-android for instance, it will compile the native Java code present in the Android project located in the android folder and pack the APK with that. Then JavaScript will have access to the native Java code. Same thing for iOS with the Objective-C/Swift code. So yes, you can (actually, I'd say you must) use the same name for the native modules.

Navigating through Typescript references in Webstorm using ES6 module syntax

We are using Typescript with Intellij Webstorm IDE.
The situation is we use ES6 import syntax and tsc compiler 1.5.3 (set as custom compiler in Webstorm also with flag --module commonjs)
The problem is it is imposible to click through (navigate to) method from module (file)
// app.ts
import * as myModule from 'myModule';
myModule.myFunction();
// myModule.ts
export function myFunction() {
// implementation
}
When I click on .myFunction() in app.ts I expect to navigate to myModule.ts file but this doesn't happen?
EDIT:
The way we exported functionality was bit different as in first example:
export: {
myFunction1,
myFunction2,
// ...
};
When I click on .myFunction() in app.ts I expect to navigate to myModule.ts file but this doesn't happen
This is working fine in the current WebStorm release.
I found out the problem, my example in question was simplified too much. In real code we are using:
export: {
myFunction1,
myFunction2
// ...
};
and this really doesn't work.
I have to change it to:
export function myFunction1() { /* impl */ }
export function myFunction2() { /* impl */ }
then it works.