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/ios rest #4

Merged
merged 9 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ client library SDKs for [Ably](https://ably.io/), the realtime data delivery pla
Ably provides the best infrastructure and APIs to power realtime experiences at scale, delivering billions of realtime messages everyday to millions of end users.
We handle the complexity of realtime messaging so you can focus on your code.

## :construction: Work In Progress! :construction:
## :construction: Experimental! :construction:

We're busy working on this repository at the moment and we're doing that work in the public domain so that you can watch or
[contribute](#contributing).
Expand Down
5 changes: 4 additions & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
10B8B89ABB4264117E7AB56C /* Pods-Runner.release.xcconfig */,
EA3336021AE374E30F8FCF54 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
Expand Down Expand Up @@ -185,6 +184,7 @@
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = S38X8U35U5;
QuintinWillison marked this conversation as resolved.
Show resolved Hide resolved
};
};
};
Expand Down Expand Up @@ -393,6 +393,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = S38X8U35U5;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -523,6 +524,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = S38X8U35U5;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -546,6 +548,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = S38X8U35U5;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
Expand All @@ -38,8 +36,8 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -61,8 +59,6 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
Expand Down
4 changes: 3 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ class _MyAppState extends State<MyApp> {

String name = "Hello";
dynamic data = "Flutter";
print('publishing message... name "$name", message "$data"');
print('publishing messages... name "$name", message "$data"');
await rest.channels.get('test').publish(name, data);
await rest.channels.get('test').publish(name);
await rest.channels.get('test').publish();
print('Message published');
}

Expand Down
5 changes: 5 additions & 0 deletions ios/Classes/AblyFlutter.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
@import Foundation;

@class ARTRest;
@class ARTClientOptions;
@class AblyFlutterSurfaceRealtime;

NS_ASSUME_NONNULL_BEGIN

@interface AblyFlutter : NSObject

-(NSNumber *)createRestWithOptions:(ARTClientOptions *)options;

-(nullable ARTRest *)getRest:(NSNumber *)handle;

-(NSNumber *)createRealtimeWithOptions:(ARTClientOptions *)options;

-(nullable AblyFlutterSurfaceRealtime *)realtimeWithHandle:(NSNumber *)handle;
Expand Down
19 changes: 19 additions & 0 deletions ios/Classes/AblyFlutter.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@implementation AblyFlutter {
BOOL _disposed;
NSMutableDictionary<NSNumber *, AblyFlutterSurfaceRealtime *>* _realtimeInstances;
NSMutableDictionary<NSNumber *, ARTRest *>* _restInstances;
long long _nextHandle;
}

Expand All @@ -19,6 +20,7 @@ -(instancetype)init {
}

_realtimeInstances = [NSMutableDictionary new];
_restInstances = [NSMutableDictionary new];
_nextHandle = 1;

return self;
Expand All @@ -30,6 +32,23 @@ -(instancetype)init {
format:@"Instance disposed."]; \
}

-(NSNumber *)createRestWithOptions:(ARTClientOptions *const)options {
if (!options) {
[NSException raise:NSInvalidArgumentException format:@"options cannot be nil."];
}

ASSERT_NOT_DISPOSED

ARTRest *const instance = [[ARTRest alloc] initWithOptions:options];
NSNumber *const handle = @(_nextHandle++);
[_restInstances setObject:instance forKey:handle];
return handle;
}

-(ARTRest *)getRest:(NSNumber *const)handle {
return [_restInstances objectForKey:handle];
}

