CocoaPods / CocoaPods

The Cocoa Dependency Manager.
https://cocoapods.org/
Other
14.57k stars 2.63k forks source link

Objective-C Swift Generated Interface Header imports itself #10544

Open mrousavy opened 3 years ago

mrousavy commented 3 years ago

Report

What did you do?

I'm creating a library which contains Swift and Objective-C code. The library is called VisionCamera.

In the Objective-C code, I want to import the Swift code by making use of the Objective-C generated interface header:

#if __has_include("VisionCamera-Swift.h")
#import "VisionCamera-Swift.h"
#else
#error Objective-C Generated Interface Header (VisionCamera-Swift.h) was not found!
#endif

The VisionCamera-Swift.h header gets generated successfully, but seems to be incorrect because it tries to import itself:

Screenshot 2021-03-24 at 20 43 07
Full code of the generated VisionCamera-Swift.h ```objc // Generated by Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28) #ifndef VISIONCAMERA_SWIFT_H #define VISIONCAMERA_SWIFT_H #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgcc-compat" #if !defined(__has_include) # define __has_include(x) 0 #endif #if !defined(__has_attribute) # define __has_attribute(x) 0 #endif #if !defined(__has_feature) # define __has_feature(x) 0 #endif #if !defined(__has_warning) # define __has_warning(x) 0 #endif #if __has_include() # include #endif #pragma clang diagnostic ignored "-Wauto-import" #include #include #include #include #if !defined(SWIFT_TYPEDEFS) # define SWIFT_TYPEDEFS 1 # if __has_include() # include # elif !defined(__cplusplus) typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; # endif typedef float swift_float2 __attribute__((__ext_vector_type__(2))); typedef float swift_float3 __attribute__((__ext_vector_type__(3))); typedef float swift_float4 __attribute__((__ext_vector_type__(4))); typedef double swift_double2 __attribute__((__ext_vector_type__(2))); typedef double swift_double3 __attribute__((__ext_vector_type__(3))); typedef double swift_double4 __attribute__((__ext_vector_type__(4))); typedef int swift_int2 __attribute__((__ext_vector_type__(2))); typedef int swift_int3 __attribute__((__ext_vector_type__(3))); typedef int swift_int4 __attribute__((__ext_vector_type__(4))); typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #endif #if !defined(SWIFT_PASTE) # define SWIFT_PASTE_HELPER(x, y) x##y # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) #endif #if !defined(SWIFT_METATYPE) # define SWIFT_METATYPE(X) Class #endif #if !defined(SWIFT_CLASS_PROPERTY) # if __has_feature(objc_class_property) # define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ # else # define SWIFT_CLASS_PROPERTY(...) # endif #endif #if __has_attribute(objc_runtime_name) # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) #else # define SWIFT_RUNTIME_NAME(X) #endif #if __has_attribute(swift_name) # define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) #else # define SWIFT_COMPILE_NAME(X) #endif #if __has_attribute(objc_method_family) # define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) #else # define SWIFT_METHOD_FAMILY(X) #endif #if __has_attribute(noescape) # define SWIFT_NOESCAPE __attribute__((noescape)) #else # define SWIFT_NOESCAPE #endif #if __has_attribute(ns_consumed) # define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) #else # define SWIFT_RELEASES_ARGUMENT #endif #if __has_attribute(warn_unused_result) # define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else # define SWIFT_WARN_UNUSED_RESULT #endif #if __has_attribute(noreturn) # define SWIFT_NORETURN __attribute__((noreturn)) #else # define SWIFT_NORETURN #endif #if !defined(SWIFT_CLASS_EXTRA) # define SWIFT_CLASS_EXTRA #endif #if !defined(SWIFT_PROTOCOL_EXTRA) # define SWIFT_PROTOCOL_EXTRA #endif #if !defined(SWIFT_ENUM_EXTRA) # define SWIFT_ENUM_EXTRA #endif #if !defined(SWIFT_CLASS) # if __has_attribute(objc_subclassing_restricted) # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA # else # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA # endif #endif #if !defined(SWIFT_RESILIENT_CLASS) # if __has_attribute(objc_class_stub) # define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) # define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) # else # define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) # define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) # endif #endif #if !defined(SWIFT_PROTOCOL) # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA #endif #if !defined(SWIFT_EXTENSION) # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) #endif #if !defined(OBJC_DESIGNATED_INITIALIZER) # if __has_attribute(objc_designated_initializer) # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) # else # define OBJC_DESIGNATED_INITIALIZER # endif #endif #if !defined(SWIFT_ENUM_ATTR) # if defined(__has_attribute) && __has_attribute(enum_extensibility) # define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) # else # define SWIFT_ENUM_ATTR(_extensibility) # endif #endif #if !defined(SWIFT_ENUM) # define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type # if __has_feature(generalized_swift_name) # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type # else # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) # endif #endif #if !defined(SWIFT_UNAVAILABLE) # define SWIFT_UNAVAILABLE __attribute__((unavailable)) #endif #if !defined(SWIFT_UNAVAILABLE_MSG) # define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) #endif #if !defined(SWIFT_AVAILABILITY) # define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) #endif #if !defined(SWIFT_WEAK_IMPORT) # define SWIFT_WEAK_IMPORT __attribute__((weak_import)) #endif #if !defined(SWIFT_DEPRECATED) # define SWIFT_DEPRECATED __attribute__((deprecated)) #endif #if !defined(SWIFT_DEPRECATED_MSG) # define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) #endif #if __has_feature(attribute_diagnose_if_objc) # define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) #else # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) #endif #if !defined(IBSegueAction) # define IBSegueAction #endif #if __has_feature(modules) #if __has_warning("-Watimport-in-framework-header") #pragma clang diagnostic ignored "-Watimport-in-framework-header" #endif @import AVFoundation; @import CoreGraphics; @import CoreMedia; @import Dispatch; @import ObjectiveC; @import UIKit; #endif #import #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" #pragma clang diagnostic ignored "-Wduplicate-method-arg" #if __has_warning("-Wpragma-clang-attribute") # pragma clang diagnostic ignored "-Wpragma-clang-attribute" #endif #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wnullability" #if __has_attribute(external_source_symbol) # pragma push_macro("any") # undef any # pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="VisionCamera",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) # pragma pop_macro("any") #endif SWIFT_CLASS("_TtC12VisionCamera12CameraQueues") @interface CameraQueues : NSObject /// The serial execution queue for the camera preview layer (input stream) as well as output processing of photos. SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) dispatch_queue_t _Nonnull cameraQueue;) + (dispatch_queue_t _Nonnull)cameraQueue SWIFT_WARN_UNUSED_RESULT; /// The serial execution queue for output processing of videos as well as frame processors. SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) dispatch_queue_t _Nonnull videoQueue;) + (dispatch_queue_t _Nonnull)videoQueue SWIFT_WARN_UNUSED_RESULT; - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; @end @class NSCoder; SWIFT_CLASS("_TtC12VisionCamera10CameraView") @interface CameraView : UIView @property (nonatomic, copy) FrameProcessorCallback _Nullable frameProcessorCallback; SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly) Class _Nonnull layerClass;) + (Class _Nonnull)layerClass SWIFT_WARN_UNUSED_RESULT; - (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE; - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)_ SWIFT_UNAVAILABLE; - (void)removeFromSuperview; - (void)didSetProps:(NSArray * _Null_unspecified)changedProps; @end @class AVCaptureOutput; @class AVCaptureConnection; @interface CameraView (SWIFT_EXTENSION(VisionCamera)) - (void)captureOutput:(AVCaptureOutput * _Nonnull)_ didOutputSampleBuffer:(CMSampleBufferRef _Nonnull)sampleBuffer fromConnection:(AVCaptureConnection * _Nonnull)_; - (void)captureOutput:(AVCaptureOutput * _Nonnull)_ didDropSampleBuffer:(CMSampleBufferRef _Nonnull)_ fromConnection:(AVCaptureConnection * _Nonnull)_; @end #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif #pragma clang diagnostic pop #endif ```

