Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/android support #16

Merged
merged 12 commits into from
Jun 12, 2024
Prev Previous commit
Next Next commit
Add iOS native implementation
  • Loading branch information
mvanbeusekom committed Jun 6, 2024
commit 9901be38d7a0c1574a5497cc69b8bab092aee88d
6 changes: 3 additions & 3 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -20,9 +20,9 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_instance_manager: 02c8307bca749e95c498f5618b916badc23438f8
integration_test: 13825b8a9334a850581300559b8839134b124670
flutter_instance_manager: fd2581b919cbd3f83c541e6166ddaa4fe8e261f6
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4

PODFILE CHECKSUM: 6e700dec67e6deac9b1c69bb14c49a2217a12d15

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
96 changes: 48 additions & 48 deletions example/ios/Runner.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

30 changes: 0 additions & 30 deletions example/test/widget_test.dart

This file was deleted.

41 changes: 41 additions & 0 deletions ios/Classes/FLTFoundationImplementation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Flutter/Flutter.h>

#import "foundation.pigeon.h"
#import "FLTInstanceManager.h"

NS_ASSUME_NONNULL_BEGIN

/**
* Flutter api implementation for NSObject.
*
* Handles making callbacks to Dart for an NSObject.
*/
@interface FLTObjectFlutterApiImpl : FLTNSObjectFlutterApi
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
instanceManager:(FLTInstanceManager *)instanceManager;
@end

/**
* Implementation of NSObject for FWFObjectHostApiImpl.
*/
@interface FLTObject : NSObject
@property(readonly, nonnull, nonatomic) FLTObjectFlutterApiImpl *objectApi;

- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
instanceManager:(FLTInstanceManager *)instanceManager;
@end

/**
* Host api implementation for NSObject.
*
* Handles creating NSObject that intercommunicate with a paired Dart object.
*/
@interface FLTObjectHostApiImpl : NSObject <FLTNSObjectHostApi>
- (instancetype)initWithInstanceManager:(FLTInstanceManager *)instanceManager;
@end

NS_ASSUME_NONNULL_END
58 changes: 58 additions & 0 deletions ios/Classes/FLTFoundationImplementation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "FLTFoundationImplementation.h"
#import <objc/runtime.h>

@interface FLTObjectFlutterApiImpl ()
// BinaryMessenger must be weak to prevent a circular reference with the host API it
// references.
@property(nonatomic, weak) id<FlutterBinaryMessenger> binaryMessenger;
// InstanceManager must be weak to prevent a circular reference with the object it stores.
@property(nonatomic, weak) FLTInstanceManager *instanceManager;
@end

@implementation FLTObjectFlutterApiImpl
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
instanceManager:(FLTInstanceManager *)instanceManager {
self = [self initWithBinaryMessenger:binaryMessenger];
if (self) {
_binaryMessenger = binaryMessenger;
_instanceManager = instanceManager;
}
return self;
}
@end

@implementation FLTObject
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
instanceManager:(FLTInstanceManager *)instanceManager {
self = [self init];
if (self) {
_objectApi = [[FLTObjectFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger
instanceManager:instanceManager];
}
return self;
}
@end

@interface FLTObjectHostApiImpl ()
// InstanceManager must be weak to prevent a circular reference with the object it stores.
@property(nonatomic, weak) FLTInstanceManager *instanceManager;
@end

@implementation FLTObjectHostApiImpl
- (instancetype)initWithInstanceManager:(FLTInstanceManager *)instanceManager {
self = [self init];
if (self) {
_instanceManager = instanceManager;
}
return self;
}

- (void)disposeObjectWithIdentifier:(nonnull NSUUID *)identifier
error:(FlutterError *_Nullable *_Nonnull)error {
[self.instanceManager removeInstanceWithIdentifier:identifier];
}
@end
90 changes: 0 additions & 90 deletions ios/Classes/FoundationApi/foundation.pigeon.swift

This file was deleted.

43 changes: 43 additions & 0 deletions ios/Classes/foundation.pigeon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v19.0.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon

#import <Foundation/Foundation.h>

@protocol FlutterBinaryMessenger;
@protocol FlutterMessageCodec;
@class FlutterError;
@class FlutterStandardTypedData;

NS_ASSUME_NONNULL_BEGIN


/// The codec used by FLTNSObjectHostApi.
NSObject<FlutterMessageCodec> *FLTNSObjectHostApiGetCodec(void);

/// Mirror of NSObject.
///
/// See https://developer.apple.com/documentation/objectivec/nsobject.
@protocol FLTNSObjectHostApi
- (void)disposeObjectWithIdentifier:(NSString *)identifier error:(FlutterError *_Nullable *_Nonnull)error;
@end

extern void SetUpFLTNSObjectHostApi(id<FlutterBinaryMessenger> binaryMessenger, NSObject<FLTNSObjectHostApi> *_Nullable api);

extern void SetUpFLTNSObjectHostApiWithSuffix(id<FlutterBinaryMessenger> binaryMessenger, NSObject<FLTNSObjectHostApi> *_Nullable api, NSString *messageChannelSuffix);

/// The codec used by FLTNSObjectFlutterApi.
NSObject<FlutterMessageCodec> *FLTNSObjectFlutterApiGetCodec(void);

/// Handles callbacks from an NSObject instance.
///
/// See https://developer.apple.com/documentation/objectivec/nsobject.
@interface FLTNSObjectFlutterApi : NSObject
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger messageChannelSuffix:(nullable NSString *)messageChannelSuffix;
- (void)disposeObjectWithIdentifier:(NSString *)identifier completion:(void (^)(FlutterError *_Nullable))completion;
@end

NS_ASSUME_NONNULL_END
113 changes: 113 additions & 0 deletions ios/Classes/foundation.pigeon.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v19.0.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon

#import "foundation.pigeon.h"

#if TARGET_OS_OSX
#import <FlutterMacOS/FlutterMacOS.h>
#else
#import <Flutter/Flutter.h>
#endif

#if !__has_feature(objc_arc)
#error File requires ARC to be enabled.
#endif

static NSArray *wrapResult(id result, FlutterError *error) {
if (error) {
return @[
error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null]
];
}
return @[ result ?: [NSNull null] ];
}

