mirror of
https://github.com/zhigang1992/facebook-ios-sdk.git
synced 2026-01-12 22:47:16 +08:00
Add AAM to FBSDKCoreKit
Summary: Add AAM to FBSDKCoreKit along with changes in podspec and BUCK Reviewed By: tianqibt Differential Revision: D17532337 fbshipit-source-id: 770f421602ba8757dce4db3cebf4091605e0169d
This commit is contained in:
committed by
Facebook Github Bot
parent
d3ed4b996e
commit
9d1df4e172
@@ -66,7 +66,8 @@ Pod::Spec.new do |s|
|
||||
'FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.{h,m}',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/Internal/Device/**/*',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/Swift/**/*'
|
||||
ss.tvos.exclude_files = 'FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/*',
|
||||
ss.tvos.exclude_files = 'FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/*',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/*',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKHybridAppEventsScriptMessageHandler.{h,m}',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/AppLink/**/*',
|
||||
'FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.{h,m}',
|
||||
|
||||
@@ -1270,6 +1270,13 @@
|
||||
F92F8F8B22BA275B00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; };
|
||||
F92F8F8C22BA275C00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; };
|
||||
F92F8F8D22BA275D00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; };
|
||||
F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; };
|
||||
F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; };
|
||||
F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; };
|
||||
F952EA4A2339405F00B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; };
|
||||
F952EA4B2339406400B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; };
|
||||
F952EA4C2339406500B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; };
|
||||
F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */; };
|
||||
F96ADE7A21E6ABB400F6043F /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F96ADE6321E6ABB400F6043F /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
F9FD9A6221659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */; };
|
||||
F9FD9A6321659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */; };
|
||||
@@ -1734,6 +1741,9 @@
|
||||
F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKUserDataStore.m; sourceTree = "<group>"; };
|
||||
F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSessionTask.h; sourceTree = "<group>"; };
|
||||
F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSessionTask.m; sourceTree = "<group>"; };
|
||||
F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexer.m; sourceTree = "<group>"; };
|
||||
F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMetadataIndexer.h; sourceTree = "<group>"; };
|
||||
F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexerTests.m; sourceTree = "<group>"; };
|
||||
F96ADE6321E6ABB400F6043F /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKGateKeeperManager.h; sourceTree = "<group>"; };
|
||||
F9FD9A7C21659F320068DEAF /* FBSDKGateKeeperManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGateKeeperManager.m; sourceTree = "<group>"; };
|
||||
@@ -2238,6 +2248,7 @@
|
||||
9D18A8D91A95403F00A41042 /* AppEvents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F952EA4D2339412C00B20652 /* AAM */,
|
||||
C51121C720A27EF50041DC94 /* Codeless */,
|
||||
9D18A8DA1A95405A00A41042 /* FBSDKAppEventsStateTests.m */,
|
||||
9D18A8E81A95495D00A41042 /* FBSDKAppEventsUtilityTests.m */,
|
||||
@@ -2456,6 +2467,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5D9031C0233AAC5D0001450C /* RestrictiveDataFilter */,
|
||||
F952EA442339403900B20652 /* AAM */,
|
||||
C5696F1D209BBC35009C931F /* Codeless */,
|
||||
9D0BC1531A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h */,
|
||||
5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */,
|
||||
@@ -2559,6 +2571,23 @@
|
||||
path = Swift;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F952EA442339403900B20652 /* AAM */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */,
|
||||
F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */,
|
||||
);
|
||||
path = AAM;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F952EA4D2339412C00B20652 /* AAM */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */,
|
||||
);
|
||||
path = AAM;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FD2A237F22FBF7A700DC928F /* ErrorReport */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -2678,6 +2707,7 @@
|
||||
C5696F94209BBC35009C931F /* FBSDKEventBinding.h in Headers */,
|
||||
C5C4B3EE2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */,
|
||||
81B71D531D19C87400933E93 /* FBSDKGraphErrorRecoveryProcessor.h in Headers */,
|
||||
F952EA4B2339406400B20652 /* FBSDKMetadataIndexer.h in Headers */,
|
||||
52963A89215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.h in Headers */,
|
||||
81B71D551D19C87400933E93 /* FBSDKBase64.h in Headers */,
|
||||
81B71D571D19C87400933E93 /* FBSDKAppEventsUtility.h in Headers */,
|
||||
@@ -2802,6 +2832,7 @@
|
||||
C5C4B3ED2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */,
|
||||
9D3AF4501A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h in Headers */,
|
||||
9D0BC1511A8D236200BE8BA4 /* FBSDKTimeSpentData.h in Headers */,
|
||||
F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */,
|
||||
891687D21AB33CA200F55364 /* FBSDKIcon.h in Headers */,
|
||||
52963A92215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.h in Headers */,
|
||||
52963AA82159A13400C7B252 /* FBSDKMeasurementEvent_Internal.h in Headers */,
|
||||
@@ -3222,6 +3253,7 @@
|
||||
F487DB75231EBCD2008416A9 /* FBSDKHybridAppEventsScriptMessageHandler.h in Headers */,
|
||||
F487DB76231EBCD2008416A9 /* FBSDKWebViewAppLinkResolver.h in Headers */,
|
||||
5D9A705D23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */,
|
||||
F952EA4C2339406500B20652 /* FBSDKMetadataIndexer.h in Headers */,
|
||||
F487DB77231EBCD2008416A9 /* FBSDKBridgeAPIProtocolWebV2.h in Headers */,
|
||||
F487DB78231EBCD2008416A9 /* FBSDKInternalUtility.h in Headers */,
|
||||
F487DB79231EBCD2008416A9 /* FBSDKConstants.h in Headers */,
|
||||
@@ -3958,6 +3990,7 @@
|
||||
52D4F0BC1D91A18D0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */,
|
||||
81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */,
|
||||
81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */,
|
||||
F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */,
|
||||
81B71D441D19C87400933E93 /* FBSDKMaleSilhouetteIcon.m in Sources */,
|
||||
C5C7B74F22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */,
|
||||
C554DB0B2304D11200A32E8B /* FBSDKErrorReport.m in Sources */,
|
||||
@@ -4058,6 +4091,7 @@
|
||||
520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */,
|
||||
9DE1F3CE1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m in Sources */,
|
||||
89830F301A7805E100226ABB /* FBSDKServerConfiguration.m in Sources */,
|
||||
F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */,
|
||||
FD8E438122FBF8F1008B6DD3 /* FBSDKErrorReport.m in Sources */,
|
||||
899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */,
|
||||
C5C7B74E22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */,
|
||||
@@ -4086,6 +4120,7 @@
|
||||
89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */,
|
||||
C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.m in Sources */,
|
||||
5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */,
|
||||
F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */,
|
||||
5D68D7D822BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m in Sources */,
|
||||
9D3AF4661A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m in Sources */,
|
||||
C51122A020A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m in Sources */,
|
||||
@@ -4412,6 +4447,7 @@
|
||||
F487DB2E231EBCD2008416A9 /* FBSDKURLSession.m in Sources */,
|
||||
F487DB30231EBCD2008416A9 /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */,
|
||||
F487DB31231EBCD2008416A9 /* FBSDKMeasurementEvent.m in Sources */,
|
||||
F952EA4A2339405F00B20652 /* FBSDKMetadataIndexer.m in Sources */,
|
||||
F487DB32231EBCD2008416A9 /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */,
|
||||
5D9A709D2326EB5E00BF9783 /* FBSDKCrashObserver.m in Sources */,
|
||||
F487DB33231EBCD2008416A9 /* FBSDKWebDialogView.m in Sources */,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKMetadataIndexer : NSObject
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,331 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKMetadataIndexer.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import <sys/sysctl.h>
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit+Internal.h>
|
||||
|
||||
static const int FBSDKMetadataIndexerMaxTextLength = 100;
|
||||
static const int FBSDKMetadataIndexerMaxIndicatorLength = 100;
|
||||
static const int FBSDKMetadataIndexerMaxValue = 5;
|
||||
|
||||
static NSString * const FIELD_K = @"k";
|
||||
static NSString * const FIELD_V = @"v";
|
||||
static NSString * const FIELD_K_DELIMITER = @",";
|
||||
|
||||
FBSDKAppEventUserDataType FBSDKAppEventRule1 = @"r1";
|
||||
FBSDKAppEventUserDataType FBSDKAppEventRule2 = @"r2";
|
||||
|
||||
static NSMutableDictionary<NSString *, NSDictionary<NSString *, NSString *> *> *FBSDKMetadataIndexerRules;
|
||||
static NSMutableDictionary<NSString *, NSMutableArray<NSString *> *> *FBSDKMetadataIndexerStore;
|
||||
static dispatch_queue_t serialQueue;
|
||||
|
||||
@implementation FBSDKMetadataIndexer
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
serialQueue = dispatch_queue_create("com.facebook.appevents.MetadataIndexer", DISPATCH_QUEUE_SERIAL);
|
||||
}
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
[self initStore];
|
||||
[self loadAndSetup];
|
||||
}
|
||||
|
||||
+ (void)initStore
|
||||
{
|
||||
FBSDKMetadataIndexerStore = [[NSMutableDictionary alloc] init];
|
||||
NSString *userData = [[NSUserDefaults standardUserDefaults] stringForKey:@"com.facebook.appevents.UserDataStore.userData"];
|
||||
if (userData) {
|
||||
NSMutableDictionary<NSString *, NSString *> * hashedUserData = (NSMutableDictionary<NSString *, NSString *> *)[NSJSONSerialization JSONObjectWithData:[userData dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:NSJSONReadingMutableContainers
|
||||
error:nil];
|
||||
for (NSString *key in FBSDKMetadataIndexerRules) {
|
||||
if (hashedUserData[key].length > 0) {
|
||||
FBSDKMetadataIndexerStore[key] = [NSMutableArray arrayWithArray:[hashedUserData[key] componentsSeparatedByString:FIELD_K_DELIMITER]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (NSString *key in FBSDKMetadataIndexerRules) {
|
||||
if (!FBSDKMetadataIndexerStore[key]) {
|
||||
FBSDKMetadataIndexerStore[key] = [[NSMutableArray alloc] init];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)loadAndSetup
|
||||
{
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
|
||||
initWithGraphPath:[NSString stringWithFormat:@"%@?fields=aam_rules", [FBSDKSettings appID]]
|
||||
HTTPMethod:FBSDKHTTPMethodGET];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([result isKindOfClass:[NSDictionary class]]) {
|
||||
NSString *json = [(NSDictionary *)result objectForKey:@"aam_rules"];
|
||||
if (json) {
|
||||
[FBSDKMetadataIndexer constructRules:[FBSDKBasicUtility objectForJSONString:json error:nil]];
|
||||
BOOL isR1Enabled = (nil != [FBSDKMetadataIndexerRules objectForKey:FBSDKAppEventRule1]);
|
||||
BOOL isR2Enabled = (nil != [FBSDKMetadataIndexerRules objectForKey:FBSDKAppEventRule2]);
|
||||
if (!isR1Enabled) {
|
||||
[FBSDKMetadataIndexerStore removeObjectForKey:FBSDKAppEventRule1];
|
||||
[FBSDKUserDataStore setHashData:nil forType:FBSDKAppEventRule1];
|
||||
}
|
||||
if (!isR2Enabled) {
|
||||
[FBSDKMetadataIndexerStore removeObjectForKey:FBSDKAppEventRule2];
|
||||
[FBSDKUserDataStore setHashData:nil forType:FBSDKAppEventRule2];
|
||||
}
|
||||
if (isR1Enabled || isR2Enabled) {
|
||||
[self setupMetadataIndexing];
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)constructRules:(NSDictionary<NSString *, id> *)rules
|
||||
{
|
||||
if (!FBSDKMetadataIndexerRules) {
|
||||
FBSDKMetadataIndexerRules = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
for (NSString *key in rules) {
|
||||
NSDictionary<NSString *, NSString *> *value = [self dictionaryValueOf:rules[key]];
|
||||
if (value && value[FIELD_K].length > 0 && value[FIELD_V].length > 0) {
|
||||
FBSDKMetadataIndexerRules[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setupMetadataIndexing
|
||||
{
|
||||
void (^block)(UIView *) = ^(UIView *view) {
|
||||
// Indexing when the view is removed from window and conforms to UITextInput, and skip UIFieldEditor, which is an internval view of UITextField
|
||||
if (![view window] && ![NSStringFromClass([view class]) isEqualToString:@"UIFieldEditor"] && [view conformsToProtocol:@protocol(UITextInput)]) {
|
||||
NSString *text = [FBSDKViewHierarchy getText:view];
|
||||
NSString *placeholder = [FBSDKViewHierarchy getHint:view];
|
||||
BOOL secureTextEntry = [self checkSecureTextEntry:view];
|
||||
NSArray<NSString *> *labels = [self getLabelsOfView:view];
|
||||
UIKeyboardType keyboardType = [self getKeyboardType:view];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
|
||||
[self getMetadataWithText:[self normalizedValue:text]
|
||||
placeholder:[self normalizeField:placeholder]
|
||||
labels:labels
|
||||
secureTextEntry:secureTextEntry
|
||||
inputType:keyboardType];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UIView class] withBlock:block named:@"metadataIndexingUIView"];
|
||||
|
||||
// iOS 12: UITextField implements didMoveToWindow without calling parent implementation
|
||||
if (@available(iOS 12, *)) {
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UITextField class] withBlock:block named:@"metadataIndexingUITextField"];
|
||||
} else {
|
||||
[FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UIControl class] withBlock:block named:@"metadataIndexingUIControl"];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSArray<UIView *> *)getSiblingViewsOfView:(UIView *)view
|
||||
{
|
||||
NSObject *parent = [FBSDKViewHierarchy getParent:view];
|
||||
if (parent) {
|
||||
NSArray<id> *views = [FBSDKViewHierarchy getChildren:parent];
|
||||
if (views) {
|
||||
NSMutableArray<id> *siblings = [NSMutableArray arrayWithArray:views];
|
||||
[siblings removeObject:view];
|
||||
return [siblings copy];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)getLabelsOfView:(UIView *)view
|
||||
{
|
||||
NSMutableArray<NSString *> *labels = [[NSMutableArray alloc] init];
|
||||
|
||||
NSString *placeholder = [self normalizeField:[FBSDKViewHierarchy getHint:view]];
|
||||
if (placeholder) {
|
||||
[labels addObject:placeholder];
|
||||
}
|
||||
|
||||
NSArray<id> *siblingViews = [self getSiblingViewsOfView:view];
|
||||
for (id sibling in siblingViews) {
|
||||
if ([sibling isKindOfClass:[UILabel class]]) {
|
||||
NSString *text = [self normalizeField:[FBSDKViewHierarchy getText:sibling]];
|
||||
if (text) {
|
||||
[labels addObject:text];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [labels copy];
|
||||
}
|
||||
|
||||
+ (BOOL)checkSecureTextEntry:(UIView *)view
|
||||
{
|
||||
if ([view isKindOfClass:[UITextField class]]) {
|
||||
return ((UITextField *)view).secureTextEntry;
|
||||
}
|
||||
if ([view isKindOfClass:[UITextView class]]) {
|
||||
return ((UITextView *)view).secureTextEntry;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (UIKeyboardType)getKeyboardType:(UIView *)view
|
||||
{
|
||||
if ([view isKindOfClass:[UITextField class]]) {
|
||||
return ((UITextField *)view).keyboardType;
|
||||
}
|
||||
if ([view isKindOfClass:[UITextView class]]) {
|
||||
return ((UITextView *)view).keyboardType;
|
||||
}
|
||||
|
||||
return UIKeyboardTypeDefault;
|
||||
}
|
||||
|
||||
+ (void)getMetadataWithText:(NSString *)text
|
||||
placeholder:(NSString *)placeholder
|
||||
labels:(NSArray<NSString *> *)labels
|
||||
secureTextEntry:(BOOL)secureTextEntry
|
||||
inputType:(UIKeyboardType)inputType
|
||||
{
|
||||
if (secureTextEntry ||
|
||||
[placeholder containsString:@"password"] ||
|
||||
text.length == 0 ||
|
||||
text.length > FBSDKMetadataIndexerMaxTextLength ||
|
||||
placeholder.length >= FBSDKMetadataIndexerMaxIndicatorLength) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (NSString *key in FBSDKMetadataIndexerRules) {
|
||||
NSDictionary<NSString *, NSString *> *rule = FBSDKMetadataIndexerRules[key];
|
||||
BOOL isRuleKMatched = [self checkMetadataHint:placeholder matchRuleK:rule[FIELD_K]]
|
||||
|| [self checkMetadataLabels:labels matchRuleK:rule[FIELD_K]];
|
||||
BOOL isRuleVMatched = [self checkMetadataText:text matchRuleV:rule[FIELD_V]];
|
||||
if (isRuleKMatched && isRuleVMatched) {
|
||||
[FBSDKMetadataIndexer checkAndAppendData:text forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
+ (void)checkAndAppendData:(NSString *)data
|
||||
forKey:(NSString *)key
|
||||
{
|
||||
NSString *hashData = [FBSDKUtility SHA256Hash:data];
|
||||
dispatch_async(serialQueue, ^{
|
||||
if (hashData.length == 0 || [FBSDKMetadataIndexerStore[key] containsObject:hashData]) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (FBSDKMetadataIndexerStore[key].count >= FBSDKMetadataIndexerMaxValue) {
|
||||
[FBSDKMetadataIndexerStore[key] removeObjectAtIndex:0];
|
||||
}
|
||||
[FBSDKMetadataIndexerStore[key] addObject:hashData];
|
||||
[FBSDKUserDataStore setHashData:[FBSDKMetadataIndexerStore[key] componentsJoinedByString:@","]
|
||||
forType:key];
|
||||
});
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataLabels:(NSArray<NSString *> *)labels
|
||||
matchRuleK:(NSString *)ruleK
|
||||
{
|
||||
for (NSString *label in labels) {
|
||||
if ([self checkMetadataHint:label matchRuleK:ruleK]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataHint:(NSString *)hint
|
||||
matchRuleK:(NSString *)ruleK
|
||||
{
|
||||
if (hint.length > 0 && ruleK) {
|
||||
NSArray<NSString *> *items = [ruleK componentsSeparatedByString:@","];
|
||||
for (NSString *item in items) {
|
||||
if ([hint containsString:item]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)checkMetadataText:(NSString *)text
|
||||
matchRuleV:(NSString *)ruleV
|
||||
{
|
||||
if (text.length > 0 && ruleV) {
|
||||
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:ruleV
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:nil];
|
||||
NSUInteger matches = [regex numberOfMatchesInString:text options:0 range:NSMakeRange(0, text.length)];
|
||||
|
||||
NSString *prunedText = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"+- ()."]] componentsJoinedByString:@""];
|
||||
NSUInteger prunedMatches = [regex numberOfMatchesInString:prunedText options:0 range:NSMakeRange(0, prunedText.length)];
|
||||
|
||||
return matches > 0 || prunedMatches > 0;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString *)normalizeField:(NSString *)field
|
||||
{
|
||||
if (!field) {
|
||||
return nil;
|
||||
}
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[_-]|\\s"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:nil];
|
||||
return [regex stringByReplacingMatchesInString:field
|
||||
options:0
|
||||
range:NSMakeRange(0, field.length)
|
||||
withTemplate:@""].lowercaseString;
|
||||
}
|
||||
|
||||
+ (NSString *)normalizedValue:(NSString *)value
|
||||
{
|
||||
if (!value) {
|
||||
return nil;
|
||||
}
|
||||
return [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].lowercaseString;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryValueOf:(id)object
|
||||
{
|
||||
if ([object isKindOfClass:[NSDictionary class]]) {
|
||||
return (NSDictionary *)object;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,283 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <OCMock/OCMock.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
|
||||
#import "FBSDKMetadataIndexer.h"
|
||||
|
||||
extern FBSDKAppEventUserDataType FBSDKAppEventRule1;
|
||||
extern FBSDKAppEventUserDataType FBSDKAppEventRule2;
|
||||
|
||||
@interface FBSDKMetadataIndexer ()
|
||||
+ (void)constructRules:(NSDictionary<NSString *, id> *)rules;
|
||||
|
||||
+ (void)initStore;
|
||||
|
||||
+ (BOOL)checkSecureTextEntry:(UIView *)view;
|
||||
|
||||
+ (UIKeyboardType)getKeyboardType:(UIView *)view;
|
||||
|
||||
+ (void)getMetadataWithText:(NSString *)text
|
||||
placeholder:(NSString *)placeholder
|
||||
labels:(NSArray<NSString *> *)labels
|
||||
secureTextEntry:(BOOL)secureTextEntry
|
||||
inputType:(UIKeyboardType)inputType;
|
||||
|
||||
+ (void)checkAndAppendData:(NSString *)data forKey:(NSString *)key;
|
||||
@end
|
||||
|
||||
@interface FBSDKMetadataIndexerTests : XCTestCase {
|
||||
id _mockMetadataIndexer;
|
||||
UITextField *_emailField;
|
||||
UITextView *_emailView;
|
||||
UITextField *_phoneField;
|
||||
UITextView *_phoneView;
|
||||
UITextField *_pwdField;
|
||||
UITextView *_pwdView;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FBSDKMetadataIndexerTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
_mockMetadataIndexer = OCMClassMock([FBSDKMetadataIndexer class]);
|
||||
[FBSDKMetadataIndexer initStore];
|
||||
[FBSDKMetadataIndexer constructRules:@{
|
||||
@"r1": @{
|
||||
@"k": @"email,e-mail,em,electronicmail",
|
||||
@"v": @"^([A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})$",
|
||||
},
|
||||
@"r2": @{
|
||||
@"k": @"phone,mobile,contact",
|
||||
@"v": @"^([0-9]{5,15})$",
|
||||
}
|
||||
}];
|
||||
|
||||
_emailField = [[UITextField alloc] init];
|
||||
_emailField.placeholder = @"Enter your email";
|
||||
_emailField.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
|
||||
_emailView = [[UITextView alloc] init];
|
||||
_emailView.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
|
||||
_phoneField = [[UITextField alloc] init];
|
||||
_phoneField.placeholder = @"Enter your phone";
|
||||
_phoneField.keyboardType = UIKeyboardTypePhonePad;
|
||||
|
||||
_pwdField = [[UITextField alloc] init];
|
||||
_pwdField.placeholder = @"Enter your password";
|
||||
_pwdField.secureTextEntry = YES;
|
||||
|
||||
_pwdView = [[UITextView alloc] init];
|
||||
_pwdView.secureTextEntry = YES;
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[_mockMetadataIndexer stopMocking];
|
||||
}
|
||||
|
||||
// test for geting secure text entry in UITextField
|
||||
- (void)testCheckSecureTextEntryOfTextField
|
||||
{
|
||||
// without secure text
|
||||
XCTAssertFalse([FBSDKMetadataIndexer checkSecureTextEntry:_emailField],
|
||||
@"test for UITextField without secure text");
|
||||
|
||||
// with secure text
|
||||
XCTAssertTrue([FBSDKMetadataIndexer checkSecureTextEntry:_pwdField],
|
||||
@"test for UITextField with secure text");
|
||||
}
|
||||
|
||||
// test for geting secure text entry in UITextView
|
||||
- (void)testCheckSecureTextEntryOfTextView
|
||||
{
|
||||
// without secure text
|
||||
XCTAssertFalse([FBSDKMetadataIndexer checkSecureTextEntry:_emailView],
|
||||
@"test for UITextView without secure text");
|
||||
|
||||
// with secure text
|
||||
XCTAssertTrue([FBSDKMetadataIndexer checkSecureTextEntry:_pwdView], @"test for UITextView with secure text");
|
||||
}
|
||||
|
||||
// test for geting keyboard type from UITextField
|
||||
- (void)testGetKeyboardTypeOfTextField
|
||||
{
|
||||
XCTAssertEqual(_emailField.keyboardType,
|
||||
[FBSDKMetadataIndexer getKeyboardType:_emailField],
|
||||
@"test for geting keyboard type from UITextField");
|
||||
}
|
||||
|
||||
// test for geting keyboard type from UITextView
|
||||
- (void)testGetKeyboardTypeOfTextView
|
||||
{
|
||||
XCTAssertEqual(_emailView.keyboardType,
|
||||
[FBSDKMetadataIndexer getKeyboardType:_emailView],
|
||||
@"test for geting keyboard type from UITextView");
|
||||
}
|
||||
|
||||
// test for geting metadata with valid email
|
||||
- (void)testGetMetadataWithEmail
|
||||
{
|
||||
NSString *text = @"test@fb.com";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your email"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMVerify([_mockMetadataIndexer checkAndAppendData:text forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with valid phone number
|
||||
- (void)testGetMetadataWithPhoneNumber
|
||||
{
|
||||
NSString *text = @"1112223333";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your phone number"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypePhonePad];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMVerify([_mockMetadataIndexer checkAndAppendData:text forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with secure text
|
||||
- (void)testGetMetadataWithSecureText
|
||||
{
|
||||
NSString *text = @"dfjald1314";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your password"
|
||||
labels:nil
|
||||
secureTextEntry:YES
|
||||
inputType:UIKeyboardTypeDefault];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with invalid email
|
||||
- (void)testGetMetadataWithInvalidEmail
|
||||
{
|
||||
NSString *text = @"test";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your email"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with invalid email placeholder
|
||||
- (void)testGetMetadataWithInvalidEmailPlaceholder
|
||||
{
|
||||
NSString *text = @"test@fb.com";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with invalid phone number
|
||||
- (void)testGetMetadataWithInvalidPhoneNumber
|
||||
{
|
||||
NSString *text = @"1234";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your phone number"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypePhonePad];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with invalid phone number placeholder
|
||||
- (void)testGetMetadataWithInvalidPhoneNumberPlaceholder
|
||||
{
|
||||
NSString *text = @"1112223333";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypePhonePad];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with text which is neither email nor phone number
|
||||
- (void)testGetMetadataWithTextNotEmailAndPhone
|
||||
{
|
||||
NSString *text = @"Facebook";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your name"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeAlphabet];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with no text
|
||||
- (void)testGetMetadataWithNoText
|
||||
{
|
||||
NSString *text = @"";
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your email"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with too long text
|
||||
- (void)testGetMetadataWithTooLongText
|
||||
{
|
||||
NSString *text = [NSString stringWithFormat:@"%@%@", [@"" stringByPaddingToLength:1000 withString: @"a" startingAtIndex:0], @"@fb.com"];
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:@"enter your email"
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
// test for geting metadata with too long placeholder
|
||||
- (void)testGetMetadataWithTooLongPlaceholder
|
||||
{
|
||||
NSString *text = @"test@fb.com";
|
||||
NSString *indicator = [NSString stringWithFormat:@"%@", [@"" stringByPaddingToLength:1000 withString: @"enter your email " startingAtIndex:0]];
|
||||
[FBSDKMetadataIndexer getMetadataWithText:text
|
||||
placeholder:indicator
|
||||
labels:nil
|
||||
secureTextEntry:NO
|
||||
inputType:UIKeyboardTypeEmailAddress];
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule1]);
|
||||
OCMReject([_mockMetadataIndexer checkAndAppendData:[OCMArg any] forKey:FBSDKAppEventRule2]);
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user