Skip to content

Commit 51f1368

Browse files
author
Ali Abdelfattah
authored
Merge pull request #221 from Instabug/fix/ios-void-calls
[MOB-8369] Fix `void` calls on iOS
2 parents 614f593 + af1e7e6 commit 51f1368

File tree

9 files changed

+199
-131
lines changed

9 files changed

+199
-131
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## master
2+
3+
* Fixes iOS platform calls not completing with `void` return type
4+
15
## v10.11.0 (2022-01-04)
26

37
* Adds support for APM.endAppLaunch API

analysis_options.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ linter:
155155
- throw_in_finally
156156
# - type_annotate_public_apis # subset of always_specify_types
157157
- type_init_formals
158-
# - unawaited_futures # too many false positives
158+
- unawaited_futures
159159
# - unnecessary_await_in_return # not yet tested
160160
- unnecessary_brace_in_string_interps
161161
- unnecessary_const

example/ios/InstabugSampleTests/InstabugSampleTests.m

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,127 +15,189 @@ @interface InstabugSampleTests : XCTestCase
1515

1616
@implementation InstabugSampleTests
1717

18+
static const NSTimeInterval kTimeout = 30.0;
19+
1820
- (void)testShowWelcomeMessageWithMode {
1921
id mock = OCMClassMock([InstabugFlutterPlugin class]);
2022
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
21-
id result;
2223

2324
NSArray *arguments = [NSArray arrayWithObjects:@"WelcomeMessageMode.live", nil];
2425
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"showWelcomeMessageWithMode:" arguments:arguments];
2526
[[[mock stub] classMethod] showWelcomeMessageWithMode:@"WelcomeMessageMode.live"];
26-
[instabug handleMethodCall:call result:result];
27+
28+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
29+
[instabug handleMethodCall:call result:^(id _Nullable result) {
30+
XCTAssertNil(result);
31+
[expectation fulfill];
32+
}];
33+
2734
[[[mock verify] classMethod] showWelcomeMessageWithMode:@"WelcomeMessageMode.live"];
35+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
2836
}
2937

3038
- (void)testIdentifyUserWithEmail {
3139
id mock = OCMClassMock([InstabugFlutterPlugin class]);
3240
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
33-
id result;
3441

3542
NSArray *arguments = [NSArray arrayWithObjects:@"[email protected]", @"name", nil];
3643
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"identifyUserWithEmail:name:" arguments:arguments];
3744
[[[mock stub] classMethod] identifyUserWithEmail:@"[email protected]"name:@"name"];
38-
[instabug handleMethodCall:call result:result];
45+
46+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
47+
[instabug handleMethodCall:call result:^(id _Nullable result) {
48+
XCTAssertNil(result);
49+
[expectation fulfill];
50+
}];
51+
3952
[[[mock verify] classMethod] identifyUserWithEmail:@"[email protected]"name:@"name"];
53+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
4054
}
4155

4256
- (void)testLogOut {
4357
id mock = OCMClassMock([InstabugFlutterPlugin class]);
4458
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
45-
id result;
4659

4760
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"logOut" arguments:NULL];
4861
[[[mock stub] classMethod] logOut];
49-
[instabug handleMethodCall:call result:result];
62+
63+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
64+
[instabug handleMethodCall:call result:^(id _Nullable result) {
65+
XCTAssertNil(result);
66+
[expectation fulfill];
67+
}];
68+
5069
[[[mock verify] classMethod] logOut];
70+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
5171
}
5272

5373
- (void)testAppendTags {
5474
id mock = OCMClassMock([InstabugFlutterPlugin class]);
5575
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
56-
id result;
5776

5877
NSArray *tags = [NSArray arrayWithObjects:@"tag1", @"tag2", nil];
5978
NSArray *arguments = [NSArray arrayWithObjects: tags, nil];
6079
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"appendTags:" arguments:arguments];
6180
[[[mock stub] classMethod] appendTags:tags];
62-
[instabug handleMethodCall:call result:result];
81+
82+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
83+
[instabug handleMethodCall:call result:^(id _Nullable result) {
84+
XCTAssertNil(result);
85+
[expectation fulfill];
86+
}];
87+
6388
[[[mock verify] classMethod] appendTags:tags];
89+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
6490
}
6591