What did you expect to happen?

I expect the Swift header to be imported successfully.

What happened instead?

It somehow gets generated incorrectly and tries to import itself with angle brackets (<) instead of quotes ("), which apparently does not work.

CocoaPods Environment

Stack

   CocoaPods : 1.10.1
        Ruby : ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
    RubyGems : 3.0.3
        Host : macOS 11.2.3 (20D91)
       Xcode : 12.4 (12D4e)
         Git : git version 2.24.3 (Apple Git-128)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib
Repositories : trunk - CDN - https://cdn.cocoapods.org/

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

cocoapods-check       : 1.1.0
cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.5.0
cocoapods-try         : 1.2.0

Podfile

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '11.0'

target 'VisionCameraExample' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => true
  )

  pod 'VisionCamera', :path => '../..'

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

Project that demonstrates the issue

VisionCamera (try-simplify-frame-processor branch). See the VisionCamera.podspec in the root, and ios/ for sources.

Relevant files:

mrousavy commented 3 years ago

I already tried cleaning the CameraBridge.h file to not import anything at all which would resolve an import cycle, but apparently that wasn't the problem.

Would it work if I split the Swift and Objective-C files into 2 subspecs?

I found someone having the same issue here. Also related:

is there any solution for this?

GGGava commented 3 years ago

