无法分发 Mac Catalyst 扩展
Can't distribute Mac Catalyst extension
我成功上传到 Appstore iOS 一个带有多个扩展的应用程序,但是当我尝试为 Mac AppStore(一个 Mac Catalyst 应用程序)上传相同的应用程序时,我在两个扩展
上从 Xcode 得到以下错误
ERROR ITMS-90355: "Missing Info.plist value. No value for NSExtensionPrincipalClass found in extension Info.plist
for MyApp.app/Contents/PlugIns/MyExtension.appex"
这些扩展是具有故事板文件的共享扩展和动作扩展,因此如果我在 Info.plist 文件中设置 NSExtensionPrincipalClass 键,我会在控制台中收到以下消息
Invalid Configuration: Either NSExtensionMainStoryboard or NSExtensionPrincipalClass
must be specified in the extension's Info.plist file but not both.
当然没有出现扩展界面,也没有任何作用
有人知道如何解决这个问题吗?
或者,可以仅在 Info.plist 文件中设置 NSExtensionPrincipalClass 键,然后以编程方式调用故事板文件?
提前谢谢大家
瓦尼
在我的扩展中,我使用的是故事板,可以使用
NSExtensionPrincipalClass 而不是 NSExtensionMainStoryboard ?
同时,我已经向 Apple 发送了反馈,
现在 Apple 已经解决了这个问题,我可以毫无问题地加载带有扩展的应用程序。
[更新:问题未解决 - 查看评论]
等待 Apple 的答复,我想出了一个解决方法,包括将故事板包装到新的 AUViewcontroller。
1. include MyXib_Wrapper.h and MyXib_Wrapper.m
2. Add to AudioUnitInterface.storyboard the ID mainStoryID
3. Remove or comment the <AUAudioUnitFactory> from your derived AUViewController class
4. Update code in MyXib_Wrapper.m -> createAudioUnitWithComponentDescription according to your code (if you are performing more tasks)
5. Replace in .plist NSExtensionMainStoryboard with NSExtensionPrincipalClass
6. Sets MyXib_Wrapper for NSExtensionPrincipalClass and factoryFunction (very important!)
MyXib_Wrapper.h
#import <CoreAudioKit/AUViewController.h>
#import "AudioUnitViewController.h"
@class AudioUnitViewController;
@interface MyXib_Wrapper : AUViewController <AUAudioUnitFactory> {
AudioUnitViewController *vc;
}
@end
MyXib_Wrapper.m
#import "MyXib_Wrapper.h"
#import "AudioUnitViewController.h"
#import "MyAudioUnit.h"
@implementation MyXib_Wrapper
- (MyAudioUnit *) createAudioUnitWithComponentDescription:(AudioComponentDescription) desc error:(NSError **)error {
vc.audioUnit = [[MyAudioUnit alloc] initWithComponentDescription:desc error:error];
// perform here more tasks
return vc.audioUnit;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"AudioUnitInterface" bundle:nil];
vc = (AudioUnitViewController*) [storyboard instantiateViewControllerWithIdentifier:@"mainStoryID"];
}
return self;
}
#pragma mark - View lifecycle
-(UIView*)view {
return vc.view;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.preferredContentSize = vc.preferredContentSize;
}
@end
从 Alessandro Petrolati 变通方法中获得灵感,我认为我找到了一个更简单的解决方案,至少在我的案例中,这两个扩展都运行良好。
1. Replace in .plist NSExtensionMainStoryboard with NSExtensionPrincipalClass
2. Update YourViewController.m file
将此 init 方法添加到您的 .m class 文件
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YournStoryboardName" bundle:nil];
self = (YourViewController*) [storyboard instantiateViewControllerWithIdentifier:@"YourStoryboardID"];
}
return self;
}
这似乎太简单了...
包验证成功,我终于顺利地将应用程序上传到 AppStore Connect!
我要做的就是在上线前查看最新详情...
试着相信!
让我知道您的印象
我的方法是只使用一个简单的 VC 加载到代码中,然后 VC 包含实际呈现我们想要的 VC(从 Storyboard 加载)
info.plist 包含:
<key>NSExtension</key>
<dict>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).PreviewVCLoader</string>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportsSearchableItems</key>
<true/>
<key>QLSupportedContentTypes</key>
<array>
<string>com.hobbyistsoftware.jump</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.preview</string>
</dict>
然后我的预览VC加载器class是
import UIKit
import QuickLook
class PreviewVCLoader: UIViewController, QLPreviewingController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var realVC:PreviewViewController = {
let board = UIStoryboard.init(name: "MainInterface", bundle: nil)
guard let vc = board.instantiateViewController(withIdentifier: "PreviewViewController") as? PreviewViewController else {
fatalError("Unable to instantiate storyboard in preview")
}
return vc
}()
override func viewDidLoad() {
super.viewDidLoad()
self.addChild(realVC)
realVC.view.frame = self.view.bounds
realVC.view.autoresizingMask = [.flexibleWidth,.flexibleHeight]
self.view.addSubview(realVC.view)
realVC.didMove(toParent: self)
}
func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
realVC.preparePreviewOfFile(at: url, completionHandler: handler)
}
}
我成功上传到 Appstore iOS 一个带有多个扩展的应用程序,但是当我尝试为 Mac AppStore(一个 Mac Catalyst 应用程序)上传相同的应用程序时,我在两个扩展
上从 Xcode 得到以下错误ERROR ITMS-90355: "Missing Info.plist value. No value for NSExtensionPrincipalClass found in extension Info.plist
for MyApp.app/Contents/PlugIns/MyExtension.appex"
这些扩展是具有故事板文件的共享扩展和动作扩展,因此如果我在 Info.plist 文件中设置 NSExtensionPrincipalClass 键,我会在控制台中收到以下消息
Invalid Configuration: Either NSExtensionMainStoryboard or NSExtensionPrincipalClass
must be specified in the extension's Info.plist file but not both.
当然没有出现扩展界面,也没有任何作用
有人知道如何解决这个问题吗?
或者,可以仅在 Info.plist 文件中设置 NSExtensionPrincipalClass 键,然后以编程方式调用故事板文件?
提前谢谢大家
瓦尼
在我的扩展中,我使用的是故事板,可以使用 NSExtensionPrincipalClass 而不是 NSExtensionMainStoryboard ? 同时,我已经向 Apple 发送了反馈,
现在 Apple 已经解决了这个问题,我可以毫无问题地加载带有扩展的应用程序。
[更新:问题未解决 - 查看评论]
等待 Apple 的答复,我想出了一个解决方法,包括将故事板包装到新的 AUViewcontroller。
1. include MyXib_Wrapper.h and MyXib_Wrapper.m
2. Add to AudioUnitInterface.storyboard the ID mainStoryID
3. Remove or comment the <AUAudioUnitFactory> from your derived AUViewController class
4. Update code in MyXib_Wrapper.m -> createAudioUnitWithComponentDescription according to your code (if you are performing more tasks)
5. Replace in .plist NSExtensionMainStoryboard with NSExtensionPrincipalClass
6. Sets MyXib_Wrapper for NSExtensionPrincipalClass and factoryFunction (very important!)
MyXib_Wrapper.h
#import <CoreAudioKit/AUViewController.h>
#import "AudioUnitViewController.h"
@class AudioUnitViewController;
@interface MyXib_Wrapper : AUViewController <AUAudioUnitFactory> {
AudioUnitViewController *vc;
}
@end
MyXib_Wrapper.m
#import "MyXib_Wrapper.h"
#import "AudioUnitViewController.h"
#import "MyAudioUnit.h"
@implementation MyXib_Wrapper
- (MyAudioUnit *) createAudioUnitWithComponentDescription:(AudioComponentDescription) desc error:(NSError **)error {
vc.audioUnit = [[MyAudioUnit alloc] initWithComponentDescription:desc error:error];
// perform here more tasks
return vc.audioUnit;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"AudioUnitInterface" bundle:nil];
vc = (AudioUnitViewController*) [storyboard instantiateViewControllerWithIdentifier:@"mainStoryID"];
}
return self;
}
#pragma mark - View lifecycle
-(UIView*)view {
return vc.view;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.preferredContentSize = vc.preferredContentSize;
}
@end
从 Alessandro Petrolati 变通方法中获得灵感,我认为我找到了一个更简单的解决方案,至少在我的案例中,这两个扩展都运行良好。
1. Replace in .plist NSExtensionMainStoryboard with NSExtensionPrincipalClass
2. Update YourViewController.m file
将此 init 方法添加到您的 .m class 文件
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YournStoryboardName" bundle:nil];
self = (YourViewController*) [storyboard instantiateViewControllerWithIdentifier:@"YourStoryboardID"];
}
return self;
}
这似乎太简单了...
包验证成功,我终于顺利地将应用程序上传到 AppStore Connect!
我要做的就是在上线前查看最新详情...
试着相信!
让我知道您的印象
我的方法是只使用一个简单的 VC 加载到代码中,然后 VC 包含实际呈现我们想要的 VC(从 Storyboard 加载)
info.plist 包含:
<key>NSExtension</key>
<dict>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).PreviewVCLoader</string>
<key>NSExtensionAttributes</key>
<dict>
<key>QLSupportsSearchableItems</key>
<true/>
<key>QLSupportedContentTypes</key>
<array>
<string>com.hobbyistsoftware.jump</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.preview</string>
</dict>
然后我的预览VC加载器class是
import UIKit
import QuickLook
class PreviewVCLoader: UIViewController, QLPreviewingController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var realVC:PreviewViewController = {
let board = UIStoryboard.init(name: "MainInterface", bundle: nil)
guard let vc = board.instantiateViewController(withIdentifier: "PreviewViewController") as? PreviewViewController else {
fatalError("Unable to instantiate storyboard in preview")
}
return vc
}()
override func viewDidLoad() {
super.viewDidLoad()
self.addChild(realVC)
realVC.view.frame = self.view.bounds
realVC.view.autoresizingMask = [.flexibleWidth,.flexibleHeight]
self.view.addSubview(realVC.view)
realVC.didMove(toParent: self)
}
func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
realVC.preparePreviewOfFile(at: url, completionHandler: handler)
}
}