6692
- (void)testShowBugReportingWithReportTypeAndOptions {
6793
id mock = OCMClassMock([InstabugFlutterPlugin class]);
6894
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
69-
id result;
7095

7196
NSArray *options = [NSArray arrayWithObjects:@"commentFieldRequired", @"disablePostSendingDialog", nil];
7297
NSArray *arguments = [NSArray arrayWithObjects:@"bug", options, nil];
7398
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"showBugReportingWithReportTypeAndOptions:options:" arguments:arguments];
7499
[[[mock stub] classMethod] showBugReportingWithReportTypeAndOptions:@"bug"options:options];
75-
[instabug handleMethodCall:call result:result];
100+
101+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
102+
[instabug handleMethodCall:call result:^(id _Nullable result) {
103+
XCTAssertNil(result);
104+
[expectation fulfill];
105+
}];
106+
76107
[[[mock verify] classMethod] showBugReportingWithReportTypeAndOptions:@"bug"options:options];
108+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
77109
}
78110

79111
- (void)testSetSessionProfilerEnabled {
80112
id mock = OCMClassMock([InstabugFlutterPlugin class]);
81113
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
82-
id result;
83114

84115
NSArray *arguments = [NSArray arrayWithObjects:@(1), nil];
85116
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"setSessionProfilerEnabled:" arguments:arguments];
86117
[[[mock stub] classMethod] setSessionProfilerEnabled:@(1)];
87-
[instabug handleMethodCall:call result:result];
118+
119+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
120+
[instabug handleMethodCall:call result:^(id _Nullable result) {
121+
XCTAssertNil(result);
122+
[expectation fulfill];
123+
}];
124+
88125
[[[mock verify] classMethod] setSessionProfilerEnabled:@(1)];
126+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
89127
}
90128

91129
- (void)testSetPrimaryColor {
92130
id mock = OCMClassMock([InstabugFlutterPlugin class]);
93131
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
94-
id result;
95132

96133
NSArray *arguments = [NSArray arrayWithObjects:@(1123123123121), nil];
97134
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"setPrimaryColor:" arguments:arguments];
98135
[[[mock stub] classMethod] setPrimaryColor:@(1123123123121)];
99-
[instabug handleMethodCall:call result:result];
136+
137+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
138+
[instabug handleMethodCall:call result:^(id _Nullable result) {
139+
XCTAssertNil(result);
140+
[expectation fulfill];
141+
}];
142+
100143
[[[mock verify] classMethod] setPrimaryColor:@(1123123123121)];
144+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
101145
}
102146

103147
- (void)testAddFileAttachmentWithData {
104148
id mock = OCMClassMock([InstabugFlutterPlugin class]);
105149
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
106-
id result;
107150

108151
FlutterStandardTypedData *data;
109152
NSArray *arguments = [NSArray arrayWithObjects:data, nil];
110153
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"addFileAttachmentWithData:" arguments:arguments];
111154
[[[mock stub] classMethod] addFileAttachmentWithData:data];
112-
[instabug handleMethodCall:call result:result];
155+
156+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
157+
[instabug handleMethodCall:call result:^(id _Nullable result) {
158+
XCTAssertNil(result);
159+
[expectation fulfill];
160+
}];
161+
113162
[[[mock verify] classMethod] addFileAttachmentWithData:data];
163+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
114164
}
115165

116166
- (void)testSetEnabledAttachmentTypes {
117167
id mock = OCMClassMock([InstabugFlutterPlugin class]);
118168
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
119-
id result;
120169

121170
NSArray *arguments = [NSArray arrayWithObjects:@(1),@(1),@(1),@(1), nil];
122171
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"setEnabledAttachmentTypes:extraScreenShot:galleryImage:screenRecording:" arguments:arguments];
123172
[[[mock stub] classMethod] setEnabledAttachmentTypes:@(1) extraScreenShot:@(1) galleryImage:@(1) screenRecording:@(1) ];
124-
[instabug handleMethodCall:call result:result];
173+
174+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
175+
[instabug handleMethodCall:call result:^(id _Nullable result) {
176+
XCTAssertNil(result);
177+
[expectation fulfill];
178+
}];
179+
125180
[[[mock verify] classMethod] setEnabledAttachmentTypes:@(1) extraScreenShot:@(1) galleryImage:@(1) screenRecording:@(1)];
181+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
126182
}
127183

