Commit fdd3e041 by GuoJianPeng

update

parent 3b19ef05
//
// ASCellularSignalMonitor.h
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import <Foundation/Foundation.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger,ASCellularType)
{
ASCellularTypeUnknown = 0,
ASCellularType2G,
ASCellularType3G,
ASCellularType4G,
ASCellularType5G API_AVAILABLE(ios(14.1))//iPhone12以上系列
};
typedef NS_ENUM(NSInteger,ASCelluarSignalStrength){
ASCelluarSignalStrengthUnknown = 0,
ASCelluarSignalStrengthStrong,
ASCelluarSignalStrengthWeak
};
@interface ASCellularService : NSObject
- (NSString*)accessTypeValue;
- (ASCellularType)accessType;
- (ASCelluarSignalStrength)signalStrength;
- (ASCelluarSignalStrength)signalStrengthEvaluatedForType:(ASCellularType)type;
@end
NS_ASSUME_NONNULL_END
//
// ASCellularSignalMonitor.m
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import "ASCellularService.h"
@implementation ASCellularService
-(NSString *)accessTypeValue
{
CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSString *radioAccessTechnology = nil;
if (@available(iOS 12.0, *)) {
// iOS 12 及以上版本,获取当前网络类型
NSDictionary *serviceRadioAccessTech = [networkInfo serviceCurrentRadioAccessTechnology];
radioAccessTechnology = serviceRadioAccessTech.allValues.firstObject;
} else {
// iOS 12 以下,直接获取当前网络类型
radioAccessTechnology = networkInfo.currentRadioAccessTechnology;
}
return radioAccessTechnology;
}
-(ASCellularType)accessType
{
ASCellularType type = ASCellularTypeUnknown;
NSString * value = [self accessTypeValue];
NSArray * secondGValues = @[
CTRadioAccessTechnologyEdge,CTRadioAccessTechnologyGPRS
];
if([secondGValues containsObject:value]){return ASCellularType2G;}
NSArray * threeGValues = @[
CTRadioAccessTechnologyHSDPA,CTRadioAccessTechnologyHSUPA,
CTRadioAccessTechnologyWCDMA,CTRadioAccessTechnologyCDMA1x
];
if([threeGValues containsObject:value]){return ASCellularType3G;}
else if ([value isEqualToString:CTRadioAccessTechnologyLTE]){
return ASCellularType4G;
}else{
if (@available(iOS 14.1, *)) {
NSArray * fiveGValues = @[
CTRadioAccessTechnologyNRNSA,CTRadioAccessTechnologyNR
];
if([fiveGValues containsObject:value]){return ASCellularType5G;}
}
}
return type;
}
-(ASCelluarSignalStrength)signalStrength
{
ASCellularType type = [self accessType];
return [self signalStrengthEvaluatedForType:type];
}
-(ASCelluarSignalStrength)signalStrengthEvaluatedForType:(ASCellularType)type
{
if (@available(iOS 14.1, *)) {
if(type == ASCellularType5G){
return ASCelluarSignalStrengthStrong;
}
}else if (type == ASCellularType4G){
return ASCelluarSignalStrengthStrong;
}else if (type == ASCellularType3G || type == ASCellularType2G){
return ASCelluarSignalStrengthWeak;
}else{
return ASCelluarSignalStrengthUnknown;
}
return ASCelluarSignalStrengthUnknown;
}
@end
//
// ASIPService.h
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/15.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger,ASIPType)
{
ASIPTypeUnknown = 0,
ASIPTypeWiFi,//Wifi
ASIPTypeCelluar,//蜂窝
ASIPTypeVPN,//VPN
ASIPTypeEthernet,//以太
ASIPTypeLo0,//本地环回
ASIPTypeBridge0,//热点
};
@interface ASIPEntity : NSObject
@property(nonatomic,copy,readonly)NSString*value;
@property(nonatomic,assign,readonly)ASIPType type;
@property(nonatomic,assign,readonly)BOOL isIpv4;
@property(nonatomic,assign,readonly)BOOL isIpv6;
@property(nonatomic,assign,readonly)BOOL isPrivateIP;//是否局域网私有IP
@property(nonatomic,assign,readonly)BOOL isLinkLocalIP;//是否自分配IP,169.254开头
@end
@interface ASIPService : NSObject
- (void)updateAvailableIPList;
- (BOOL)usingVPN;
//ipv4+ipv6可能同时启用
- (NSArray<NSString*>* _Nullable)getWiFiIP;
//ipv4+ipv6可能同时启用或多sim卡
- (NSArray<NSString*>*_Nullable)getCelluarIP;
@property(nonatomic,strong,readonly,nullable)NSArray<ASIPEntity*>*availableIPList;
@end
NS_ASSUME_NONNULL_END
//
// ASIPService.m
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/15.
//
#import "ASIPService.h"
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
@interface ASIPEntity()
- (instancetype)initWithInterfaceName:(NSString*)name ip:(NSString*)ip isIpv6:(BOOL)isIpv6;
@end
@implementation ASIPService
-(void)updateAvailableIPList
{
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int successCode = 0;
if(getifaddrs(&interfaces)!=successCode){
return;
}
temp_addr = interfaces;
NSMutableArray * newIPList = @[].mutableCopy;
while (temp_addr != NULL) {
BOOL isUsed = (temp_addr->ifa_flags & IFF_UP);
BOOL isIpv4 = (temp_addr->ifa_addr->sa_family == AF_INET);
BOOL isIpv6 = (temp_addr->ifa_addr->sa_family == AF_INET6);
if(!isUsed || (!isIpv4 && !isIpv6)){
temp_addr = temp_addr->ifa_next;
continue;
}//只处理启用的ipv4或ipv6接口.
NSString *interfaceName = [NSString stringWithUTF8String:temp_addr->ifa_name];
NSString *ipAddress = nil;
if(isIpv4){
ipAddress = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}else{
char addrBuffer[INET6_ADDRSTRLEN];
const struct sockaddr_in6 *sockaddr_ipv6 = (const struct sockaddr_in6 *)temp_addr->ifa_addr;
inet_ntop(AF_INET6, &sockaddr_ipv6->sin6_addr, addrBuffer, sizeof(addrBuffer));
ipAddress = [NSString stringWithUTF8String:addrBuffer];
}
temp_addr = temp_addr->ifa_next;
[newIPList addObject:[[ASIPEntity alloc]initWithInterfaceName:interfaceName ip:ipAddress isIpv6:isIpv6]];
}
freeifaddrs(interfaces);
_availableIPList = newIPList;
}
-(NSArray<NSString *> *)getWiFiIP
{
NSMutableArray * list;
for (ASIPEntity * ipEntity in _availableIPList) {
if(ipEntity.type == ASIPTypeWiFi){
if(!list){list = @[].mutableCopy;}
[list addObject:ipEntity.value];
}
}
return list;
}
-(NSArray<NSString *> *)getCelluarIP
{
NSMutableArray * list;
for (ASIPEntity * ipEntity in _availableIPList) {
if(ipEntity.type == ASIPTypeCelluar){
if(!list){list = @[].mutableCopy;}
[list addObject:ipEntity.value];
}
}
return list;
}
-(BOOL)usingVPN
{
for (ASIPEntity * ipEntity in _availableIPList) {
if(ipEntity.type == ASIPTypeVPN){return true;}
}
return false;
}
@end
@implementation ASIPEntity
{
NSString*_interfaceName;
}
-(instancetype)initWithInterfaceName:(NSString *)name ip:(NSString *)ip isIpv6:(BOOL)isIpv6{
if(self = [super init]){
_interfaceName = name;
_value = ip;
if(isIpv6){_isIpv6 = true;}else{_isIpv4 = true;}
_type = [self _convertTypeFromInterfaceName:name];
_isPrivateIP = [self isPrivateIP:_value];
_isLinkLocalIP = _isIpv6?[self isIPv6LinkLocalAddress:ip]:[ip hasPrefix:@"169.254"];
}return self;
}
- (ASIPType)_convertTypeFromInterfaceName:(NSString*)name
{
if([name isEqualToString:@"en0"]){return ASIPTypeWiFi;}
else if ([name isEqualToString:@"pdp_ip0"]){return ASIPTypeCelluar;}
else if ([name hasPrefix:@"utun"]){return ASIPTypeVPN;}
else if ([name hasPrefix:@"en"]){return ASIPTypeEthernet;}
else if ([name hasPrefix:@"lo0"]){return ASIPTypeLo0;}
else if ([name hasPrefix:@"bridge0"]){return ASIPTypeBridge0;}
else{return ASIPTypeUnknown;}
}
-(BOOL)isPrivateIP:(NSString*)value
{
if(_isIpv6){
return [self isIPv6PrivateAddress:value];
}
//判断ipv4
NSArray *privateRanges = @[
@"10.",
@"172.16.", @"172.17.", @"172.18.", @"172.19.", @"172.20.",
@"172.21.", @"172.22.", @"172.23.", @"172.24.", @"172.25.",
@"172.26.", @"172.27.", @"172.28.", @"172.29.", @"172.30.",
@"172.31.",
@"192.168."
];
return [privateRanges containsObject:value];
}
// 判断 IPv6 地址是否为 Link-Local 地址
- (BOOL)isIPv6LinkLocalAddress:(NSString *)ipAddress {
return [ipAddress hasPrefix:@"fe80"];
}
// 判断 IPv6 地址是否为私有 IP 地址(Unique Local Address, ULA)
- (BOOL)isIPv6PrivateAddress:(NSString *)ipAddress {
return [ipAddress hasPrefix:@"fc00"] || [ipAddress hasPrefix:@"fd00"];
}
-(NSString *)description
{
return [NSString stringWithFormat:@"IP:%@,interface:%@",_value,_interfaceName];
}
@end
//
// ASPingService.h
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/15.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class ASPingService;
@protocol ASPingServiceDelegate <NSObject>
- (void)pingService:(ASPingService*)service pingingWithDuration:(NSTimeInterval)millionSeconds seq:(uint16_t)seq;//正常收到回调
- (void)pingService:(ASPingService*)service pingTimeout:(uint16_t)seq;//ping超时,可能来自自身控制,也可能来自icmp通知.
- (void)pingService:(ASPingService*)service tmporaryErrorHappens:(NSError*)error seq:(uint16_t)seq;//可恢复的错误,后续会继续ping
@optional
- (void)pingingServiceDidStart:(ASPingService*)service;//[调用starts]成功
- (void)pingService:(ASPingService*)service failedToStartWithError:(NSError*)error;//调用[starts]失败
- (void)pingService:(ASPingService*)service stopWithError:(NSError*_Nullable)error;//ping终止,error为空时则为正常终止.
@end
@interface ASPingService : NSObject
- (instancetype)initWithDelegate:(id<ASPingServiceDelegate>)delegate;
- (void)starts;
- (void)stops;
@property(nonatomic,assign)BOOL usingICMPv6;//大陆的v6支持有限,一般不建议开启.
@property(nonatomic,weak,readonly)id<ASPingServiceDelegate>delegate;
@property(nonatomic,assign,readonly)BOOL isPinging;
@property(nonatomic,copy)NSString * targetHost;
@property(nonatomic,assign)NSInteger pingCount;//默认为1即只ping一次。
@property(nonatomic,assign)NSTimeInterval timeoutSeconds;//默认为3s,超出3s收不到当次ping回调,则取消当次ping,就算后续收到回调也ignore;不建议设置过低.
@end
NS_ASSUME_NONNULL_END
//
// ASPingService.m
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/15.
//
#import "ASPingService.h"
#import <CRMNetDetect/ASSimplePing.h>
#import <sys/time.h>
static uint16_t KASPingNotStartedSeq = -1;
@interface ASPingService()<ASSimplePingDelegate>
@end
@implementation ASPingService
{
ASSimplePing *_samplePing;
NSTimeInterval _startPingTime;
uint16_t _pingingSeq;
}
-(instancetype)initWithDelegate:(id<ASPingServiceDelegate>)delegate{
if (self = [super init]) {
_delegate = delegate;
_pingCount = 1;
_timeoutSeconds = 3;
_pingingSeq = KASPingNotStartedSeq;
}return self;
}
-(void)starts
{
if(_isPinging){
if([self.delegate respondsToSelector:@selector(pingService:failedToStartWithError:)]){
[self.delegate pingService:self failedToStartWithError:[self _createErrorWithMsg:@"Pinging Aready!"]];
}
return;
}
NSAssert(_targetHost, @"target host could not be nil.");
NSAssert(_pingCount >=1, @"Ping count could not smaller than 1");
NSAssert(_timeoutSeconds >=1, @"Ping timeout could not smaller than 1");
_isPinging = true;
_samplePing = [[ASSimplePing alloc] initWithHostName:_targetHost];
_samplePing.delegate = self;
_samplePing.addressStyle = _usingICMPv6?ASSimplePingAddressStyleICMPv6:ASSimplePingAddressStyleICMPv4;
if([self.delegate respondsToSelector:@selector(pingingServiceDidStart:)]){
[self.delegate pingingServiceDidStart:self];
}
NSLog(@"PING %@:",_targetHost);
[_samplePing start];
}
-(void)stops
{
if(!_samplePing){
return;
}
NSLog(@"stops ping service");
[_samplePing stop];
_samplePing = nil;
_pingingSeq = KASPingNotStartedSeq;
_isPinging = false;
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (NSError*)_createErrorWithMsg:(NSString*)msg
{
return [NSError errorWithDomain:@"ASPingServiceErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey:msg}];
}
- (void)_sendPingOnce
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_gotManulyTimeoutNotification) object:nil];
_pingingSeq ++;
if(_pingingSeq >= _pingCount){
[self stops];
if([self.delegate respondsToSelector:@selector(pingService:stopWithError:)]){
[self.delegate pingService:self stopWithError:nil];
}
return;
}
[self performSelector:@selector(_gotManulyTimeoutNotification) withObject:nil afterDelay:self.timeoutSeconds];
_startPingTime = [self _getCurrentMicroSeconds];
[_samplePing sendPingWithData:nil];
NSLog(@"did send next ping and current count is %hu",_pingingSeq);
}
- (void)_gotManulyTimeoutNotification
{
NSLog(@"Request timeout for icmp_seq %hu",_pingingSeq);
//当次ping超时
if([self.delegate respondsToSelector:@selector(pingService:pingTimeout:)]){
[self.delegate pingService:self pingTimeout:_pingingSeq];
}
//开启下次ping
[self _sendPingOnce];
}
- (NSTimeInterval)_getCurrentMicroSeconds
{
struct timeval time;
gettimeofday(&time,NULL);
return time.tv_usec;
}
- (NSTimeInterval)_getPingTimePastMicroSeconds
{
NSTimeInterval now = [self _getCurrentMicroSeconds];
if(now < _startPingTime){
return (1000000 + now - _startPingTime)/1000;
}
return (now - _startPingTime)/1000;
}
#pragma mark - ASSimplePingDelegate
- (void)simplePing:(ASSimplePing *)pinger didStartWithAddress:(NSData *)address
{
[self _sendPingOnce];
}
- (void)simplePing:(ASSimplePing *)pinger didFailWithError:(NSError *)error
{
BOOL isTimeoutCase = ([error.domain isEqualToString:NSPOSIXErrorDomain]&&error.code ==ETIMEDOUT);
if(isTimeoutCase){
[self _gotManulyTimeoutNotification];//按照手动超时的方式处理.
}else{
[self stops];
if([self.delegate respondsToSelector:@selector(pingService:stopWithError:)]){
[self.delegate pingService:self stopWithError:nil];
}
}
}
- (void)simplePing:(ASSimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
// NSLog(@"did send ping seq:%hu",sequenceNumber);
}
- (void)simplePing:(ASSimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error
{
NSLog(@"did failed to send ping");
if([self.delegate respondsToSelector:@selector(pingService:tmporaryErrorHappens:seq:)]){
[self.delegate pingService:self tmporaryErrorHappens:error seq:_pingingSeq];
}
[self _sendPingOnce];//resend again.
}
- (void)simplePing:(ASSimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
if(sequenceNumber == _pingingSeq){
NSTimeInterval duration = [self _getPingTimePastMicroSeconds];
NSLog(@"%ld bytes from %@: icmp_seq=%hu time=%.3f ms",packet.length,_targetHost,sequenceNumber,duration);
[self.delegate pingService:self pingingWithDuration:duration seq:sequenceNumber];
[self _sendPingOnce];
}else{
NSLog(@"got outdate sequenceNumber:%hu",sequenceNumber);
}
}
- (void)simplePing:(ASSimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet
{
NSLog(@"did failed to send ping");
if([self.delegate respondsToSelector:@selector(pingService:tmporaryErrorHappens:seq:)]){
[self.delegate pingService:self tmporaryErrorHappens:[self _createErrorWithMsg:@"ReceiveUnexpectedPacket"] seq:_pingingSeq];
}
[self _sendPingOnce];//ignore,send again.
}
@end
//
// ASReachability.h
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import <Foundation/Foundation.h>
#import <CRMNetDetect/ASCellularService.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger,ASReachabilityStatus){
ASReachabilityStatusUnknown = 0,
ASReachabilityStatusNotReachable,
ASReachabilityStatusWWAN,
ASReachabilityStatusWifi
};
@class ASReachability;
@protocol ASReachabilityDelegate <NSObject>
- (void)reachabilityBecomesNotReachable:(ASReachability*)ability;
- (void)reachabilityChangedToWiFi:(ASReachability*)ability;
- (void)reachabilityChangedToWWAN:(ASReachability*)ability
type:(ASCellularType)type signalStrength:(ASCelluarSignalStrength)strength;
@end
@interface ASReachability : NSObject
- (instancetype)initWithDelegate:(id<ASReachabilityDelegate>)delegate;
- (void)startsObserving;
- (void)stopObserving;
@property(nonatomic,copy,nullable)NSString * host;
@property(nonatomic,assign,readonly)ASReachabilityStatus status;
@property(nonatomic,weak,readonly)id<ASReachabilityDelegate>delegate;
@end
NS_ASSUME_NONNULL_END
//
// ASReachability.m
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import "ASReachability.h"
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
@interface ASReachability()
@property(nonatomic,strong,nullable)ASCellularService * celluarService;
@property (nonatomic) SCNetworkReachabilityRef reachabilityRef;
@end
@implementation ASReachability
-(instancetype)initWithDelegate:(id<ASReachabilityDelegate>)delegate
{
if(self = [super init]){
_delegate = delegate;
}return self;
}
-(void)startsObserving
{
if(_reachabilityRef){
return;
}
self.reachabilityRef = [self _createHostReachabilityRef]?:[self _createInternetReachabilityRef];
if(!_reachabilityRef){
NSLog(@"Could not create reachabilityRef");
return;
}
// 初始化时检查网络状态
[self checkCurrentNetworkStatus];
SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
SCNetworkReachabilitySetCallback(self.reachabilityRef, ReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}
-(void)stopObserving
{
if (_reachabilityRef) {
SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFRelease(_reachabilityRef);
_reachabilityRef = NULL;
}
}
// 网络状态变化回调函数
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) {
ASReachability *monitor = (__bridge ASReachability *)info;
[monitor handleNetworkChangeWithFlags:flags];
}
- (void)checkCurrentNetworkStatus {
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) {
[self handleNetworkChangeWithFlags:flags];
} else {
NSLog(@"Failed to retrieve network status");
}
}
// 处理网络状态变化
- (void)handleNetworkChangeWithFlags:(SCNetworkReachabilityFlags)flags {
BOOL isReachable = (flags & kSCNetworkReachabilityFlagsReachable);
BOOL needsConnection = (flags & kSCNetworkReachabilityFlagsConnectionRequired);
if (isReachable && !needsConnection) {
NSLog(@"Network is reachable");
// 进一步检查网络类型
[self detectConnectionTypeWithFlags:flags];
} else {
BOOL isTransient = (flags & kSCNetworkReachabilityFlagsTransientConnection);
BOOL interventionRequired = (flags & kSCNetworkReachabilityFlagsInterventionRequired);
// 网络不可达处理
if (isReachable && interventionRequired) {
NSLog(@"Network requires user intervention (e.g., Wi-Fi login)");
} else if (isReachable && isTransient) {
NSLog(@"Network connection is transient (e.g., dial-up or other temporary connection)");
} else {
NSLog(@"Network is not reachable");
}
_status = ASReachabilityStatusNotReachable;
[self.delegate reachabilityBecomesNotReachable:self];
}
}
// 检测当前的网络连接类型(Wi-Fi 或 蜂窝)
- (void)detectConnectionTypeWithFlags:(SCNetworkReachabilityFlags)flags {
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
// 通过蜂窝网络连接
if(!_celluarService){_celluarService = [ASCellularService new];}
ASCellularType type = _celluarService.accessType;
NSLog(@"Connected via Cellular of %ld",type);
_status = ASReachabilityStatusWifi;
[self.delegate reachabilityChangedToWWAN:self type:type signalStrength:[_celluarService signalStrengthEvaluatedForType:type]];
} else {
// 通过Wi-Fi或其他网络连接
NSLog(@"Connected via Wi-Fi");
_status = ASReachabilityStatusWWAN;
[self.delegate reachabilityChangedToWiFi:self];
}
}
-(void)dealloc
{
[self stopObserving];
}
#pragma mark - Privates
- (SCNetworkReachabilityRef _Nullable)_createHostReachabilityRef
{
return _host ? SCNetworkReachabilityCreateWithName(NULL, _host.UTF8String) : nil;
}
- (SCNetworkReachabilityRef _Nullable)_createInternetReachabilityRef{
struct sockaddr_in6 ipv6Address;
memset(&ipv6Address, 0, sizeof(ipv6Address));
ipv6Address.sin6_len = sizeof(ipv6Address);
ipv6Address.sin6_family = AF_INET6;
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&ipv6Address);
if(ref){return ref;}//优先使用ipv6地址
struct sockaddr_in ipv4Address;
memset(&ipv4Address, 0, sizeof(ipv4Address));
ipv4Address.sin_len = sizeof(ipv4Address);
ipv4Address.sin_family = AF_INET;
ref = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&ipv4Address);
return ref;
}
@end
//
// CRMNetDetectService.h
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger,CRMNetSignalLevel){
CRMNetSignalLevelUnknown = 0,
CRMNetSignalLevelStrong,
CRMNetSignalLevelWeak
};
@class CRMNetDetectService;
@protocol CRMNetDetectServiceDelegate <NSObject>
- (void)netDetect:(CRMNetDetectService*)service signalLevelChanged:(CRMNetSignalLevel)level;
@end
@interface CRMNetDetectService : NSObject
/**
* @return 是否检测中的标识,在调用[startsDetecting]后为true,初始状态或[stopDetecting]后为false
**/
- (BOOL)isDetectStarted;
/**
* @brief 启动网络探测,探测结果通过delegate通知.
**/
- (void)startsDetecting;
/**
* @brief 停止网络探测.
**/
- (void)stopDetecting;
@end
NS_ASSUME_NONNULL_END
//
// CRMNetDetectService.m
// CRMNetDetect
//
// Created by 坚鹏 on 2024/10/14.
//
#import "CRMNetDetectService.h"
@implementation CRMNetDetectService
@end
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:CRMNetDetect.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
// //
@import UIKit; @import UIKit;
#import <CRMNetDetect/ASReachability.h>
#import <CRMNetDetect/ASPingService.h>
@interface ASAppDelegate : UIResponder <UIApplicationDelegate> @interface ASAppDelegate : UIResponder <UIApplicationDelegate,ASReachabilityDelegate,ASPingServiceDelegate>
@property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UIWindow *window;
......
...@@ -7,12 +7,28 @@ ...@@ -7,12 +7,28 @@
// //
#import "ASAppDelegate.h" #import "ASAppDelegate.h"
#import "ASIPService.h"
@implementation ASAppDelegate @implementation ASAppDelegate
{
ASReachability * _reachability;
ASPingService *_pingService;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ {
// Override point for customization after application launch. // Override point for customization after application launch.
ASIPService*service = [ASIPService new];
[service updateAvailableIPList];
NSLog(@"当前网络下\n%@",service.availableIPList);
_reachability = [[ASReachability alloc] initWithDelegate:self];
[_reachability startsObserving];
_pingService = [[ASPingService alloc] initWithDelegate:self];
_pingService.pingCount = 10;
_pingService.timeoutSeconds = 2;
_pingService.targetHost = @"ebank.sdb.com.cn";
[_pingService starts];
return YES; return YES;
} }
...@@ -43,4 +59,39 @@ ...@@ -43,4 +59,39 @@
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
} }
- (void)reachabilityBecomesNotReachable:(nonnull ASReachability *)ability {
}
- (void)reachabilityChangedToWWAN:(nonnull ASReachability *)ability type:(ASCellularType)type signalStrength:(ASCelluarSignalStrength)strength {
ASIPService*service = [ASIPService new];
[service updateAvailableIPList];
NSLog(@"celluar ip:%@",service.getCelluarIP);
}
- (void)reachabilityChangedToWiFi:(nonnull ASReachability *)ability {
ASIPService*service = [ASIPService new];
[service updateAvailableIPList];
NSLog(@"wifi ip:%@",service.getWiFiIP);
}
- (void)pingService:(nonnull ASPingService *)service pingTimeout:(uint16_t)seq {
}
- (void)pingService:(nonnull ASPingService *)service pingingWithDuration:(NSTimeInterval)millionSeconds seq:(uint16_t)seq {
}
- (void)pingService:(nonnull ASPingService *)service tmporaryErrorHappens:(nonnull NSError *)error seq:(uint16_t)seq {
}
-(void)pingService:(ASPingService *)service stopWithError:(NSError *)error
{
if(![service.targetHost isEqualToString:@"svinvy.com"]){
_pingService.targetHost = @"svinvy.com";
[_pingService starts];
}
}
@end @end
...@@ -7,7 +7,10 @@ ...@@ -7,7 +7,10 @@
// //
#import "ASViewController.h" #import "ASViewController.h"
struct IPV4Header{
uint8_t na;
};
typedef struct IPV4Header ASIPV4Header;
@interface ASViewController () @interface ASViewController ()
@end @end
......
PODS:
- CRMNetDetect (0.1.0)
DEPENDENCIES:
- CRMNetDetect (from `../`)
EXTERNAL SOURCES:
CRMNetDetect:
:path: "../"
SPEC CHECKSUMS:
CRMNetDetect: bfcefd1bdbfe5c6882b53814a550a8a8f840e082
PODFILE CHECKSUM: ab41865aadda21067563b5d42c8b495684c3026e
COCOAPODS: 1.12.1
{
"name": "CRMNetDetect",
"version": "0.1.0",
"summary": "A short description of CRMNetDetect.",
"description": "TODO: Add long description of the pod here.",
"homepage": "https://github.com/guojianpeng@svinvy.com/CRMNetDetect",
"license": {
"type": "MIT",
"file": "LICENSE"
},
"authors": {
"guojianpeng@svinvy.com": "svinvy@gmail.com"
},
"source": {
"git": "https://github.com/guojianpeng@svinvy.com/CRMNetDetect.git",
"tag": "0.1.0"
},
"platforms": {
"ios": "10.0"
},
"source_files": "CRMNetDetect/Classes/**/*"
}
PODS:
- CRMNetDetect (0.1.0)
DEPENDENCIES:
- CRMNetDetect (from `../`)
EXTERNAL SOURCES:
CRMNetDetect:
:path: "../"
SPEC CHECKSUMS:
CRMNetDetect: bfcefd1bdbfe5c6882b53814a550a8a8f840e082
PODFILE CHECKSUM: ab41865aadda21067563b5d42c8b495684c3026e
COCOAPODS: 1.12.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_CRMNetDetect : NSObject
@end
@implementation PodsDummy_CRMNetDetect
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "ASCellularService.h"
#import "ASIPService.h"
#import "ASPingService.h"
#import "ASReachability.h"
#import "ASSimplePing.h"
#import "CRMNetDetectService.h"
FOUNDATION_EXPORT double CRMNetDetectVersionNumber;
FOUNDATION_EXPORT const unsigned char CRMNetDetectVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module CRMNetDetect {
umbrella header "CRMNetDetect-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
# Acknowledgements
This application makes use of the following third party libraries:
## CRMNetDetect
Copyright (c) 2024 guojianpeng@svinvy.com <svinvy@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission 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.
Generated by CocoaPods - https://cocoapods.org
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2024 guojianpeng@svinvy.com &lt;svinvy@gmail.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission 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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>CRMNetDetect</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_CRMNetDetect_Example : NSObject
@end
@implementation PodsDummy_Pods_CRMNetDetect_Example
@end
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
BCSYMBOLMAP_DIR="BCSymbolMaps"
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink -f "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
warn_missing_arch=${2:-true}
if [ -r "$source" ]; then
# Copy the dSYM into the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
fi
fi
}
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
warn_missing_arch=${2:-true}
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
if [[ "$warn_missing_arch" == "true" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
fi
STRIP_BINARY_RETVAL=1
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=0
}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/CRMNetDetect/CRMNetDetect.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/CRMNetDetect/CRMNetDetect.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_CRMNetDetect_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_CRMNetDetect_ExampleVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect/CRMNetDetect.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "CRMNetDetect"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module Pods_CRMNetDetect_Example {
umbrella header "Pods-CRMNetDetect_Example-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect/CRMNetDetect.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "CRMNetDetect"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
# Acknowledgements
This application makes use of the following third party libraries:
Generated by CocoaPods - https://cocoapods.org
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_CRMNetDetect_Tests : NSObject
@end
@implementation PodsDummy_Pods_CRMNetDetect_Tests
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_CRMNetDetect_TestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_CRMNetDetect_TestsVersionString[];
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect/CRMNetDetect.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "CRMNetDetect"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
framework module Pods_CRMNetDetect_Tests {
umbrella header "Pods-CRMNetDetect_Tests-umbrella.h"
export *
module * { export * }
}
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CRMNetDetect/CRMNetDetect.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "CRMNetDetect"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment