Skip to content

Commit dd37806

Browse files
authored
Merge pull request #898 from Microsoft/develop
Release 1.2.0
2 parents 0eaa394 + 543b8f9 commit dd37806

File tree

131 files changed

+4709
-2632
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+4709
-2632
lines changed

AppCenter.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'AppCenter'
3-
s.version = '1.1.0'
3+
s.version = '1.2.0'
44

55
s.summary = 'Visual Studio App Center is your continuous integration, delivery and learning solution for iOS and macOS apps.'
66
s.description = <<-DESC
@@ -25,6 +25,7 @@ Pod::Spec.new do |s|
2525

2626
s.homepage = 'https://appcenter.ms'
2727
s.documentation_url = "https://docs.microsoft.com/en-us/appcenter/sdk"
28+
s.social_media_url = 'https://twitter.com/vsappcenter'
2829

2930
s.license = { :type => 'MIT', :file => 'AppCenter-SDK-Apple/iOS/LICENSE' }
3031
s.author = { 'Microsoft' => '[email protected]' }

AppCenter/AppCenter.xcodeproj/project.pbxproj

Lines changed: 68 additions & 10 deletions
Large diffs are not rendered by default.

AppCenter/AppCenter/Internals/AppDelegate/MSAppDelegateForwarder.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
#import <Foundation/Foundation.h>
2-
#if TARGET_OS_OSX
3-
#import "MSNSAppDelegate.h"
4-
#else
5-
#import "MSUIAppDelegate.h"
6-
#endif
1+
#import "MSCustomApplicationDelegate.h"
72

83
NS_ASSUME_NONNULL_BEGIN
94

10-
@interface MSAppDelegateForwarder : NSObject <MSAppDelegate>
5+
/**
6+
* Enum used to represent all kind of executors running the completion handler.
7+
*/
8+
typedef NS_OPTIONS(NSUInteger, MSCompletionExecutor) {
9+
MSCompletionExecutorNone = (1 << 0),
10+
MSCompletionExecutorOriginal = (1 << 1),
11+
MSCompletionExecutorCustom = (1 << 2),
12+
MSCompletionExecutorForwarder = (1 << 3)
13+
};
14+
15+
@interface MSAppDelegateForwarder : NSObject <MSCustomApplicationDelegate>
1116

1217
/**
1318
* Enable/Disable Application forwarding.
@@ -19,14 +24,14 @@ NS_ASSUME_NONNULL_BEGIN
1924
*
2025
* @param delegate A delegate.
2126
*/
22-
+ (void)addDelegate:(id<MSAppDelegate>)delegate;
27+
+ (void)addDelegate:(id<MSCustomApplicationDelegate>)delegate;
2328

2429
/**
2530
* Remove a delegate. This method is thread safe.
2631
*
2732
* @param delegate A delegate.
2833
*/
29-
+ (void)removeDelegate:(id<MSAppDelegate>)delegate;
34+
+ (void)removeDelegate:(id<MSCustomApplicationDelegate>)delegate;
3035

