user3097511
user3097511

Reputation: 53

Swift generated header missing external swift frameworks

I'm running into some issues with my Swift generated header. My Swift classes in the Swift generated header aren't including any properties or methods from any Swift frameworks installed via Cocoapods.

Here's what I am doing.

  1. I have an XCode project that is pure Objective-C.

  2. I added a Swift class (Model.swift) to the project that handles my networking calls and syncing JSON responses to CoreData. That Swift class is using Alamofire to do all the networking calls.

  3. I setup XCode build settings to properly generate my ProjectName-Swift.h

    • Define Module YES
    • Added Product Module Name
  4. When I view my Model.swift class in the Swift generated header, function calls are missing. The missing function call's return Request Objects which are from Alamofire. So it appears that when Xcode build's the Swift header, it is unable to see Alamofire.

Here are some things I've checked.

  1. My Model.swift is public. Class is marked public, and functions I want exposed are public. Generated Swift header will include anything marked public.
  2. I checked Alamofire from the Pods build settings, the framework is public and Define Modules is set to YES. It also has it's own generated 'Alamofire-Swift.h'.

I'm Running XCode 7.2 with a minimum deployment target of iOS 8

I'm using cocoapods 0.39

Here is a sample of my Cocoapods.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0' 
use_frameworks!
pod 'Alamofire', '3.1.2'

Is there anything else I am missing in order for the Swift header to generate code from external Swift frameworks?

My next step will be creating a smaller project to test. But, if this isn't possible or I am missing something I would like to know.

Thanks all

Update - I just created a smaller Xcode project in Objective-C so you can see a scaled down test version of my Model.swift and the generated header.

import Foundation
import Alamofire

public class Model: NSObject
{
    public var myPropertyA: String?
    public var myPropertyB: Int = 0

    public override init()
    {
        super.init()
    }

    deinit
    {

    }

    //MARK: public methods

    public func myPublicFunctionA() -> String?
    {
        return nil
    }

    public func myPublicFunctionB() -> Int
    {
        return 0
    }

    public func simpleRequest() -> Request?
    {
        return nil
    }

    public func requestJSON(method: Alamofire.Method, url: String?, parameters: [String: AnyObject]?, headers: [String: String]?, complete: ((json: AnyObject?, error: NSError?, errorOccurred: Bool) -> Void)?) -> Request?
    {
        var request: Request?
        request = Alamofire.request(method, url!, parameters: parameters, encoding: .URL, headers: headers).validate().responseJSON { response in

            let json: AnyObject? = response.result.value

            switch response.result
            {
            case .Success:

                if (complete != nil)
                {
                    complete?(json: json, error: nil, errorOccurred: false)
                }

                break

            case .Failure(let error):

                if (complete != nil)
                {
                    complete?(json: json, error: error, errorOccurred: true)
                }

                break
            }
        }

        return request
    }
}

And here is the swift header generated from Xcode. If you scroll to the bottom you will see the generated Model.swift will be missing 2 functions that require Alamofire dependency. simpleRequest and requestJSON are missing.

// Generated by Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
#pragma clang diagnostic push

#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include <objc/NSObject.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#if defined(__has_include) && __has_include(<uchar.h>)
# include <uchar.h>
#elif !defined(__cplusplus) || __cplusplus < 201103L
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
#endif

typedef struct _NSZone NSZone;

#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(__has_attribute) && __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#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 defined(__has_attribute) && __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_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 defined(__has_attribute) && __has_attribute(objc_designated_initializer)
#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
#  define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
#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)));
#if defined(__has_feature) && __has_feature(modules)
@import ObjectiveC;
#endif

#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"

SWIFT_CLASS("_TtC6MyTest5Model")
@interface Model : NSObject
@property (nonatomic, copy) NSString * __nullable myPropertyA;
@property (nonatomic) NSInteger myPropertyB;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
- (NSString * __nullable)myPublicFunctionA;
- (NSInteger)myPublicFunctionB;
@end

#pragma clang diagnostic pop

Upvotes: 2

Views: 1668

Answers (1)

JaimeLeon
JaimeLeon

Reputation: 11

I had the same problem and the way to solve it was adding the directive @objc before the public function to use in Objective C.

For example:

import Foundation
import Alamofire

public class Model: NSObject
{
    public var myPropertyA: String?
    public var myPropertyB: Int = 0

public override init()
{
    super.init()
}

deinit
{

}

//MARK: public methods

@objc public func myPublicFunctionA() -> String?
{
    return nil
}

@objc public func myPublicFunctionB() -> Int
{
    return 0
}

@objc public func simpleRequest() -> Request?
{
    return nil
}

...

I hope to help.

Upvotes: 1

Related Questions