

Unity用iOSプラグインをSwiftベースで作っております．  
ただし，SQLiteを使用するためFMDBをソースファイル(.m/.h)から読み込んでおります．  
そのためか，複数のUnityPluginをSwiftで生成するページを参照しておりますが，上手く行かず困っております．

## １つ目：SwiftクラスがExportされない！？

次の通り，SwiftクラスをObjCから参照できるようにWrapperクラスを定義しておりますが，後述するSwiftのExampleクラスのメソッドをObj-
Cから参照できず，`No known class method for selector 'swiftMethod'`というエラーがでております．

**【質問１】**
どうやらSwift.hにWrapperクラスから参照したいメソッドの雛形(Extern)の記述がない事から，メソッドが１つもObjective-
Cから参照できない結果となっている事が原因かと思われるのですが，なぜ，Swift.hにメソッドの雛形（Extern)が記述されないのかわかる方がいらっしゃったらお教え頂けますでしょうか．

### Example.mm

[code]

    #import <UIKit/UIKit.h>
    ////#import <Foundation/Foundation.h>
    #import <MyUnityPlugin-Swift.h>
    //// This header file is generated automatically when Xcode build runs.
    //
    
    #ifdef __cplusplus
    extern "C" {
    #endif
        void _ex_callSwiftMethod(const char *message) {
            // You can access Swift classes directly here.
            [Example swiftMethod]; // No known class method for selector 'swiftMethod'
            [[Example swiftMethod]Method]; // No known class method for selector 'swiftMethod'
        }
    #ifdef __cplusplus
    }
    #endif
    
[/code]

### Example.swift

[code]

    import Foundation
    
    public class Example : NSObject {
        public static func swiftMethod() {
            print("\(#function) message: ")
        }
    
        public func test(){
            print("test1 on ObjC");
        }
    
        public static func test2(test:NSString){
            print("test2")
        }
    }
    
    public func Test2(){
        print("test2");
    }
    
[/code]

### auto生成されたSwift.h

[code]

    SWIFT_CLASS("_TtC13MyUnityPlugin7Example")
    @interface Example : NSObject
    - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
    @end
    
[/code]

## ２つ目：Swift-ObjCの循環参照問題

Bridging-
Header.hと<ProjectName>-Swift.h(以下,Swift.hと略)を使う事による循環参照が生じているようです．問題の発端は次です．

[code]

    Cannot find protocol declaration for 'CLLocationManagerDelegate'; did you mean 'NSLayoutManagerDelegate'?`
    
[/code]

エラーを調べてみると，header/import(も含む?)の循環参照（参照不備へ訂正）だろうと推測．  
循環参照（参照不備へ訂正）は，Bridging-Header.hとSwift.hによるものかと推測します．

**【質問２】** Swift.hに，上記原因となったCLLocationManagerDelegateを書き出されています．それはObjective-
Cから参照しないので，解決策としてSwift.hに書き出さない方法をご教示いただけないでしょうか．(※
こちらはSwift.hを手動で編集する手で何とかなるのですが，毎回編集するのも負担なので，どうぞよろしくお願い致します．）

### Bridging-Header.h

[code]

    // For FMDB
    #import "FMDatabase.h"
    #import "FMResultSet.h"
    #import "FMDatabaseAdditions.h"
    #import "FMDatabaseQueue.h"
    #import "FMDatabasePool.h"
    
[/code]

### <ProjectName>-Swift.h

[code]

    // Generated by Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wgcc-compat"
    
    【省略】
    
    #if __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 __has_feature(modules)
    @import UIKit;
    @import ObjectiveC;
    @import CoreLocation;
    #endif
    
    【省略】
    
    @class UIWindow;
    @class UIApplication;
    
    SWIFT_CLASS("_TtC13MyUnityPlugin11AppDelegate")
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    @property (nonatomic, strong) UIWindow * _Nullable window;
    - (BOOL)application:(UIApplication * _Nonnull)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> * _Nullable)launchOptions SWIFT_WARN_UNUSED_RESULT;
    - (void)applicationWillResignActive:(UIApplication * _Nonnull)application;
    - (void)applicationDidEnterBackground:(UIApplication * _Nonnull)application;
    - (void)applicationWillEnterForeground:(UIApplication * _Nonnull)application;
    - (void)applicationDidBecomeActive:(UIApplication * _Nonnull)application;
    - (void)applicationWillTerminate:(UIApplication * _Nonnull)application;
    - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
    @end
    
    
    SWIFT_CLASS("_TtC13MyUnityPlugin7Example")
    @interface Example : NSObject
    - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
    @end
    
    
    【省略】
    
    @class CLLocationManager;
    @class CLLocation;
    
    @interface MyLocationService (SWIFT_EXTENSION(MyUnityPlugin)) <CLLocationManagerDelegate>
    - (void)locationManager:(CLLocationManager * _Nonnull)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
    - (void)locationManager:(CLLocationManager * _Nonnull)manager didUpdateLocations:(NSArray<CLLocation *> * _Nonnull)locations;
    @end
    
    【省略】
    
[/code]


CC BY-SA 3.0
2018-04-19T02:51:03.347
43368
2018-10-21T17:00:35.720
2018-04-19T11:07:58.247
9726
9726
question
swift ios xcode objective-c unity3d
Swift-ObjCの参照不備とswiftクラスのメソッドがExportされない？問題


### 【質問１】について

Swift4では極めて限定的な条件が成立した時以外には、ObjC用のエントリーポイントが生成されません。必要なメソッドの前に@objcを付けてみて下さい。

### 【質問２】について

循環参照と言うより、メッセージの通りCLLocationManagerDelegateの定義が見つからないと言うだけだと思うのですが？Example.mmのUIKitのimportのように-
Swift.hをimportする前には、必ずCoreLocationをimportする方が確実なのではないでしょうか？ObjCから使わなくても、毎回-
Swift.hを修正するなんて怪しい事よりはましだと思います。


CC BY-SA 3.0
2018-04-19T06:44:31.390
43376
2018-04-19T06:44:31.390
13972
43368
answer


OOPerさん

【質問1の回答】頂いた実施で，下記を得ました．エントリーポイントSwiftMethodが見えるので，恐らくObjCから参照できそうです．ありがとうございました．

[code]

    SWIFT_CLASS("_TtC13MyUnityPlugin7Example")
    @interface Example : NSObject
    + (void)swiftMethod;
    - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
    @end
    
[/code]

【質問2の回答】

CLLocationManagerDelegateクラスは，Swiftクラス周り（内部）では使用しているのですが，外部(Unity)から参照はできない予定です．（Swift周りからはCLLocationManagerDelegateを継承したクラスは参照できております）

CLLocationManagerDelegate継承/関連したSwiftのクラスを「ObjCから」は使用しないにもかかわらず，  
生成したSwift.hにそれらSwiftクラスのエントリーポイントが含まれてしまい，そこで参照関連のエラーとなってしまっているようです．

Swift.hへのエントリーポイントの生成も避けるよい方法がございましたら．  
（意図を理解しようとしましたが，ご指摘いただいた通りするには，CLLocationManagerDelegateクラスを参照するObjCクラスの.mmファイルがあればよいのですが，そういったファイルがないのが現状でございます）


CC BY-SA 3.0
2018-04-19T08:31:22.930
43380
2018-04-20T08:26:22.170
2018-04-20T08:26:22.170
9726
9726
43368
answer