3136
/**
3237
* Add an app delegate selector to swizzle.

AppCenter/AppCenter/Internals/AppDelegate/MSAppDelegateForwarder.m

Lines changed: 10 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
#import <Foundation/Foundation.h>
21
#import <objc/runtime.h>
3-
#if TARGET_OS_OSX
4-
#import <AppKit/AppKit.h>
5-
#import "MSNSAppDelegate.h"
6-
#else
7-
#import <UIKit/UIKit.h>
8-
#import "MSUIAppDelegate.h"
9-
#endif
102

3+
#import "MSCustomApplicationDelegate.h"
114
#import "MSAppDelegateForwarderPrivate.h"
125
#import "MSAppCenterInternal.h"
136
#import "MSLogger.h"
@@ -18,14 +11,11 @@
1811
static NSString *const kMSIsAppDelegateForwarderEnabledKey = @"AppCenterAppDelegateForwarderEnabled";
1912

2013
// Original selectors with special handling.
21-
static NSString *const kMSDidReceiveRemoteNotificationFetchHandler =
22-
@"application:didReceiveRemoteNotification:fetchCompletionHandler:";
2314
static NSString *const kMSOpenURLSourceApplicationAnnotation = @"application:openURL:sourceApplication:annotation:";
2415
static NSString *const kMSOpenURLOptions = @"application:openURL:options:";
2516

26-
static NSHashTable<id<MSAppDelegate>> *_delegates = nil;
17+
static NSHashTable<id<MSCustomApplicationDelegate>> *_delegates = nil;
2718
static NSMutableSet<NSString *> *_selectorsToSwizzle = nil;
28-
static NSArray<NSString *> *_selectorsNotToOverride = nil;
2919
static NSDictionary<NSString *, NSString *> *_deprecatedSelectors = nil;
3020
static NSMutableDictionary<NSString *, NSValue *> *_originalImplementations = nil;
3121
static NSMutableArray<dispatch_block_t> *traceBuffer = nil;
@@ -75,27 +65,18 @@ + (instancetype)sharedInstance {
7565

7666
#pragma mark - Accessors
7767

78-
+ (NSHashTable<id<MSAppDelegate>> *)delegates {
68+
+ (NSHashTable<id<MSCustomApplicationDelegate>> *)delegates {
7969
return _delegates ?: (_delegates = [NSHashTable weakObjectsHashTable]);
8070
}
8171

82-
+ (void)setDelegates:(NSHashTable<id<MSAppDelegate>> *)delegates {
72+
+ (void)setDelegates:(NSHashTable<id<MSCustomApplicationDelegate>> *)delegates {
8373
_delegates = delegates;
8474
}
8575

8676
+ (NSMutableSet<NSString *> *)selectorsToSwizzle {
8777
return _selectorsToSwizzle ?: (_selectorsToSwizzle = [NSMutableSet new]);
8878
}
8979

90-
+ (NSArray<NSString *> *)selectorsNotToOverride {
91-
if (!_selectorsNotToOverride) {
92-
#if !TARGET_OS_OSX
93-
_selectorsNotToOverride = @[ kMSDidReceiveRemoteNotificationFetchHandler ];
94-
#endif
95-
}
96-
return _selectorsNotToOverride;
97-
}
98-
9980
+ (NSDictionary<NSString *, NSString *> *)deprecatedSelectors {
10081
if (!_deprecatedSelectors) {
10182
#if TARGET_OS_OSX
@@ -152,15 +133,15 @@ + (void)setEnabled:(BOOL)enabled {
152133

153134
#pragma mark - Delegates
154135

155-
+ (void)addDelegate:(id<MSAppDelegate>)delegate {
136+
+ (void)addDelegate:(id<MSCustomApplicationDelegate>)delegate {
156137
@synchronized(self) {
157138
if (self.enabled) {
158139
[self.delegates addObject:delegate];
159140
}
160141
}
161142
}
162143

163-
+ (void)removeDelegate:(id<MSAppDelegate>)delegate {
144+
+ (void)removeDelegate:(id<MSCustomApplicationDelegate>)delegate {
164145
@synchronized(self) {
165146
if (self.enabled) {
166147
[self.delegates removeObject:delegate];
@@ -184,8 +165,7 @@ + (void)swizzleOriginalDelegate:(id<MSApplicationDelegate>)originalDelegate {
184165
if (originalImp) {
185166

186167
// Save the original implementation for later use.
187-
MSAppDelegateForwarder.originalImplementations[selectorString] =
188-
[NSValue valueWithBytes:&originalImp objCType:@encode(IMP)];
168+
self.originalImplementations[selectorString] = [NSValue valueWithBytes:&originalImp objCType:@encode(IMP)];
189169
}
190170
}
191171
[self.selectorsToSwizzle removeAllObjects];
@@ -208,18 +188,7 @@ + (IMP)swizzleOriginalSelector:(SEL)originalSelector
208188

209189
// Replace original implementation by the custom one.
210190
if (originalMethod) {
211-
212-
/*
213-
* Also, some selectors should not be overridden mostly because the original implementation highly
214-
* depend on the SDK return value for its own logic so customers already have to call the SDK API
215-
* in their implementation which makes swizzling useless.
216-
*/
217-
if (![self.selectorsNotToOverride containsObject:originalSelectorStr]) {
218-
originalImp = method_setImplementation(originalMethod, customImp);
219-
} else {
220-
warningMsg =
221-
[NSString stringWithFormat:@"This selector is not supported when already implemented. %@", remediationMsg];
222-
}
191+
originalImp = method_setImplementation(originalMethod, customImp);
223192
} else if (![originalClass instancesRespondToSelector:originalSelector]) {
224193

225194
// Check for deprecation.
@@ -326,6 +295,7 @@ - (void)custom_setDelegate:(id<MSApplicationDelegate>)delegate {
326295
#pragma mark - Custom UIApplicationDelegate
327296

328297
#if !TARGET_OS_OSX
298+
329299
/*
330300
* Those methods will never get called but their implementation will be used by swizzling.
331301
* Those implementations will run within the delegate context. Meaning that `self` will point
@@ -375,103 +345,6 @@ - (BOOL)custom_application:(UIApplication *)application
375345
}
376346
#endif
377347

378-
#if TARGET_OS_OSX
379-
- (void)custom_application:(NSApplication *)application
380-
#else
381-
- (void)custom_application:(UIApplication *)application
382-
#endif
383-
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
384-
IMP originalImp = NULL;
385-
386-
// Forward to the original delegate.
387-
[MSAppDelegateForwarder.originalImplementations[NSStringFromSelector(_cmd)] getValue:&originalImp];
388-
if (originalImp) {
389-
#if TARGET_OS_OSX
390-
((void (*)(id, SEL, NSApplication *, NSData *))originalImp)(self, _cmd, application, deviceToken);
391-
#else
392-
((void (*)(id, SEL, UIApplication *, NSData *))originalImp)(self, _cmd, application, deviceToken);
393-
#endif
394-
}
395-
396-
// Forward to custom delegates.
397-
[[MSAppDelegateForwarder sharedInstance] application:application
398-
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
399-
}
400-
401-
#if TARGET_OS_OSX
402-
- (void)custom_application:(NSApplication *)application
403-
#else
404-
- (void)custom_application:(UIApplication *)application
405-
#endif
406-
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
407-
IMP originalImp = NULL;
408-
409-
// Forward to the original delegate.
410-
[MSAppDelegateForwarder.originalImplementations[NSStringFromSelector(_cmd)] getValue:&originalImp];
411-
if (originalImp) {
412-
#if TARGET_OS_OSX
413-
((void (*)(id, SEL, NSApplication *, NSError *))originalImp)(self, _cmd, application, error);
414-
#else
415-
((void (*)(id, SEL, UIApplication *, NSError *))originalImp)(self, _cmd, application, error);
416-
#endif
417-
}
418-
419-
// Forward to custom delegates.
420-
[[MSAppDelegateForwarder sharedInstance] application:application
421-
didFailToRegisterForRemoteNotificationsWithError:error];
422-
}
423-
424-
#if TARGET_OS_OSX
425-
- (void)custom_application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
426-
#else
427-
- (void)custom_application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
428-
#endif
429-
IMP originalImp = NULL;
430-
431-
// Forward to the original delegate.
432-
[MSAppDelegateForwarder.originalImplementations[NSStringFromSelector(_cmd)] getValue:&originalImp];
433-
if (originalImp) {
434-
#if TARGET_OS_OSX
435-
((void (*)(id, SEL, NSApplication *, NSDictionary *))originalImp)(self, _cmd, application, userInfo);
436-
#else
437-
((void (*)(id, SEL, UIApplication *, NSDictionary *))originalImp)(self, _cmd, application, userInfo);
438-
#endif
439-
}
440-
441-
// Forward to custom delegates.
442-
[[MSAppDelegateForwarder sharedInstance] application:application didReceiveRemoteNotification:userInfo];
443-
}
444-
445-
#if !TARGET_OS_OSX
446-
- (void)custom_application:(UIApplication *)application
447-
didReceiveRemoteNotification:(NSDictionary *)userInfo
448-
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
449-
450-
// Collect `UIBackgroundFetchResult` from delegates in order to call the original completion handler later.
451-
__block UIBackgroundFetchResult forwardedFetchResult = UIBackgroundFetchResultNoData;
452-
void (^forwardedCompletionHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult fetchResult) {
453-
forwardedFetchResult = fetchResult;
454-
};
455-
456-
/*
457-
* FIXME: We still need to chain the forwardedFetchResult somehow in case of multiple custom delegate implementing
458-
* this selector.
459-
*/
460-
461-
/*
462-
* Forward to custom delegates. This method doesn't override original the delegate implementation so there is no need
463-
* to forward to the original implementation. As a consequence customers must call the corresponding APIs in the SDK
464-
* if they implement this selector in their delegate.
465-
*/
466-
[[MSAppDelegateForwarder sharedInstance] application:application
467-
didReceiveRemoteNotification:userInfo
468-
fetchCompletionHandler:forwardedCompletionHandler];
469-
470-
// Must call the original completion handler.
471-
completionHandler(forwardedFetchResult);
472-
}
473-
#endif
474-
475348
#pragma mark - Forwarding
476349

477350
- (void)forwardInvocation:(NSInvocation *)invocation {
@@ -490,7 +363,7 @@ - (void)forwardInvocation:(NSInvocation *)invocation {
490363
}
491364

492365
// Forward to delegates executing a custom method.
493-
for (id<MSAppDelegate> delegate in [self class].delegates) {
366+
for (id<MSCustomApplicationDelegate> delegate in [self class].delegates) {
494367
if ([delegate respondsToSelector:invocation.selector]) {
495368
[invocation invokeWithTarget:delegate];
496369

AppCenter/AppCenter/Internals/AppDelegate/MSAppDelegateForwarderPrivate.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#import <Foundation/Foundation.h>
2-
31
#import "MSAppDelegateForwarder.h"
42

53
NS_ASSUME_NONNULL_BEGIN
@@ -9,18 +7,13 @@ NS_ASSUME_NONNULL_BEGIN
97
/**
108
* Hash table containing all the delegates as weak references.
119
*/
12-
@property(nonatomic, class) NSHashTable<id<MSAppDelegate>> *delegates;
10+
@property(nonatomic, class) NSHashTable<id<MSCustomApplicationDelegate>> *delegates;
1311

1412
/**
1513
* Keep track of original selectors to swizzle.
1614
*/
1715
@property(nonatomic, class, readonly) NSMutableSet<NSString *> *selectorsToSwizzle;
1816

19-
/**
20-
* List of original selectors not to override if already implemented in the original application delegate.
21-
*/
22-
@property(nonatomic, class, readonly) NSArray<NSString *> *selectorsNotToOverride;
23-
2417
/**
2518
* Dictionary of deprecated original selectors indexed by their new equivalent.
2619
*/
@@ -42,6 +35,11 @@ NS_ASSUME_NONNULL_BEGIN
4235
#endif
4336
@property(nonatomic, class) IMP originalSetDelegateImp;
4437

38+
/**
39+
* Returns the singleton instance of MSAppDelegateForwarder.
40+
*/
41+
+ (instancetype)sharedInstance;
42+
4543
/**
4644
* Register swizzling for the given original application delegate.
4745
*
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#import <Foundation/Foundation.h>
2+
#if TARGET_OS_OSX
3+
#import <AppKit/AppKit.h>
4+
#ifndef MSApplicationDelegate
5+
#define MSApplicationDelegate NSApplicationDelegate
6+
#endif
7+
#ifndef MSApplication
8+
#define MSApplication NSApplication
9+
#endif
10+
#else
11+
#import <UIKit/UIKit.h>
12+
#ifndef MSApplicationDelegate
13+
#define MSApplicationDelegate UIApplicationDelegate
14+
#endif
15+
#ifndef MSApplication
16+
#define MSApplication UIApplication
17+
#endif
18+
#endif
19+

0 commit comments

Comments
 (0)