-(NSNumber *)createRealtimeWithOptions:(ARTClientOptions *const)options {
if (!options) {
[NSException raise:NSInvalidArgumentException format:@"options cannot be nil."];
Expand Down
36 changes: 36 additions & 0 deletions ios/Classes/AblyFlutterPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,40 @@ -(nullable AblyFlutter *)ablyWithHandle:(NSNumber *)handle;
[plugin registerWithCompletionHandler:result];
};

static FlutterHandler _createRestWithOptions = ^void(AblyFlutterPlugin *const plugin, FlutterMethodCall *const call, const FlutterResult result) {
AblyFlutterMessage *const message = call.arguments;
LOG(@"message for handle %@", message.handle);
AblyFlutter *const ably = [plugin ablyWithHandle:message.handle];
// TODO if ably is nil here then an error response, perhaps? or allow Dart side to understand null response?
result([ably createRestWithOptions:message.message]);
};

static FlutterHandler _publishRestMessage = ^void(AblyFlutterPlugin *const plugin, FlutterMethodCall *const call, const FlutterResult result) {
tiholic marked this conversation as resolved.
Show resolved Hide resolved
AblyFlutterMessage *const message = call.arguments;
LOG(@"message for handle %@", message.handle);
AblyFlutter *const ably = [plugin ablyWithHandle:message.handle];
AblyFlutterMessage *const messageData = message.message;
NSMutableDictionary<NSString *, NSObject *>* _dataMap = messageData.message;
NSString *channelName = (NSString*)[_dataMap objectForKey:@"channel"];
QuintinWillison marked this conversation as resolved.
Show resolved Hide resolved
NSString *const eventName = (NSString*)[_dataMap objectForKey:@"name"];
NSObject *const eventData = (NSString*)[_dataMap objectForKey:@"message"];
ARTRest *client = [ably getRest:messageData.handle];
ARTRestChannel *channel = [client.channels get:channelName];

[channel publish:eventName data:eventData callback:^(ARTErrorInfo *_Nullable error){
tiholic marked this conversation as resolved.
Show resolved Hide resolved
if(error){
result([
FlutterError
errorWithCode:[NSString stringWithFormat: @"%ld", (long)error.code]
message:[NSString stringWithFormat:@"Unable to publish message to Ably server; err = %@", [error message]]
details:nil
]);
}else{
result(nil);
}
}];
};

static FlutterHandler _createRealtimeWithOptions = ^void(AblyFlutterPlugin *const plugin, FlutterMethodCall *const call, const FlutterResult result) {
AblyFlutterMessage *const message = call.arguments;
LOG(@"message for handle %@", message.handle);
Expand Down Expand Up @@ -92,6 +126,8 @@ -(instancetype)initWithChannel:(FlutterMethodChannel *const)channel {
@"getPlatformVersion": _getPlatformVersion,
@"getVersion": _getVersion,
@"register": _register,
@"createRestWithOptions": _createRestWithOptions,
@"publish": _publishRestMessage,
@"createRealtimeWithOptions": _createRealtimeWithOptions,
@"connectRealtime": _connectRealtime,
@"dispose": _dispose,
Expand Down
34 changes: 29 additions & 5 deletions ios/Classes/AblyFlutterReader.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ @implementation AblyFlutterReader

typedef NS_ENUM(UInt8, _Value) {
_valueClientOptions = 128,
_valueAblyMessage = 129,
_valueTokenDetails = 129,
_valueAblyMessage = 255,
};

-(id)readValueOfType:(const UInt8)type {
switch ((_Value)type) {
case _valueClientOptions:
return [self readClientOptions];

case _valueTokenDetails:
return [self readTokenDeatils];

case _valueAblyMessage:
return [self readAblyFlutterMessage];
}
Expand Down Expand Up @@ -81,7 +85,8 @@ -(ARTClientOptions *)readClientOptions {
READ_VALUE(o, authUrl);
READ_VALUE(o, authMethod);
READ_VALUE(o, key);
READ_VALUE(o, tokenDetails);
// READ_VALUE(o, tokenDetails);
ON_VALUE(^(const id value) { o.tokenDetails = value; });
READ_VALUE(o, authHeaders);
READ_VALUE(o, authParams);
READ_VALUE(o, queryTime);
Expand All @@ -90,6 +95,7 @@ -(ARTClientOptions *)readClientOptions {
// ClientOptions
READ_VALUE(o, clientId);
ON_VALUE(^(const id value) { o.logLevel = _logLevel(value); });
//TODO log handler
READ_VALUE(o, tls);
READ_VALUE(o, restHost);
READ_VALUE(o, realtimeHost);
Expand All @@ -100,7 +106,6 @@ -(ARTClientOptions *)readClientOptions {
READ_VALUE(o, queueMessages);
READ_VALUE(o, echoMessages);
READ_VALUE(o, recover);
[self readValue]; // TODO READ_VALUE(o, proxy); // property not found
READ_VALUE(o, environment);
READ_VALUE(o, idempotentRestPublishing);
[self readValue]; // TODO READ_VALUE(o, httpOpenTimeout); // NSTimeInterval
Expand All @@ -113,9 +118,28 @@ -(ARTClientOptions *)readClientOptions {
READ_VALUE(o, defaultTokenParams);
[self readValue]; // TODO READ_VALUE(o, channelRetryTimeout); // NSTimeInterval
[self readValue]; // TODO READ_VALUE(o, transportParams); // property not found
[self readValue]; // TODO READ_VALUE(o, asyncHttpThreadpoolSize); // property not found
READ_VALUE(o, pushFullWait);
// [self readValue]; // TODO READ_VALUE(o, asyncHttpThreadpoolSize); // property not found
// READ_VALUE(o, pushFullWait);

return o;
}


-(ARTTokenDetails *)readTokenDeatils {
__block NSString *token = nil;
__block NSDate *expires = nil;
__block NSDate *issued = nil;
__block NSString *capability = nil;
__block NSString *clientId = nil;

ON_VALUE(^(const id value) { token = value; })
ON_VALUE(^(const id value) { expires = value; })
ON_VALUE(^(const id value) { issued = value; })
ON_VALUE(^(const id value) { capability = value; })
ON_VALUE(^(const id value) { clientId = value; })

ARTTokenDetails *const o = [ARTTokenDetails new];
[o initWithToken:token expires:expires issued:issued capability:capability clientId:clientId];
return o;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/src/codec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Codec extends StandardMessageCodec {

// ClientOptions
writeValue(buffer, v.clientId);
writeValue(buffer, v.logLevel.index);
writeValue(buffer, v.logLevel);
//TODO handle logHandler
writeValue(buffer, v.tls);
writeValue(buffer, v.restHost);
Expand Down Expand Up @@ -98,7 +98,7 @@ class Codec extends StandardMessageCodec {

// ClientOptions
v.clientId = readValue(buffer) as String;
v.logLevel = LogLevel.values[readValue(buffer) as int];
v.logLevel = readValue(buffer) as int;
//TODO handle logHandler
v.tls = readValue(buffer) as bool;
v.restHost = readValue(buffer) as String;
Expand Down
9 changes: 4 additions & 5 deletions lib/src/impl/rest/channels.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ class RestPlatformChannel extends PlatformObject implements spec.Channel{
@override
Future<void> publish([String name, dynamic data]) async {
try {
await this.invoke(PlatformMethod.publish, {
"channel": this.name,
"name": name,
"message": data
});
Map _map = { "channel": this.name, };
if(name!=null) _map["name"] = name;
if(data!=null) _map["message"] = data;
await this.invoke(PlatformMethod.publish, _map);
} on PlatformException catch (pe) {
throw spec.AblyException(pe.code, pe.message);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/src/spec/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class LogLevel{
static final int none = 99;
static final int verbose = 2;
static final int debug = 3;
static final int info = 4;
static final int warn = 5;
static final int error = 6;
}
8 changes: 0 additions & 8 deletions lib/src/spec/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,6 @@ enum HttpAuthType {
X_ABLY_TOKEN,
}

enum LogLevel{
none, //no logs
errors, //errors only
info, //errors and channel state changes
debug, //high-level debug output
verbose //full debug output
}

enum DevicePushState{
active,
failing,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/spec/rest/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ typedef void LogHandler({String msg, AblyException exception});
class ClientOptions extends AuthOptions {

ClientOptions(){
logLevel = LogLevel.info;
logLevel = 4;
}

ClientOptions.fromKey(String key): super.fromKey(key){
logLevel = LogLevel.info;
logLevel = 4;
}

///Optional clientId that can be used to specify the identity for this client.
Expand All @@ -65,7 +65,7 @@ class ClientOptions extends AuthOptions {

///Logger configuration
LogHandler logHandler; //optional
LogLevel logLevel; //optional
int logLevel; //optional

String restHost; //optional
String realtimeHost; //optional
Expand Down
1 change: 1 addition & 0 deletions lib/src/spec/spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export 'realtime/realtime.dart';
export 'push/push.dart';
export 'message.dart';
export 'common.dart';
export 'constants.dart';
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ dev_dependencies:

# Specifying a slightly older version minimum for the 'pure' Dart test package
# because the flutter_test package needs an older version of test_api.
test: ^1.9.4
test: ^1.14.2

# Stricter Linting
pedantic: ^1.0.0
pedantic: ^1.9.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down