static FlutterError *createConnectionError(NSString *channelName) {
return [FlutterError errorWithCode:@"channel-error" message:[NSString stringWithFormat:@"%@/%@/%@", @"Unable to establish connection on channel: '", channelName, @"'."] details:@""];
}

static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
id result = array[key];
return (result == [NSNull null]) ? nil : result;
}

NSObject<FlutterMessageCodec> *FLTNSObjectHostApiGetCodec(void) {
static FlutterStandardMessageCodec *sSharedObject = nil;
sSharedObject = [FlutterStandardMessageCodec sharedInstance];
return sSharedObject;
}

void SetUpFLTNSObjectHostApi(id<FlutterBinaryMessenger> binaryMessenger, NSObject<FLTNSObjectHostApi> *api) {
SetUpFLTNSObjectHostApiWithSuffix(binaryMessenger, api, @"");
}

void SetUpFLTNSObjectHostApiWithSuffix(id<FlutterBinaryMessenger> binaryMessenger, NSObject<FLTNSObjectHostApi> *api, NSString *messageChannelSuffix) {
messageChannelSuffix = messageChannelSuffix.length > 0 ? [NSString stringWithFormat: @".%@", messageChannelSuffix] : @"";
{
FlutterBasicMessageChannel *channel =
[[FlutterBasicMessageChannel alloc]
initWithName:[NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.flutter_instance_manager.NSObjectHostApi.dispose", messageChannelSuffix]
binaryMessenger:binaryMessenger
codec:FLTNSObjectHostApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(disposeObjectWithIdentifier:error:)], @"FLTNSObjectHostApi api (%@) doesn't respond to @selector(disposeObjectWithIdentifier:error:)", api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
NSString *arg_identifier = GetNullableObjectAtIndex(args, 0);
FlutterError *error;
[api disposeObjectWithIdentifier:arg_identifier error:&error];
callback(wrapResult(nil, error));
}];
} else {
[channel setMessageHandler:nil];
}
}
}
NSObject<FlutterMessageCodec> *FLTNSObjectFlutterApiGetCodec(void) {
static FlutterStandardMessageCodec *sSharedObject = nil;
sSharedObject = [FlutterStandardMessageCodec sharedInstance];
return sSharedObject;
}

@interface FLTNSObjectFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@property(nonatomic, strong) NSString *messageChannelSuffix;
@end

@implementation FLTNSObjectFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
return [self initWithBinaryMessenger:binaryMessenger messageChannelSuffix:@""];
}
- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger messageChannelSuffix:(nullable NSString*)messageChannelSuffix{
self = [self init];
if (self) {
_binaryMessenger = binaryMessenger;
_messageChannelSuffix = [messageChannelSuffix length] == 0 ? @"" : [NSString stringWithFormat: @".%@", messageChannelSuffix];
}
return self;
}
- (void)disposeObjectWithIdentifier:(NSString *)arg_identifier completion:(void (^)(FlutterError *_Nullable))completion {
NSString *channelName = [NSString stringWithFormat:@"%@%@", @"dev.flutter.pigeon.flutter_instance_manager.NSObjectFlutterApi.dispose", _messageChannelSuffix];
FlutterBasicMessageChannel *channel =
[FlutterBasicMessageChannel
messageChannelWithName:channelName
binaryMessenger:self.binaryMessenger
codec:FLTNSObjectFlutterApiGetCodec()];
[channel sendMessage:@[arg_identifier ?: [NSNull null]] reply:^(NSArray<id> *reply) {
if (reply != nil) {
if (reply.count > 1) {
completion([FlutterError errorWithCode:reply[0] message:reply[1] details:reply[2]]);
} else {
completion(nil);
}
} else {
completion(createConnectionError(channelName));
}
}];
}
@end

Loading