128184
- (void)testSetEmailFieldRequiredForFeatureRequests {
129185
id mock = OCMClassMock([InstabugFlutterPlugin class]);
130186
InstabugFlutterPlugin *instabug = [[InstabugFlutterPlugin alloc] init];
131-
id result;
132187

133188
NSArray *actions = [NSArray arrayWithObjects:@"reportBug", @"requestNewFeature", nil];
134189
NSArray *arguments = [NSArray arrayWithObjects:@(1), actions, nil];
135190
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"setEmailFieldRequiredForFeatureRequests:forAction:" arguments:arguments];
136191
[[[mock stub] classMethod] setEmailFieldRequiredForFeatureRequests:@(1) forAction:actions];
137-
[instabug handleMethodCall:call result:result];
192+
193+
XCTestExpectation *expectation = [self expectationWithDescription:@"Result is called"];
194+
[instabug handleMethodCall:call result:^(id _Nullable result) {
195+
XCTAssertNil(result);
196+
[expectation fulfill];
197+
}];
198+
138199
[[[mock verify] classMethod] setEmailFieldRequiredForFeatureRequests:@(1) forAction:actions];
200+
[self waitForExpectationsWithTimeout:kTimeout handler:nil];
139201
}
140202

141203

ios/Classes/InstabugFlutterPlugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@
428428
*
429429
* @param isEnabled whether chat notification is reburied or not
430430
*/
431-
- (void)setChatNotificationEnabled:(NSNumber *)isEnabled;
431+
+ (void)setChatNotificationEnabled:(NSNumber *)isEnabled;
432432

433433
+ (void)networkLog:(NSDictionary *)networkData;
434434

ios/Classes/InstabugFlutterPlugin.m

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,38 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
2020

2121
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
2222
BOOL isImplemented = NO;
23-
SEL method = NSSelectorFromString(call.method);
24-
if([[InstabugFlutterPlugin class] respondsToSelector:method]) {
23+
SEL method = NSSelectorFromString(call.method);
24+
if ([[InstabugFlutterPlugin class] respondsToSelector:method]) {
2525
isImplemented = YES;
2626
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[InstabugFlutterPlugin class] methodSignatureForSelector:method]];
2727
[inv setSelector:method];
2828
[inv setTarget:[InstabugFlutterPlugin class]];
2929
/*
3030
* Indices 0 and 1 indicate the hidden arguments self and _cmd,
31-
* respectively; you should set these values directly with the target and selector properties.
31+
* respectively; you should set these values directly with the target and selector properties.
3232
* Use indices 2 and greater for the arguments normally passed in a message.
3333
*/
3434
NSInteger index = 2;
3535
NSArray* argumentsArray = call.arguments;
3636
for (NSObject * argument in argumentsArray) {
37-
[inv setArgument:&(argument) atIndex:index];
38-
index++;
39-
}
37+
[inv setArgument:&argument atIndex:index];
38+
index++;
39+
}
4040
[inv invoke];
41-
NSMethodSignature *signature = [inv methodSignature];
42-
const char *type = [signature methodReturnType];
41+
NSMethodSignature *signature = [inv methodSignature];
42+
const char *type = [signature methodReturnType];
4343

44-
if (strcmp(type, "v") != 0) {
44+
if (strcmp(type, "v") != 0) {
4545
void *returnVal;
4646
[inv getReturnValue:&returnVal];
4747
NSObject *resultSet = (__bridge NSObject *)returnVal;
4848
result(resultSet);
49-
}
50-
}
49+
} else {
50+
result(nil);
51+
}
52+
}
5153
if (!isImplemented) {
52-
result(FlutterMethodNotImplemented);
54+
result(FlutterMethodNotImplemented);
5355
}
5456
}
5557