I could not access the link to your branch nor to your files, could you double check?

mrousavy commented 3 years ago

Sorry, I must've accidentally deleted the branch when cleaning a bit. The issue is still present in the frame-processor branch

dinesh547 commented 3 years ago

Are you able to solve this issue? I am facing the same issue here.

mrousavy commented 3 years ago

No, unfortunately I couldn't manage to get the bridging header import working. I had to manually forward-declare the Swift classes, which seems like a hacky workaround. See code here

dinesh547 commented 3 years ago

No, unfortunately I couldn't manage to get the bridging header import working. I had to manually forward-declare the Swift classes, which seems like a hacky workaround. See code here

Thanks @mrousavy . I took a different approach though not complete yet. I created a new new podspec as dependency and added only swift file in that. so i have 2 podspec one containing swift files and 1 containing .h &.m.

May be this can help someone to find a better solution.

But Really thanks for your help.

mrousavy commented 3 years ago

Did you create two separate podspecs or did you use subspecs? I tried to use subspecs, one for the Swift code ("Core") and one for the .h, .m, .mm logic that imported the Swift bridging header, but that didn't work, can't remember what build errors I was getting

dinesh547 commented 3 years ago

Did you create two separate podspecs or did you use subspecs? I tried to use subspecs, one for the Swift code ("Core") and one for the .h, .m, .mm logic that imported the Swift bridging header, but that didn't work, can't remember what build errors I was getting

sorry my mistake, I used subspec like this. s.subspec 'temp_swift' do |ss| ss.dependency 'React' ss.source_files = 'ios/NativeModule/*/.{h,m}' end

I am also getting error in frameworks which i embedded using podspec

Could not find module 'Alamofire' for target 'x86_64-apple-ios-simulator'; found: arm64, armv7-apple-ios, arm64-apple-ios, arm, armv7

Struggling to solve this issue. Any idea how to solve such issue if you have similar issue ?

dnkoutso commented 3 years ago

@mrousavy i will need to take a look. Separating into two different root podspecs is preferable compared to two subspecs. There are quite a few nuances and issues around subspecs, particularly when a different set of subspecs is used across different targets.

dnkoutso commented 3 years ago

also thanks for the great report and sample app, those help a ton.

craigrouse commented 2 years ago

Same issue here with a React Native module, and splitting the Swift and ObjC files into separate podspecs (the Swift one depending on the ObjC one) solved the problem for us.

DanijelBojcic commented 2 years ago

@craigrouse Can you please share you podspecs and the way you import the -Swift.h file? I have the same issue with react-native. I have created two podspecs in the root, the main one is objc which has a dependency to the swift pod. I can see the generated Module-Swift.h in the derived data, but the compiler can't find it...

paulb777 commented 2 years ago

Here's an example import: https://github.com/firebase/firebase-ios-sdk/blob/master/CoreOnly/Sources/Firebase.h#L77. The relevant podspecs are at the top of the repo.

vbabenkoru commented 2 years ago

@DanijelBojcic Have you been able to figure it out?