I am creating an Xcode project using xcode generator in Cmake. The project has a library which contains cpp files and swift files. I m trying to test swift-cpp interoperability that is introduced in xcode15 to perform direct cpp calls from swift and vice-versa. For this to work, we need to set a xcode build setting 'C++ and Objective-C Interoperability' which I m doing via cmake, Below is my cmake file:
cmake_minimum_required(VERSION 3.18)
project(CxxInterop LANGUAGES CXX Swift)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_Swift_LANGUAGE_VERSION 5.0)
add_executable(CxxInterop ./Sources/CxxInterop/main.swift
./Sources/CxxInterop/Student.cpp
)
#include the directory with modulemap file and Student.hpp
target_include_directories(CxxInterop PUBLIC
${CMAKE_SOURCE_DIR}/Sources/CxxInterop)
#setting the xcode C++ and Objective-C Interoperability setting
target_compile_options(CxxInterop PRIVATE
"-cxx-interoperability-mode=default")
when building the generated xcode project I get the error unknown argument: '-cxx-interoperability-mode=default'.
However the weird thing is when I separate out the cpp code in a different library and swift files in a different one, then this works and I m able to invoke the cpp methods in my swift file after importing the clang module from the module map file.
Is there any reason to why having cpp and swift files in same library producing this error? I m following this link to setup the project via cmake.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I m trying to create an xcode project with cpp-swift interoperability(introduced in xcode15) using cmake xcode generator. I m able to invoke cpp code in swift and vice-versa but when opening the project in xcode, the build setting for 'C++ and Objective-C Interoperability' is still set to 'C/Objective C' like in image below. I want to set it to 'C++/Objective-C++'.
I m using the below cmake for this:
.
.
add_library(cxx-support ./Sources/CxxSupport/Student1.cpp
./Sources/CxxSupport/Teacher.swift
)
#include the directory to access modulemap content
target_include_directories(cxx-support PUBLIC
${CMAKE_SOURCE_DIR}/Sources/CxxSupport)
target_compile_options(cxx-support PUBLIC
"$<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default>"
)
.
.
I Have also tried the below in cmake, but it didn't work.
#set(SWIFT_OBJC_INTEROP_MODE "objcxx" CACHE STRING "")
#target_compile_options(cxx-support PUBLIC
#"SWIFT_OBJC_INTEROP_MODE=objcxx")
Any help on how this can be achieved?
I am having a usecase where I wanted to detect the system language change event under OS X. I went throught the available options in NSNotification.Name , but did not find anything helpful. I found a similar link but it seems to be no longer applicable.
Any help on how this can be achieved?
I have a project where I m making direct swift calls from cpp as introduced in swift5.9. Below is my swift class whose method is being invoked on cpp.
import Foundation
public class MySwiftClass
{
public static func testInterop () -> Void {
NSLog("----------- hey --------")
}
}
I m able to successfully invoke 'testInterop()' in cpp with the above class, however if I add conformance to NSObject in the 'MySwiftClass' class, then the swift call fails with the error "No member named 'MySwiftClass' in namespace 'Module2'", where Module2 is my swift target.
I m not able to identify why is this happening. Any help?
I was going through this apple documention and it states, "By default, the generated header contains interfaces for Swift declarations marked with the public or open modifier", however, In my Xcode project, the public methods are not visible in the objective C code, and only the methods that are marked with @objc are visible. Is there some problem in my code or Is this a bug?
I have created a universal link which I m using for two different applications in macOS. Below is the apple-app-site-association file for the same:
{
"applinks":{
"apps":[],
"details":[
{
"appID":"E5R4JF6D5K.com.demo.App1",
"paths":[
"/app1/*"
]
},
{
"appID":"E5R4JF6D5K.world.demo.App2",
"paths":[
"/app2/*"
]
}
]
}
}
After creating this file in my server and providing the same Url in my associated domain capability for both my application, when I try to launch my applications using the link then only the first application is getting launched everytime. The second application is never launched.
for Url with http://custom.com/app1/... it redirects to first app.
for Url with http://custom.com/app2/... it redirects to browser.
I tried uninstalling the first app, but then it always directs in browser.
I tried a separate url for both apps, and it works fine.
I m not able to figure out the problem. The apple documentation says that it is possible to have two application linked to a common domain. Any help?
I have observed that some of the applications like xcode show a list of recently opened documents in their dock menu like in the image below. I wanted to show similar recently opened docs for my application but I not able to find any resource on how to achieve this. Can someone help on how to do this?
The notification parameter in DidFinishLaunching contains a key LaunchIsDefaultLaunchKey which according to Apple documentation is:
The value for this key is an NSNumber containing a Boolean value. The value is false if the app was launched to open or print a file, to perform a Service action, if the app had saved state that will be restored, or if the app launch was in some other sense not a default launch. Otherwise its value will be true.
I m not able to understand the exact usecase for this parameter, like where can we make use of this parameter.
Can I use this key to identify If my application was launched using a universal link?
I have a mac application that is configured to have a universal link. Clicking the universal link launches my application. The documentation says that the link is received in the application(_:continue:restorationHandler:) delegate method which is invoked very late in the application lifecycle after applicationDidBecomeActive.
I have the initialisation code of my app in applicationWillFinishLaunching method. Is there any way the Universal link can be received early, so that I can show the appropriate application window based on the universal link parameters? Is there any other delegate that receives the universal link?
I have a project that has Cpp code and swift code and I m making some calls from swift to cpp. For this I m using the Cpp-swift interop mechanism introduced in swift 5.9 for making direct calls between swift and cpp.
I m using module.modulemap file to expose the cpp code to swift. I am facnig an error when I try to access a cpp header that are using the cpp compiler flags in some static assert statements. These methods are working fine in cpp however, when I try to access these methods from swift using the modulemap file, the compiler flags are not being identified by swift, and produces the below error
error: use of undeclared identifier 'TW_KERNEL_WINDOWS'.
This is my module.modulemap file:
module CoreModule {
header "ProcessStates.hpp" //cpp header that contains compiler flags
export *
}
below is the cpp header code that I m trying to access in swift:
#pragma once
// if the given condition is false – treat as an error
#define STATIC_CHECKFALSE(condition, message) static_assert (condition, message)
STATIC_CHECKFALSE ((TW_KERNEL_WINDOWS == 0) || (TW_KERNEL_WINDOWS == 1), "TW_KERNEL_WINDOWS can only be 0 or 1");
Can someone help, why is this happening and how to resolve this?
The Apple documentation for SessionGetInfo for swift mentions that this API takes third argument of type UnsafeMutablePointer<SessionAttributeBits>? but I m getting the below error when I pass an argument of this type.
Cannot convert value of type 'UnsafeMutablePointer<SessionAttributeBits>' to expected argument type 'UnsafeMutablePointer<UInt32>'
Why is it expecting a different type. The documentation states otherwise. How to resolve this? Is this a Bug?
public static func GetSessionInfo () -> Void
{
var sessionID = SecuritySessionId()
var sessionAttrs = SessionAttributeBits()
let status = SessionGetInfo(callerSecuritySession,
&sessionID,
&sessionAttrs) //error:Cannot convert value of type 'UnsafeMutablePointer<SessionAttributeBits>' to expected argument type 'UnsafeMutablePointer<UInt32>'
if status != errSessionSuccess {
print("Could not get session info. Error \(status)")
}
}
I am building a macOS project where I m creating a thread using pthread in cpp. I am setting the QOS class using the pthread_attr_set_qos_class_np and later checking the value of the QOS class using the pthread_attr_get_qos_class_np. These calls are successful but the QOS class is not being set. Below is the cpp function that I m invoking from my swift code.
bool CppThread::CreateThread ()
{
pthread_t threadId;
pthread_attr_t attr;
qos_class_t qos_class;
int relative_priority;
int rc = pthread_attr_init(&attr);
if (rc) {
printf ("pthread_attr_init failed");
}
if (pthread_attr_set_qos_class_np (&attr, QOS_CLASS_BACKGROUND, 5)) {
printf ("pthread_attr_set_qos_class_np failed\n");
}
int retval = pthread_create(&threadId, &attr, threadFunction, NULL);
if (retval) {
std::cerr << "Error creating thread" << std::endl;
return false;
}
if (pthread_attr_get_qos_class_np (&attr, &qos_class, &relative_priority)) {
printf ("pthread_attr_get_qos_class_np failed\n");
}
printf ("QoS class: %d, Relative priority: %d\n", qos_class, relative_priority);
pthread_join(threadId, NULL); // Wait for thread to finish
std::cout << "Thread finished" << std::endl;
return true;
}
OUTPUT:
QoS class: 0, Relative priority: 0
Thread finished
I have tried setting multiple QOS values but the output always shows the QOS class value as 0. Why is it not getting set?
We can see Xcode supports to generate code coverage for unit test bundles. Does it has any support for generating code coverage report for a regular application/bundle. What we want to try is that can I check for my certain application how much code coverage is being done.
If Xcode does not have any support for this, what apple suggest us to do for this ?
I have implemented the new cpp-swift interop mechanism using modulemap file. I have a use case to pass a swift string to the cpp function. I observed that the below code works and I am able to pass a swift String type directly to a cpp function which received it as const char *. This works only if its received as const char * in cpp(and not char *). However, this is not an interop documented behaviour for interoperating String types and wanted to know whether this is safe to use. If not, can someone suggest an alternative approach to pass a swift string to Cpp.
// Swift code
public static func StringToCharPointer () -> Void
{
// calling cpp function and passing a swift String type as argument, which is received as const char *
Student.Convert (sUItextdata) //sUItextdata is of type 'String'
}
//static Cpp function
void Student::Convert (const char * pStr)
{
std::string s(pStr);
std::cout << "char * converted from swift String : " << s << std::endl;
}
Note : I am aware that there is a way to pass it to cpp and receive it as std:string, but I do not wish to use that.
I have a macOS app project implementing the direct Cpp-swift interop mechanism. The project some cpp classes and few Swift class. I wanted to pass a cpp object to a swift function as parameter, so I can use it in my swift code. But the documentation is not very clear on how to do this. Can some please share a code snippet explaining how can I achieve this?
I have tried the below code, but it is giving linker error.
Swift code:
import StClass_modulemap
public class SwiftClass {
..
public static func getCppObj (pObj: inout StClass) -> Void
{
...
}
}
Cpp code:
#include "Student.hpp"
#include "StClass.hpp"
#include <InteropLib-Swift.h>
using namespace InteropLib;
void Student::Introduce() {
//creating cpp to be passed to swift
// StClass StObj(50);
// Teacher::getCppObj(StObj);
std::cout<< "header included in hpp " <<std::endl;
}
calling Student::Introduce is giving a linker error for StClass