lib/APM.dart

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import 'dart:async';
44
import 'dart:io';
5+
56
import 'package:flutter/services.dart';
67
import 'package:instabug_flutter/models/network_data.dart';
78
import 'package:instabug_flutter/models/trace.dart';
@@ -32,21 +33,21 @@ class APM {
3233

3334
/// Enables or disables APM feature.
3435
/// [boolean] isEnabled
35-
static void setEnabled(bool isEnabled) async {
36+
static Future<void> setEnabled(bool isEnabled) async {
3637
final List<dynamic> params = <dynamic>[isEnabled];
3738
await _channel.invokeMethod<Object>('setAPMEnabled:', params);
3839
}
3940

4041
/// Sets log Level to determine level of details in a log
4142
/// [logLevel] Enum value to determine the level
42-
static void setLogLevel(LogLevel logLevel) async {
43+
static Future<void> setLogLevel(LogLevel logLevel) async {
4344
final List<dynamic> params = <dynamic>[logLevel.toString()];
4445
await _channel.invokeMethod<Object>('setAPMLogLevel:', params);
4546
}
4647

4748
/// Enables or disables cold app launch tracking.
4849
/// [boolean] isEnabled
49-
static void setColdAppLaunchEnabled(bool isEnabled) async {
50+
static Future<void> setColdAppLaunchEnabled(bool isEnabled) async {
5051
final List<dynamic> params = <dynamic>[isEnabled];
5152
await _channel.invokeMethod<Object>('setColdAppLaunchEnabled:', params);
5253
}
@@ -69,15 +70,15 @@ class APM {
6970
}
7071
};
7172
_startExecutionTraceCallback = callback;
72-
_channel.invokeMethod<Object>('startExecutionTrace:id:', params);
73+
await _channel.invokeMethod<Object>('startExecutionTrace:id:', params);
7374
return completer.future;
7475
}
7576

7677
/// Sets attribute of an execution trace.
7778
/// [String] id of the trace.
7879
/// [String] key of attribute.
7980
/// [String] value of attribute.
80-
static void setExecutionTraceAttribute(
81+
static Future<void> setExecutionTraceAttribute(
8182
String id, String key, String value) async {
8283
final List<dynamic> params = <dynamic>[
8384
id.toString(),
@@ -90,27 +91,27 @@ class APM {
9091

9192
/// Ends an execution trace.
9293
/// [String] id of the trace.
93-
static void endExecutionTrace(String id) async {
94+
static Future<void> endExecutionTrace(String id) async {
9495
final List<dynamic> params = <dynamic>[id];
9596
await _channel.invokeMethod<Object>('endExecutionTrace:', params);
9697
}
9798

9899
/// Enables or disables auto UI tracing.
99100
/// [boolean] isEnabled
100-
static void setAutoUITraceEnabled(bool isEnabled) async {
101+
static Future<void> setAutoUITraceEnabled(bool isEnabled) async {
101102
final List<dynamic> params = <dynamic>[isEnabled];
102103
await _channel.invokeMethod<Object>('setAutoUITraceEnabled:', params);
103104
}
104105

105106
/// Starts UI trace.
106107
/// [String] name
107-
static void startUITrace(String name) async {
108+
static Future<void> startUITrace(String name) async {
108109
final List<dynamic> params = <dynamic>[name];
109110
await _channel.invokeMethod<Object>('startUITrace:', params);
110111
}
111112

112113
/// Ends UI trace.
113-
static void endUITrace() async {
114+
static Future<void> endUITrace() async {
114115
await _channel.invokeMethod<Object>('endUITrace');
115116
}
116117
/// Ends UI trace.

lib/CrashReporting.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class CrashReporting {
2626

2727
static Future<void> reportCrash(dynamic exception, StackTrace stack) async {
2828
if (kReleaseMode && enabled) {
29-
_reportUnhandledCrash(exception, stack);
29+
await _reportUnhandledCrash(exception, stack);
3030
} else {
3131
FlutterError.dumpErrorToConsole(
3232
FlutterErrorDetails(stack: stack, exception: exception));
@@ -38,12 +38,12 @@ class CrashReporting {
3838
/// [StackTrace] stack
3939
static Future<void> reportHandledCrash(dynamic exception,
4040
[StackTrace? stack]) async {
41-
_sendCrash(exception, stack ?? StackTrace.current, true);
41+
await _sendCrash(exception, stack ?? StackTrace.current, true);
4242
}
4343

4444
static Future<void> _reportUnhandledCrash(
4545
dynamic exception, StackTrace stack) async {
46-
_sendCrash(exception, stack, false);
46+
await _sendCrash(exception, stack, false);
4747
}
4848

4949
static Future<void> _sendCrash(

0 commit comments

Comments
 (0)