修复了一些可能导致崩溃的问题
This commit is contained in:
@@ -19,9 +19,16 @@
|
||||
// NSLog 一下 __FUNCTION__ 就知道为什么这么截取了。
|
||||
NSRange blankRange = [fn rangeOfString:@":"];
|
||||
NSUInteger start = blankRange.location + 1;
|
||||
NSUInteger length = fn.length - start - 2;
|
||||
NSUInteger length;
|
||||
if ((start + 2) < fn.length) {
|
||||
length = fn.length - start - 2;
|
||||
} else if ((start + 1) < fn.length) {
|
||||
length = fn.length -start - 1;
|
||||
} else {
|
||||
length = fn.length -start;
|
||||
}
|
||||
|
||||
NSString *fromatParamKeys = [fn substringWithRange:NSMakeRange(start, length)];
|
||||
|
||||
// 构造请求的 NSMutableDictionary *params 。
|
||||
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#import "StatisticsServiceHelper.h"
|
||||
#import "XPWeakTimer.h"
|
||||
#import "NSMutableDictionary+Saft.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///Model
|
||||
#import "HomeLiveTagModel.h"
|
||||
#import "HomeLiveLookRecordModel.h"
|
||||
@@ -204,13 +205,13 @@
|
||||
|
||||
- (id<JXPagerViewListViewDelegate>)pagerView:(JXPagerView *)pagerView initListAtIndex:(NSInteger)index {
|
||||
XPHomeLivePageViewController * homeVC = [[XPHomeLivePageViewController alloc] init];
|
||||
HomeLiveTagModel *tag = self.tagList[index];
|
||||
HomeLiveTagModel *tag = [self.tagList safeObjectAtIndex1:index];
|
||||
homeVC.tabId = tag.tid;
|
||||
return homeVC;
|
||||
}
|
||||
|
||||
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
|
||||
HomeLiveTagModel *tag = self.tagList[index];
|
||||
HomeLiveTagModel *tag = [self.tagList safeObjectAtIndex1:index];
|
||||
NSMutableDictionary * dic = [NSMutableDictionary dictionary];
|
||||
[dic safeSetObject: tag.sortName forKey:@"geboTagName"];
|
||||
[StatisticsServiceHelper trackEventWithKey:StatisticsServiceEventGebo_tab_click eventAttributes:dic];
|
||||
|
@@ -195,14 +195,14 @@ NSString * const XPConstSearchRecordStoreKey = @"XPConstSearchRecordStoreKey";
|
||||
return cell;
|
||||
} else {
|
||||
XPHomeAttentionCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPHomeAttentionCollectionViewCell class]) forIndexPath:indexPath];
|
||||
cell.recordRoom = self.inRoomList[indexPath.row];
|
||||
cell.recordRoom = [self.inRoomList safeObjectAtIndex1:indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (collectionView == self.searchCollectionView) {
|
||||
NSString *str = self.searchList[indexPath.row];
|
||||
NSString *str = [self.searchList safeObjectAtIndex1:indexPath.row];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(xPRoomSearchRecordViewControllerSearchWithWord:)]) {
|
||||
[self.delegate xPRoomSearchRecordViewControllerSearchWithWord:str];
|
||||
}
|
||||
@@ -213,7 +213,7 @@ NSString * const XPConstSearchRecordStoreKey = @"XPConstSearchRecordStoreKey";
|
||||
[self.delegate xPRoomSearchRecordViewControllerEveryoneSearch:model.word sid:model.sid];
|
||||
}
|
||||
} else {
|
||||
XPMineFootPrintModel *resultModel = self.inRoomList[indexPath.row];
|
||||
XPMineFootPrintModel *resultModel = [self.inRoomList safeObjectAtIndex1:indexPath.row];
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
if (resultModel.valid) {
|
||||
[XPRoomViewController openRoom:resultModel.roomUid viewController:self.presentingViewController];
|
||||
|
@@ -209,7 +209,7 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if (self.openType == SessionListOpenTypeRoom) {
|
||||
NIMRecentSession *recentSession = self.recentSessions[indexPath.row];
|
||||
NIMRecentSession *recentSession = [self.recentSessions safeObjectAtIndex1:indexPath.row];
|
||||
SessionViewController * sessionVC =[[SessionViewController alloc] initWithSession:recentSession.session];
|
||||
sessionVC.openType = self.openType;
|
||||
CATransition *transition = [CATransition animation];
|
||||
@@ -221,7 +221,7 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
|
||||
[self.mainController.view addSubview:sessionVC.view];
|
||||
[self.mainController addChildViewController:sessionVC];
|
||||
} else {
|
||||
NIMRecentSession *recentSession = self.recentSessions[indexPath.row];
|
||||
NIMRecentSession *recentSession = [self.recentSessions safeObjectAtIndex1:indexPath.row];
|
||||
SessionViewController *vc = [[SessionViewController alloc] initWithSession:recentSession.session];
|
||||
vc.openType = self.openType;
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
@@ -259,7 +259,7 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
|
||||
if (!cell) {
|
||||
cell = [[SessionListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
|
||||
}
|
||||
NIMRecentSession *recent = self.recentSessions[indexPath.row];
|
||||
NIMRecentSession *recent = [self.recentSessions safeObjectAtIndex1:indexPath.row];
|
||||
[cell renderWithSession:recent];
|
||||
return cell;
|
||||
}
|
||||
@@ -313,8 +313,9 @@ NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey";
|
||||
totalUnreadCount:(NSInteger)totalUnreadCount {
|
||||
// 清理本地数据
|
||||
NSUInteger index = [self.recentSessions indexOfObject:recentSession];
|
||||
[self.recentSessions removeObjectAtIndex:index];
|
||||
|
||||
if (index < self.recentSessions.count) {
|
||||
[self.recentSessions removeObjectAtIndex:index];
|
||||
}
|
||||
// 如果删除本地会话后就不允许漫游当前会话,则需要进行一次删除服务器会话的操作
|
||||
BOOL deleteRemote = NO;
|
||||
if (deleteRemote) {
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#import "XPNobleRankTableViewCell.h"
|
||||
#import "XPNobleMyInfoView.h"
|
||||
#import "XPNobleRankUpdateView.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///P
|
||||
#import "XPNobleCenterPresenter.h"
|
||||
#import "XPNobleCenterProtocol.h"
|
||||
@@ -139,7 +140,7 @@
|
||||
if (cell == nil) {
|
||||
cell = [[XPNobleRankTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPNobleRankTableViewCell class])];
|
||||
}
|
||||
NObleRankUserModel * userInfo = self.datasource[indexPath.row];
|
||||
NObleRankUserModel * userInfo = [self.datasource safeObjectAtIndex1:indexPath.row];
|
||||
cell.userInfo = userInfo;
|
||||
return cell;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#import "RechargeStorage.h"
|
||||
#import "AccountInfoStorage.h"
|
||||
#import "NSObject+MJExtension.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///Model
|
||||
#import "RechargeListModel.h"
|
||||
///View
|
||||
@@ -159,7 +160,7 @@
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
XPMineRechargeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPMineRechargeTableViewCell class]) forIndexPath:indexPath];
|
||||
cell.listModel = self.datasource[indexPath.row];
|
||||
cell.listModel = [self.datasource safeObjectAtIndex1:indexPath.row];
|
||||
cell.delegate = self;
|
||||
return cell;
|
||||
}
|
||||
|
@@ -99,7 +99,9 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
[self.selectArray removeObjectAtIndex:index];
|
||||
if (index < self.selectArray.count) {
|
||||
[self.selectArray removeObjectAtIndex:index];
|
||||
}
|
||||
} else {
|
||||
XPSkillCardSourcePropDetailModel *propItem = [[XPSkillCardSourcePropDetailModel alloc] init];
|
||||
propItem.parentId = self.propModel.propId;
|
||||
@@ -128,8 +130,13 @@
|
||||
}
|
||||
}
|
||||
if (index > -1) {
|
||||
[self.selectArray removeObjectAtIndex:index];
|
||||
[self.selectPropNameArray removeObjectAtIndex:index];
|
||||
if (index < self.selectArray.count) {
|
||||
[self.selectArray removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
if (index < self.selectPropNameArray.count) {
|
||||
[self.selectPropNameArray removeObjectAtIndex:index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
///Tool
|
||||
#import "ThemeColor.h"
|
||||
#import "XPMacro.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///Model
|
||||
#import "XPMineFootPrintModel.h"
|
||||
///View
|
||||
@@ -191,7 +192,7 @@
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
XPMineFootPrintModel *model = self.datasource[indexPath.row];
|
||||
XPMineFootPrintModel *model = [self.datasource safeObjectAtIndex1:indexPath.row];
|
||||
if (model.roomUid.integerValue > 0) {
|
||||
[XPRoomViewController openRoom:model.roomUid viewController:self];
|
||||
}
|
||||
|
@@ -226,7 +226,9 @@
|
||||
int t = arc4random()%startArray.count;
|
||||
resultArray[i]=startArray[t];
|
||||
startArray[t]=[startArray lastObject]; //为更好的乱序,故交换下位置
|
||||
[startArray removeLastObject];
|
||||
if (startArray.count > 0) {
|
||||
[startArray removeLastObject];
|
||||
}
|
||||
}
|
||||
return resultArray;
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#import <SDCycleScrollView/SDCycleScrollView.h>
|
||||
///
|
||||
#import "ThemeColor.h"
|
||||
#import "NSArray+Safe.h"
|
||||
|
||||
static NSString *kHideGiftViewInteractDot = @"kHideGiftViewInteractDot";//是否隐藏互动红点
|
||||
|
||||
@@ -108,7 +109,7 @@ static NSString *kHideGiftViewInteractDot = @"kHideGiftViewInteractDot";//是否
|
||||
#pragma mark - SDCycleScrollViewDelegate
|
||||
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index {
|
||||
if (self.titleArray.count > index) {
|
||||
NSString *str = self.titleArray[index];
|
||||
NSString *str = [self.titleArray safeObjectAtIndex1:index];
|
||||
if([str isEqualToString:@"首充有礼"]) {
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(xPGiftHeadTypeViewDidClickFirstRecharge:)]) {
|
||||
[self.delegate xPGiftHeadTypeViewDidClickFirstRecharge:self];
|
||||
|
@@ -225,7 +225,9 @@
|
||||
if (array.count) {
|
||||
[array makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
}
|
||||
[self.indexArray removeLastObject];
|
||||
if (self.indexArray.count > 0) {
|
||||
[self.indexArray removeLastObject];
|
||||
}
|
||||
[self cratePriceAttribute];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(xPGraffitiGiftView:didDrawCompletion:)]) {
|
||||
[self.delegate xPGraffitiGiftView:self didDrawCompletion:self.pointArray];
|
||||
|
@@ -249,18 +249,25 @@
|
||||
|
||||
if (firstRechargeActivity && [self.activityList containsObject:firstRechargeActivity]) {
|
||||
NSInteger index = [self.activityList indexOfObject:firstRechargeActivity];
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
if (index < self.imageUrlList.count) {
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
[self.activityList removeObject:firstRechargeActivity];
|
||||
}
|
||||
|
||||
if (candyActivity && [self.activityList containsObject:candyActivity]) {
|
||||
NSInteger index = [self.activityList indexOfObject:candyActivity];
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
if (index < self.imageUrlList.count) {
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
}
|
||||
[self.activityList removeObject:candyActivity];
|
||||
}
|
||||
if (sailingActivity && [self.activityList containsObject:sailingActivity]) {
|
||||
NSInteger index = [self.activityList indexOfObject:sailingActivity];
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
if (index < self.imageUrlList.count) {
|
||||
[self.imageUrlList removeObjectAtIndex:index];
|
||||
}
|
||||
[self.activityList removeObject:sailingActivity];
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#import "TTPopup.h"
|
||||
#import "XPHtmlUrl.h"
|
||||
#import "UIButton+EnlargeTouchArea.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///View
|
||||
#import "XPAnchorFansTaskTableViewCell.h"
|
||||
#import "XPRoomHalfWebView.h"
|
||||
@@ -269,7 +270,7 @@
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
XPAnchorFansTaskTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPAnchorFansTaskTableViewCell class])];
|
||||
XPAnchorFansTaskDetailModel *model = self.model.taskVos[indexPath.row];
|
||||
XPAnchorFansTaskDetailModel *model = [self.model.taskVos safeObjectAtIndex1:indexPath.row];
|
||||
cell.model = model;
|
||||
|
||||
return cell;
|
||||
|
@@ -668,7 +668,9 @@
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[candyTreeView removeFromSuperview];
|
||||
[self.candyTreegiftQueue removeObjectAtIndex:0];
|
||||
if (self.candyTreegiftQueue.count > 0) {
|
||||
[self.candyTreegiftQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.candyTreegiftQueue.count > 0) {
|
||||
[self createCandyTreeBannerAnimation:self.candyTreegiftQueue.firstObject];
|
||||
}
|
||||
@@ -713,7 +715,9 @@
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[sailingView removeFromSuperview];
|
||||
[self.sailingQueue removeObjectAtIndex:0];
|
||||
if (self.sailingQueue.count > 0) {
|
||||
[self.sailingQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.sailingQueue.count > 0) {
|
||||
[self createSailingBannerAnimation:self.sailingQueue.firstObject];
|
||||
}
|
||||
@@ -756,7 +760,9 @@
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[nobleLevelUpView removeFromSuperview];
|
||||
[self.nobleLevelUpQueue removeObjectAtIndex:0];
|
||||
if (self.nobleLevelUpQueue > 0) {
|
||||
[self.nobleLevelUpQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.nobleLevelUpQueue.count > 0) {
|
||||
[self createNobleLevelUpBannerAnimation:self.nobleLevelUpQueue.firstObject];
|
||||
}
|
||||
@@ -800,7 +806,10 @@
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[compoundGiftView removeFromSuperview];
|
||||
[self.compoundGiftQueue removeObjectAtIndex:0];
|
||||
if (self.compoundGiftQueue.count > 0) {
|
||||
[self.compoundGiftQueue removeObjectAtIndex:0];
|
||||
}
|
||||
|
||||
if (self.compoundGiftQueue.count > 0) {
|
||||
[self createGiftCompoundBannerAnimation:self.compoundGiftQueue.firstObject];
|
||||
}
|
||||
@@ -1143,7 +1152,10 @@
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[view removeFromSuperview];
|
||||
[self.giftBroadcastQueue removeObjectAtIndex:0];
|
||||
if (self.giftBroadcastQueue.count > 0) {
|
||||
[self.giftBroadcastQueue removeObjectAtIndex:0];
|
||||
}
|
||||
|
||||
if (self.giftBroadcastQueue.count > 0) {
|
||||
[self createGiftBroadcastViewAnimation:self.giftBroadcastQueue.firstObject];
|
||||
}
|
||||
@@ -1568,7 +1580,9 @@
|
||||
} else if(player == self.enterEffectView) {
|
||||
self.enterEffectView.hidden = YES;
|
||||
[self.enterEffectView removeFromSuperview];
|
||||
[self.enterEffectQueue removeObjectAtIndex:0];
|
||||
if (self.enterEffectQueue.count > 0) {
|
||||
[self.enterEffectQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.enterEffectQueue.count > 0) {
|
||||
NSString * title = [self.enterEffectQueue.firstObject objectForKey:@"title"];
|
||||
NSInteger experLevelSeq = [(NSString *)[self.enterEffectQueue.firstObject objectForKey:@"experLevelSeq"] integerValue];
|
||||
@@ -1655,7 +1669,9 @@
|
||||
if (container == self.carVapEffectView) {
|
||||
[self.carVapEffectView removeFromSuperview];
|
||||
self.carVapEffectView = nil;
|
||||
[self.carEffectQueue removeObjectAtIndex:0];
|
||||
if (self.carEffectQueue.count > 0) {
|
||||
[self.carEffectQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.carEffectQueue.count > 0) {
|
||||
[self playCarEffect:self.carEffectQueue.firstObject];
|
||||
}
|
||||
|
@@ -1442,8 +1442,10 @@
|
||||
@strongify(self);
|
||||
if (self.trumpetQueue.count) {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[self createTrumpetAnimation:self.trumpetQueue.firstObject];
|
||||
[self.trumpetQueue removeObjectAtIndex:0];
|
||||
[self createTrumpetAnimation:[self.trumpetQueue safeObjectAtIndex1:0]];
|
||||
if (self.trumpetQueue.count > 0) {
|
||||
[self.trumpetQueue removeObjectAtIndex:0];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
@@ -93,7 +93,7 @@ NSString * const kCandyTreeHideMessage = @"kCandyTreeHideMessage";
|
||||
return cell;
|
||||
}
|
||||
XPCandyTreeMoreRuleCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPCandyTreeMoreRuleCell class])];
|
||||
cell.title = self.datasource[indexPath.row];
|
||||
cell.title = [self.datasource safeObjectAtIndex1:indexPath.row];
|
||||
cell.delegate = self;
|
||||
NSString *showSwitch = [[NSUserDefaults standardUserDefaults] objectForKey:kCandyTreeHideMessage];
|
||||
cell.isShow = !showSwitch.length;
|
||||
|
@@ -1,270 +0,0 @@
|
||||
/**
|
||||
* Copyright © Sud.Tech
|
||||
* https://sud.tech
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSString (RW)
|
||||
#pragma mark - Hash
|
||||
///=============================================================================
|
||||
/// @name Hash
|
||||
///=============================================================================
|
||||
|
||||
/**
|
||||
Returns a lowercase NSString for md5 hash.
|
||||
*/
|
||||
- (nullable NSString *)md5String;
|
||||
|
||||
/**
|
||||
Returns a lowercase NSString for sha256 hash.
|
||||
*/
|
||||
- (nullable NSString *)sha256String;
|
||||
|
||||
/**
|
||||
Returns a lowercase NSString for sha1 hash.
|
||||
*/
|
||||
- (nullable NSString *)sha1String;
|
||||
|
||||
/**
|
||||
对self进行AES加密(返回加密后的Base64字符)
|
||||
|
||||
@param key A key length of 16, 24 or 32 (128, 192 or 256bits).
|
||||
@param iv An initialization vector length of 16(128bits).
|
||||
Pass nil when you don't want to use iv.
|
||||
|
||||
@return An NSString encrypted, or nil if an error occurs.
|
||||
*/
|
||||
- (nullable NSString *)aesEncryptWithKey:(NSString *)key iv:(nullable NSString *)iv;
|
||||
|
||||
/**
|
||||
对self进行AES解密(self为Base64字符)
|
||||
|
||||
@param key A key length of 16, 24 or 32 (128, 192 or 256bits).
|
||||
@param iv An initialization vector length of 16(128bits).
|
||||
Pass nil when you don't want to use iv.
|
||||
|
||||
@return An NSString encrypted, or nil if an error occurs.
|
||||
*/
|
||||
- (nullable NSString *)aesDecryptWithkey:(NSString *)key iv:(nullable NSString *)iv;
|
||||
|
||||
#pragma mark - Encode and decode
|
||||
///=============================================================================
|
||||
/// @name Encode and decode
|
||||
///=============================================================================
|
||||
|
||||
/**
|
||||
Returns an NSString for base64 encoded.
|
||||
*/
|
||||
- (nullable NSString *)base64EncodedString;
|
||||
|
||||
/**
|
||||
Returns an NSString from base64 encoded string.
|
||||
@param base64EncodedString string.
|
||||
*/
|
||||
+ (nullable NSString *)stringWithBase64EncodedString:(NSString *)base64EncodedString;
|
||||
|
||||
/**
|
||||
URL encode a string in utf-8.
|
||||
@return the encoded string.
|
||||
*/
|
||||
- (NSString *)stringByURLEncode;
|
||||
|
||||
/**
|
||||
URL decode a string in utf-8.
|
||||
@return the decoded string.
|
||||
*/
|
||||
- (NSString *)stringByURLDecode;
|
||||
|
||||
#pragma mark - Drawing
|
||||
///=============================================================================
|
||||
/// @name Drawing
|
||||
///=============================================================================
|
||||
|
||||
/**
|
||||
* 获取文本标签size
|
||||
* 截断方式为NSLineBreakByWordWrapping, 对齐方式默认为NSTextAlignmentLeft
|
||||
* @param font 字体
|
||||
* @param size 限定范围
|
||||
*
|
||||
* @return 返回文本标签实际size
|
||||
*/
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* 获取文本标签size
|
||||
* 对齐方式为NSTextAlignmentLeft
|
||||
* @param font 字体
|
||||
* @param size 限定范围
|
||||
* @param lineBreakMode 截断方式
|
||||
*
|
||||
* @return 返回文本标签实际size
|
||||
*/
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size withLineBreakingMode:(NSLineBreakMode)lineBreakMode;
|
||||
|
||||
/**
|
||||
* 获取文本标签size
|
||||
*
|
||||
* @param font 字体
|
||||
* @param size 限定范围
|
||||
* @param lineBreakingMode 截断方式
|
||||
* @param textAlignment 文字对齐类型
|
||||
*
|
||||
* @return 返回文本标签实际size
|
||||
*/
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size withLineBreakingMode:(NSLineBreakMode)lineBreakingMode withTextAlignment:(NSTextAlignment)textAlignment;
|
||||
|
||||
|
||||
/**
|
||||
Returns the width of the string if it were to be rendered with the specified
|
||||
font on a single line.
|
||||
|
||||
@param font The font to use for computing the string width.
|
||||
|
||||
@return The width of the resulting string's bounding box. These values may be
|
||||
rounded up to the nearest whole number.
|
||||
*/
|
||||
- (CGFloat)widthForFont:(UIFont *)font;
|
||||
|
||||
/**
|
||||
Returns the height of the string if it were rendered with the specified constraints.
|
||||
|
||||
@param font The font to use for computing the string size.
|
||||
|
||||
@param width The maximum acceptable width for the string. This value is used
|
||||
to calculate where line breaks and wrapping would occur.
|
||||
|
||||
@return The height of the resulting string's bounding box. These values
|
||||
may be rounded up to the nearest whole number.
|
||||
*/
|
||||
- (CGFloat)heightForFont:(UIFont *)font width:(CGFloat)width;
|
||||
|
||||
|
||||
#pragma mark - Utilities
|
||||
///=============================================================================
|
||||
/// @name Utilities
|
||||
///=============================================================================
|
||||
|
||||
/**
|
||||
Returns a new UUID NSString
|
||||
e.g. "D1178E50-2A4D-4F1F-9BD3-F6AAB00E06B1"
|
||||
*/
|
||||
+ (NSString *)stringWithUUID;
|
||||
|
||||
/**
|
||||
Trim blank characters (space and newline) in head and tail.
|
||||
@return the trimmed string.
|
||||
*/
|
||||
- (NSString *)stringByTrim;
|
||||
|
||||
/**
|
||||
nil, @"", @" ", @"\n" will Returns NO; otherwise Returns YES.
|
||||
*/
|
||||
- (BOOL)isNotBlank;
|
||||
|
||||
/**
|
||||
Returns YES if the target string is contained within the receiver.
|
||||
@param string A string to test the the receiver.
|
||||
|
||||
@discussion Apple has implemented this method in iOS8.
|
||||
*/
|
||||
- (BOOL)containsString:(NSString *)string;
|
||||
|
||||
/**
|
||||
Returns YES if the target string is contained within the receiver.
|
||||
@param string A string to test the the receiver.
|
||||
@param mask NSStringCompareOptions
|
||||
|
||||
*/
|
||||
- (BOOL)containsString:(NSString *)string options:(NSStringCompareOptions)mask;
|
||||
|
||||
/**
|
||||
Returns YES if the target string is hasPrefix within the receiver.
|
||||
default NSCaseInsensitiveSearch
|
||||
@param string A string to test the the receiver.
|
||||
|
||||
*/
|
||||
- (BOOL)hasInsensitivePrefix:(NSString *)string;
|
||||
|
||||
/**
|
||||
Returns YES if the target string is hasPrefix within the receiver.
|
||||
@param string A string to test the the receiver.
|
||||
@param mask NSStringCompareOptions
|
||||
|
||||
*/
|
||||
- (BOOL)hasPrefix:(NSString *)string options:(NSStringCompareOptions)mask;
|
||||
|
||||
/**
|
||||
Returns YES if the target CharacterSet is contained within the receiver.
|
||||
@param set A character set to test the the receiver.
|
||||
*/
|
||||
- (BOOL)containsCharacterSet:(NSCharacterSet *)set;
|
||||
|
||||
/**
|
||||
Returns an NSData using UTF-8 encoding.
|
||||
*/
|
||||
- (NSData *)dataValue;
|
||||
|
||||
/**
|
||||
Returns NSMakeRange(0, self.length).
|
||||
*/
|
||||
- (NSRange)rangeOfAll;
|
||||
|
||||
/**
|
||||
Returns an NSDictionary/NSArray which is decoded from receiver.
|
||||
Returns nil if an error occurs.
|
||||
|
||||
e.g. NSString: @"{"name":"a","count":2}" => NSDictionary: @[@"name":@"a",@"count":@2]
|
||||
*/
|
||||
- (id)jsonValueDecoded;
|
||||
|
||||
+ (NSString *) jsonStringWithDictionary:(NSDictionary *)dictionary;
|
||||
|
||||
|
||||
//密码需8-16位,至少包含字母、数字、符号2种组合
|
||||
+(BOOL)checkIsHaveNumAndLetter:(NSString*)sting;
|
||||
|
||||
/**
|
||||
中国电信号段为:133、149、153、173、177。还有180、181、189、199。
|
||||
|
||||
中国联通号段:130、131、132、145、155、156、166、171、175、176、185、186、166。
|
||||
|
||||
中国移动号段:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、172、178、182、183、184、187、188、198
|
||||
*/
|
||||
///判断是否为手机号
|
||||
- (BOOL)isPhoneNum;
|
||||
|
||||
///判断是否包含中文
|
||||
- (BOOL)isContainsChinese;
|
||||
|
||||
///包含特殊字符Special characters
|
||||
- (BOOL)isContainsSpecialCharacters;
|
||||
|
||||
///是否是纯数字
|
||||
+ (BOOL)isAllNumText:(NSString *)str;
|
||||
|
||||
///纯中文字符串
|
||||
+ (BOOL)isChineseCharacter:(NSString*)source;
|
||||
|
||||
///纯英文字符串
|
||||
+ (BOOL)isEnglishCharacter:(NSString*)source;
|
||||
|
||||
///纯特殊字符
|
||||
+ (BOOL)isAllCharacterString:(NSString *)string;
|
||||
|
||||
/// 包含emoji
|
||||
+ (BOOL)stringContainsEmoji:(NSString *)string;
|
||||
|
||||
|
||||
///去除字符串两端的空格和换行符
|
||||
- (NSString *)RW_stringByTrimmingCharacters;
|
||||
|
||||
/// 汉字转成拼音的方法
|
||||
+ (NSString *)chineseTransformToPinyin:(NSString *)chinese;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,522 +0,0 @@
|
||||
/**
|
||||
* Copyright © Sud.Tech
|
||||
* https://sud.tech
|
||||
*/
|
||||
|
||||
#import "NSString+RW.h"
|
||||
#import "NSData+RW.h"
|
||||
#import "NSArray+Safe.h"
|
||||
|
||||
@implementation NSString (RW)
|
||||
|
||||
-(NSString *)md5String {
|
||||
return [[self dataUsingEncoding:NSUTF8StringEncoding] md5String];
|
||||
}
|
||||
|
||||
- (NSString *)sha256String {
|
||||
return [[self dataUsingEncoding:NSUTF8StringEncoding] sha256String];
|
||||
}
|
||||
|
||||
- (NSString *)sha1String {
|
||||
return [[self dataUsingEncoding:NSUTF8StringEncoding] sha1String];
|
||||
}
|
||||
|
||||
- (nullable NSString *)aesEncryptWithKey:(NSString *)key iv:(nullable NSString *)iv {
|
||||
NSData * data = [self dataUsingEncoding:NSUTF8StringEncoding];
|
||||
data = [data aesEncryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]
|
||||
iv:[iv dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
//一般使用Base64, 使用UTF-8,一般会返回nil
|
||||
return [data base64EncodedString];
|
||||
}
|
||||
|
||||
- (nullable NSString *)aesDecryptWithkey:(NSString *)key iv:(nullable NSString *)iv {
|
||||
NSData * data = [NSData dataWithBase64EncodedString:self];
|
||||
data = [data aesDecryptWithkey:[key dataUsingEncoding:NSUTF8StringEncoding]
|
||||
iv:[iv dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSString * result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *)base64EncodedString {
|
||||
return [[self dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
|
||||
}
|
||||
|
||||
+ (NSString *)stringWithBase64EncodedString:(NSString *)base64EncodedString {
|
||||
NSData *data = [NSData dataWithBase64EncodedString:base64EncodedString];
|
||||
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)stringByURLEncode {
|
||||
if ([self respondsToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
|
||||
|
||||
static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
|
||||
static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
|
||||
|
||||
NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||
[allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
|
||||
static NSUInteger const batchSize = 50;
|
||||
|
||||
NSUInteger index = 0;
|
||||
NSMutableString *escaped = @"".mutableCopy;
|
||||
|
||||
while (index < self.length) {
|
||||
NSUInteger length = MIN(self.length - index, batchSize);
|
||||
NSRange range = NSMakeRange(index, length);
|
||||
// To avoid breaking up character sequences such as 👴🏻👮🏽
|
||||
range = [self rangeOfComposedCharacterSequencesForRange:range];
|
||||
NSString *substring = [self substringWithRange:range];
|
||||
NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
|
||||
[escaped appendString:encoded];
|
||||
|
||||
index += range.length;
|
||||
}
|
||||
return escaped;
|
||||
} else {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
|
||||
NSString *encoded = (__bridge_transfer NSString *)
|
||||
CFURLCreateStringByAddingPercentEscapes(
|
||||
kCFAllocatorDefault,
|
||||
(__bridge CFStringRef)self,
|
||||
NULL,
|
||||
CFSTR("!#$&'()*+,/:;=?@[]"),
|
||||
cfEncoding);
|
||||
return encoded;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringByURLDecode {
|
||||
if ([self respondsToSelector:@selector(stringByRemovingPercentEncoding)]) {
|
||||
return [self stringByRemovingPercentEncoding];
|
||||
} else {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
CFStringEncoding en = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
|
||||
NSString *decoded = [self stringByReplacingOccurrencesOfString:@"+"
|
||||
withString:@" "];
|
||||
decoded = (__bridge_transfer NSString *)
|
||||
CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
|
||||
NULL,
|
||||
(__bridge CFStringRef)decoded,
|
||||
CFSTR(""),
|
||||
en);
|
||||
return decoded;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
|
||||
{
|
||||
return [self textSizeWithFont:font constrainedToSize:size withLineBreakingMode:NSLineBreakByWordWrapping];
|
||||
}
|
||||
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size withLineBreakingMode:(NSLineBreakMode)lineBreakMode {
|
||||
return [self textSizeWithFont:font constrainedToSize:size withLineBreakingMode:NSLineBreakByWordWrapping withTextAlignment:NSTextAlignmentLeft];
|
||||
}
|
||||
|
||||
- (CGSize)textSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size withLineBreakingMode:(NSLineBreakMode)lineBreakingMode withTextAlignment:(NSTextAlignment)textAlignment
|
||||
{
|
||||
CGSize textSize;
|
||||
|
||||
NSMutableParagraphStyle *style = nil;
|
||||
style = [[NSMutableParagraphStyle alloc] init];
|
||||
style.lineBreakMode = lineBreakingMode;
|
||||
style.alignment = textAlignment;
|
||||
|
||||
NSMutableDictionary *attributes = [NSMutableDictionary new];
|
||||
attributes[NSFontAttributeName] = font;
|
||||
[attributes setValue:style forKey:NSParagraphStyleAttributeName];
|
||||
|
||||
if (CGSizeEqualToSize(size, CGSizeZero)) {
|
||||
textSize = [self sizeWithAttributes:attributes];
|
||||
}
|
||||
else {
|
||||
//NSStringDrawingTruncatesLastVisibleLine如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。 如果指定了NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略 NSStringDrawingUsesFontLeading计算行高时使用行间距。(译者注:字体大小+行间距=行高)
|
||||
NSStringDrawingOptions option = NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
|
||||
CGRect rect = [self boundingRectWithSize:size
|
||||
options:option
|
||||
attributes:attributes
|
||||
context:nil];
|
||||
textSize = rect.size;
|
||||
}
|
||||
|
||||
return textSize;
|
||||
}
|
||||
|
||||
- (CGFloat)widthForFont:(UIFont *)font {
|
||||
CGSize size = [self textSizeWithFont:font constrainedToSize:CGSizeMake(HUGE, HUGE)];
|
||||
return size.width;
|
||||
}
|
||||
|
||||
|
||||
- (CGFloat)heightForFont:(UIFont *)font width:(CGFloat)width {
|
||||
CGSize size = [self textSizeWithFont:font constrainedToSize:CGSizeMake(width, HUGE)];
|
||||
return size.height;
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)stringWithUUID {
|
||||
CFUUIDRef uuid = CFUUIDCreate(NULL);
|
||||
CFStringRef string = CFUUIDCreateString(NULL, uuid);
|
||||
CFRelease(uuid);
|
||||
return (__bridge_transfer NSString *)string;
|
||||
}
|
||||
|
||||
- (NSString *)stringByTrim {
|
||||
NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
return [self stringByTrimmingCharactersInSet:set];
|
||||
}
|
||||
|
||||
- (BOOL)isNotBlank {
|
||||
NSCharacterSet *blank = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
for (NSInteger i = 0; i < self.length; ++i) {
|
||||
unichar c = [self characterAtIndex:i];
|
||||
if (![blank characterIsMember:c]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)containsString:(NSString *)string {
|
||||
if (string == nil) return NO;
|
||||
return [self rangeOfString:string].location != NSNotFound;
|
||||
}
|
||||
|
||||
- (BOOL)containsString:(NSString *)string options:(NSStringCompareOptions)mask{
|
||||
if (string == nil) return NO;
|
||||
return [self rangeOfString:string options:mask].location != NSNotFound;
|
||||
}
|
||||
|
||||
- (BOOL)hasInsensitivePrefix:(NSString *)string{
|
||||
if (string == nil) return NO;
|
||||
NSString *commonStr = [self commonPrefixWithString:string options:NSCaseInsensitiveSearch];
|
||||
if ([commonStr caseInsensitiveCompare:string] == NSOrderedSame) {
|
||||
return YES;
|
||||
}else{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasPrefix:(NSString *)string options:(NSStringCompareOptions)mask{
|
||||
if (string == nil) return NO;
|
||||
NSString *commonStr = [self commonPrefixWithString:string options:mask];
|
||||
if ([commonStr caseInsensitiveCompare:string] == NSOrderedSame) {
|
||||
return YES;
|
||||
}else{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)containsCharacterSet:(NSCharacterSet *)set {
|
||||
if (set == nil) return NO;
|
||||
return [self rangeOfCharacterFromSet:set].location != NSNotFound;
|
||||
}
|
||||
|
||||
- (NSData *)dataValue {
|
||||
return [self dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSRange)rangeOfAll {
|
||||
return NSMakeRange(0, self.length);
|
||||
}
|
||||
|
||||
- (id)jsonValueDecoded {
|
||||
return [[self dataValue] jsonValueDecoded];
|
||||
}
|
||||
|
||||
|
||||
-(NSString*)coverBodyWithLength:(NSInteger)length
|
||||
{
|
||||
NSMutableString* body = [NSMutableString new];
|
||||
for(int i=0;i<length;i++)
|
||||
{
|
||||
[body appendString:@"*"];
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
+(NSString *) jsonStringWithDictionary:(NSDictionary *)dictionary{
|
||||
NSArray *keys = [dictionary allKeys];
|
||||
NSMutableString *reString = [NSMutableString string];
|
||||
[reString appendString:@"{"];
|
||||
NSMutableArray *keyValues = [NSMutableArray array];
|
||||
for(int i=0; i<[keys count]; i++) {
|
||||
NSString *name = [keys safeObjectAtIndex1:i];
|
||||
id valueObj = [dictionary objectForKey:name];
|
||||
NSString *value = [NSString jsonStringWithObject:valueObj];
|
||||
if(value) {
|
||||
[keyValues addObject:[NSString stringWithFormat:@"\"%@\":%@",name,value]];
|
||||
}
|
||||
}
|
||||
[reString appendFormat:@"%@",[keyValues componentsJoinedByString:@","]];
|
||||
[reString appendString:@"}"];
|
||||
return reString;
|
||||
}
|
||||
+(NSString *)jsonStringWithObject:(id) object{
|
||||
NSString *value =nil;
|
||||
if(!object) {
|
||||
return value;
|
||||
}
|
||||
if([object isKindOfClass:[NSString class]]) {
|
||||
value = [NSString jsonStringWithString:object];
|
||||
}else if([object isKindOfClass:[NSDictionary class]]){
|
||||
value = [NSString jsonStringWithDictionary:object];
|
||||
}else if([object isKindOfClass:[NSArray class]]){
|
||||
value = [NSString jsonStringWithArray:object];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+(NSString *) jsonStringWithString:(NSString *) string{
|
||||
return[NSString stringWithFormat:@"\"%@\"",
|
||||
[[string stringByReplacingOccurrencesOfString:@"\n"withString:@"\\n"] stringByReplacingOccurrencesOfString:@"\""withString:@"\\\""]
|
||||
];
|
||||
}
|
||||
|
||||
+(NSString *) jsonStringWithArray:(NSArray *)array{
|
||||
NSMutableString *reString = [NSMutableString string];
|
||||
[reString appendString:@"["];
|
||||
NSMutableArray *values = [NSMutableArray array];
|
||||
for(id valueObj in array) {
|
||||
NSString *value = [NSString jsonStringWithObject:valueObj];
|
||||
if(value) {
|
||||
[values addObject:[NSString stringWithFormat:@"%@",value]];
|
||||
}
|
||||
}
|
||||
[reString appendFormat:@"%@",[values componentsJoinedByString:@","]];
|
||||
[reString appendString:@"]"];
|
||||
return reString;
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)checkIsHaveNumAndLetter:(NSString *)sting{
|
||||
|
||||
//如果要限定特殊字符,例如,特殊字符的范围为 !#$%^&* ,那么可以这么改
|
||||
// ^(?![\d]+$)(?![a-zA-Z]+$)(?![!#$%^&*]+$)[\da-zA-Z!#$%^&*]{8,16}$
|
||||
|
||||
//表示不包含emoji表情、汉字,以及空格与回车,里面的符合可以自动补充或删除;
|
||||
NSString *regex = @"^(?![\\d]+$)(?![a-zA-Z]+$)(?![^\\da-zA-Z]+$).{8,16}$";
|
||||
NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
|
||||
return [regextestmobile evaluateWithObject:sting];
|
||||
|
||||
|
||||
// 正则表达式:1、(?!.*[!·(){}【】“”:;,》¥、。‘’——\\s-……%\\n]) 表示的是不含中文的特殊字符,以及空格与回车,里面的符合可以自动补充或删除;
|
||||
//
|
||||
// 2、(?=.*[a-zA-Z]) 表示含小写或大写的英文字母
|
||||
//
|
||||
// 3、(?=.*\\d) 表示必须匹配到数字
|
||||
//
|
||||
// 4、(?=.*[~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/]) 表示含英文的特殊字符,里面的符合可以自动补充或删除
|
||||
//
|
||||
// 5、[^\\u4e00-\\u9fa5] 表示不允许有中文 ;表示允许有中文的,即:[\\u4e00-\\u9fa5]
|
||||
//
|
||||
// 6、{6,12} 表示长度要求,6~12位
|
||||
// 表示的是不含中文的特殊字符,以及空格与回车,里面的符合可以自动补充或删除;
|
||||
// NSString *regex = @"^(?!.*[!·(){}【】“”:;,》¥、。‘’——\\s-……%\\n])(?=.*[a-zA-Z])(?=.*\\d)(?=.*[~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/])[^\\u4e00-\\u9fa5]{8,16}$";
|
||||
|
||||
|
||||
//
|
||||
// //数字条件
|
||||
// NSRegularExpression *tNumRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[0-9]" options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
//
|
||||
// //符合数字条件的有几个字节
|
||||
// NSUInteger tNumMatchCount = [tNumRegularExpression numberOfMatchesInString:sting
|
||||
// options:NSMatchingReportProgress
|
||||
// range:NSMakeRange(0, sting.length)];
|
||||
// //英文字条件
|
||||
// NSRegularExpression *tLetterRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[A-Za-z]" options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
//
|
||||
// //英文特殊字符条件
|
||||
// NSRegularExpression *specialRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[~!@#$%^&*()_+`\\-={}[]:\";'<>?,.\\/!·(){}【】“”:;,》¥、。‘’——\\s-……%\\n]" options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
//
|
||||
// //符合英文字条件的有几个字节
|
||||
// NSUInteger tLetterMatchCount = [tLetterRegularExpression numberOfMatchesInString:sting options:NSMatchingReportProgress range:NSMakeRange(0, sting.length)];
|
||||
// if (tNumMatchCount == sting.length) { //全部符合数字,表示沒有英文
|
||||
// return 1;
|
||||
//
|
||||
// } else if (tLetterMatchCount == sting.length) { //全部符合英文,表示沒有数字
|
||||
// return 2;
|
||||
//
|
||||
// } else if (tNumMatchCount + tLetterMatchCount == sting.length) { //符合英文和符合数字条件的相加等于密码长度
|
||||
// return 3;
|
||||
//
|
||||
// }else { //可能包含标点符号的情況,或是包含非英文的文字
|
||||
// return 4;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isPhoneNum
|
||||
{
|
||||
NSString *MOBILE = @"^1(3[0-9]|4[579]|5[0-35-9]|6[6]|7[0-35-9]|8[0-9]|9[89])\\d{8}$";
|
||||
NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
|
||||
return [regextestmobile evaluateWithObject:self];
|
||||
}
|
||||
|
||||
-(BOOL)isContainsChinese{
|
||||
|
||||
for(int i=0; i< [self length];i++)
|
||||
{
|
||||
int a = [self characterAtIndex:i];
|
||||
if( a > 0x4E00 && a < 0x9FFF)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isContainsSpecialCharacters{
|
||||
|
||||
NSString *str =@"^[A-Za-z0-9\\u4e00-\u9fa5]+$";
|
||||
NSPredicate* emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", str];
|
||||
if (![emailTest evaluateWithObject:self]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
//是否是纯数字
|
||||
+ (BOOL)isAllNumText:(NSString *)str{
|
||||
|
||||
NSString *regex =@"[0-9]*";
|
||||
|
||||
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
|
||||
|
||||
if ([pred evaluateWithObject:str]) {
|
||||
|
||||
return YES;
|
||||
|
||||
}
|
||||
|
||||
return NO;
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)isChineseCharacter:(NSString*)source {
|
||||
|
||||
NSString *regex = @"^[\\u4E00-\\u9FEA]+$";
|
||||
|
||||
return ([source rangeOfString:regex options:NSRegularExpressionSearch].length>0);
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)isEnglishCharacter:(NSString*)source {
|
||||
|
||||
NSString *upperRegex = @"^[\\u0041-\\u005A]+$";
|
||||
|
||||
NSString *lowerRegex = @"^[\\u0061-\\u007A]+$";
|
||||
|
||||
BOOL isEnglish = (([source rangeOfString:upperRegex options:NSRegularExpressionSearch].length>0) || ([source rangeOfString:lowerRegex options:NSRegularExpressionSearch].length>0));
|
||||
|
||||
return isEnglish;
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)isAllCharacterString:(NSString *)string
|
||||
{
|
||||
NSString *regex = @"[~`!@#$%^&*()_+-=[]|{};':\",./<>?]{,}/";//规定的特殊字符,可以自己随意添加
|
||||
|
||||
//计算字符串长度
|
||||
NSInteger str_length = [string length];
|
||||
|
||||
NSInteger allIndex = 0;
|
||||
for (int i = 0; i<str_length; i++) {
|
||||
//取出i
|
||||
NSString *subStr = [string substringWithRange:NSMakeRange(i, 1)];
|
||||
if([regex rangeOfString:subStr].location != NSNotFound)
|
||||
{ //存在
|
||||
allIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (str_length == allIndex) {
|
||||
//纯特殊字符
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
//非纯特殊字符
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
/// 包含emoji
|
||||
+ (BOOL)stringContainsEmoji:(NSString *)string{
|
||||
|
||||
__block BOOL returnValue = NO;
|
||||
[string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences
|
||||
|
||||
usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
|
||||
const unichar hs = [substring characterAtIndex:0];
|
||||
NSLog(@"hs:%c",hs);
|
||||
if (0xd800 <= hs && hs <= 0xdbff){
|
||||
|
||||
if (substring.length > 1){
|
||||
const unichar ls = [substring characterAtIndex:1];
|
||||
const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
|
||||
if (0x1d000 <= uc && uc <= 0x1f918){
|
||||
returnValue = YES;
|
||||
}
|
||||
}
|
||||
}else if (substring.length > 1){
|
||||
|
||||
const unichar ls = [substring characterAtIndex:1];
|
||||
if (ls == 0x20e3 || ls == 0xFE0F || ls == 0xd83c){
|
||||
returnValue = YES;
|
||||
}
|
||||
}else{
|
||||
if (0x2100 <= hs && hs <= 0x27ff){
|
||||
|
||||
if (0x278b <= hs && 0x2792 >= hs){
|
||||
returnValue = NO;
|
||||
}else{
|
||||
returnValue = YES;
|
||||
}
|
||||
|
||||
}else if (0x2B05 <= hs && hs <= 0x2b07){
|
||||
returnValue = YES;
|
||||
}else if (0x2934 <= hs && hs <= 0x2935){
|
||||
returnValue = YES;
|
||||
}else if (0x3297 <= hs && hs <= 0x3299){
|
||||
returnValue = YES;
|
||||
}else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50 || hs == 0xd83e){
|
||||
returnValue = YES;
|
||||
}
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)RW_stringByTrimmingCharacters{
|
||||
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
}
|
||||
|
||||
+ (NSString *)chineseTransformToPinyin:(NSString *)chinese{
|
||||
CFStringRef hanzi = (__bridge CFStringRef)(chinese);
|
||||
CFMutableStringRef string = CFStringCreateMutableCopy(NULL, 0, hanzi);
|
||||
|
||||
// Boolean CFStringTransform(CFMutableStringRef string, CFRange *range, CFStringRef transform, Boolean reverse);
|
||||
//string 为要转换的字符串
|
||||
// range 要转换的范围,NULL 则为全部
|
||||
//transform 要进行怎么样的转换 //kCFStringTransformMandarinLatin 将汉字转拼音
|
||||
//reverse 是否支持逆向转换
|
||||
CFStringTransform(string, NULL, kCFStringTransformMandarinLatin, NO);
|
||||
|
||||
//kCFStringTransformStripDiacritics去掉声调
|
||||
CFStringTransform(string, NULL, kCFStringTransformStripDiacritics, NO);
|
||||
|
||||
NSString * pinyin = (NSString *) CFBridgingRelease(string);
|
||||
//将中间分隔符号去掉
|
||||
pinyin = [pinyin stringByReplacingOccurrencesOfString:@" " withString: @""];
|
||||
|
||||
return pinyin;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Copyright © Sud.Tech
|
||||
* https://sud.tech
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#ifndef RGBA
|
||||
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
|
||||
#endif
|
||||
|
||||
#ifndef RGB
|
||||
#define RGB(r, g, b) RGBA(r, g, b, 1.0f)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Create UIColor with a hex string.
|
||||
Example: UIColorHex(0xF0F), UIColorHex(66ccff), UIColorHex(#66CCFF88)
|
||||
|
||||
Valid format: #RGB #RGBA #RRGGBB #RRGGBBAA 0xRGB ...
|
||||
The `#` or "0x" sign is not required.
|
||||
*/
|
||||
#ifndef UIColorHex
|
||||
#define UIColorHex(_hex_) [UIColor RW_colorWithHexString:((__bridge NSString *)CFSTR(#_hex_))]
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* 所有方法前面全部加pawf_, 避免与其他接入的库的category重名导致未知问题.
|
||||
* 注: colorWithHexString 与接入的某个库有冲突
|
||||
*/
|
||||
@interface UIColor (RW)
|
||||
|
||||
#pragma mark - Create a UIColor Object
|
||||
///=============================================================================
|
||||
/// @name Creating a UIColor Object
|
||||
///=============================================================================
|
||||
|
||||
/**
|
||||
Creates and returns a color object using the hex RGB color values.
|
||||
|
||||
@param rgbValue The rgb value such as 0x66ccff.
|
||||
|
||||
@return The color object. The color information represented by this
|
||||
object is in the device RGB colorspace.
|
||||
*/
|
||||
+ (UIColor *)RW_colorWithRGB:(uint32_t)rgbValue;
|
||||
|
||||
/**
|
||||
Creates and returns a color object using the hex RGBA color values.
|
||||
|
||||
@param rgbaValue The rgb value such as 0x66ccffff.
|
||||
|
||||
@return The color object. The color information represented by this
|
||||
object is in the device RGB colorspace.
|
||||
*/
|
||||
+ (UIColor *)RW_colorWithRGBA:(uint32_t)rgbaValue;
|
||||
|
||||
/**
|
||||
Creates and returns a color object using the specified opacity and RGB hex value.
|
||||
|
||||
@param rgbValue The rgb value such as 0x66CCFF.
|
||||
|
||||
@param alpha The opacity value of the color object,
|
||||
specified as a value from 0.0 to 1.0.
|
||||
|
||||
@return The color object. The color information represented by this
|
||||
object is in the device RGB colorspace.
|
||||
*/
|
||||
+ (UIColor *)RW_colorWithRGB:(uint32_t)rgbValue alpha:(CGFloat)alpha;
|
||||
|
||||
/**
|
||||
Creates and returns a color object from hex string.
|
||||
|
||||
@discussion:
|
||||
Valid format: #RGB #RGBA #RRGGBB #RRGGBBAA 0xRGB ...
|
||||
The `#` or "0x" sign is not required.
|
||||
The alpha will be set to 1.0 if there is no alpha component.
|
||||
It will return nil when an error occurs in parsing.
|
||||
|
||||
Example: @"0xF0F", @"66ccff", @"#66CCFF88"
|
||||
|
||||
@param hexStr The hex string value for the new color.
|
||||
|
||||
@return An UIColor object from string, or nil if an error occurs.
|
||||
*/
|
||||
+ (nullable UIColor *)RW_colorWithHexString:(NSString *)hexStr;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
* Copyright © Sud.Tech
|
||||
* https://sud.tech
|
||||
*/
|
||||
|
||||
#import "UIColor+RW.h"
|
||||
#import "NSString+RW.h"
|
||||
|
||||
|
||||
@implementation UIColor (RW)
|
||||
|
||||
+ (UIColor *)RW_colorWithRGB:(uint32_t)rgbValue {
|
||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0f
|
||||
green:((rgbValue & 0xFF00) >> 8) / 255.0f
|
||||
blue:(rgbValue & 0xFF) / 255.0f
|
||||
alpha:1];
|
||||
}
|
||||
|
||||
+ (UIColor *)RW_colorWithRGBA:(uint32_t)rgbaValue {
|
||||
return [UIColor colorWithRed:((rgbaValue & 0xFF000000) >> 24) / 255.0f
|
||||
green:((rgbaValue & 0xFF0000) >> 16) / 255.0f
|
||||
blue:((rgbaValue & 0xFF00) >> 8) / 255.0f
|
||||
alpha:(rgbaValue & 0xFF) / 255.0f];
|
||||
}
|
||||
|
||||
+ (UIColor *)rw_colorWithRGB:(uint32_t)rgbValue alpha:(CGFloat)alpha {
|
||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0f
|
||||
green:((rgbValue & 0xFF00) >> 8) / 255.0f
|
||||
blue:(rgbValue & 0xFF) / 255.0f
|
||||
alpha:alpha];
|
||||
}
|
||||
|
||||
+ (instancetype)RW_colorWithHexString:(NSString *)hexStr {
|
||||
CGFloat r, g, b, a;
|
||||
if (hexStrToRGBA(hexStr, &r, &g, &b, &a)) {
|
||||
return [UIColor colorWithRed:r green:g blue:b alpha:a];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static inline NSUInteger hexStrToInt(NSString *str) {
|
||||
uint32_t result = 0;
|
||||
sscanf([str UTF8String], "%X", &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL hexStrToRGBA(NSString *str,
|
||||
CGFloat *r, CGFloat *g, CGFloat *b, CGFloat *a) {
|
||||
str = [[str stringByTrim] uppercaseString];
|
||||
if ([str hasPrefix:@"#"]) {
|
||||
str = [str substringFromIndex:1];
|
||||
} else if ([str hasPrefix:@"0X"]) {
|
||||
str = [str substringFromIndex:2];
|
||||
}
|
||||
|
||||
NSUInteger length = [str length];
|
||||
// RGB RGBA RRGGBB RRGGBBAA
|
||||
if (length != 3 && length != 4 && length != 6 && length != 8) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
//RGB,RGBA,RRGGBB,RRGGBBAA
|
||||
if (length < 5) {
|
||||
*r = hexStrToInt([str substringWithRange:NSMakeRange(0, 1)]) / 255.0f;
|
||||
*g = hexStrToInt([str substringWithRange:NSMakeRange(1, 1)]) / 255.0f;
|
||||
*b = hexStrToInt([str substringWithRange:NSMakeRange(2, 1)]) / 255.0f;
|
||||
if (length == 4) *a = hexStrToInt([str substringWithRange:NSMakeRange(3, 1)]) / 255.0f;
|
||||
else *a = 1;
|
||||
} else {
|
||||
*r = hexStrToInt([str substringWithRange:NSMakeRange(0, 2)]) / 255.0f;
|
||||
*g = hexStrToInt([str substringWithRange:NSMakeRange(2, 2)]) / 255.0f;
|
||||
*b = hexStrToInt([str substringWithRange:NSMakeRange(4, 2)]) / 255.0f;
|
||||
if (length == 8) *a = hexStrToInt([str substringWithRange:NSMakeRange(6, 2)]) / 255.0f;
|
||||
else *a = 1;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
@@ -5,10 +5,9 @@
|
||||
|
||||
#import "SudCommon.h"
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
#import "UIColor+RW.h"
|
||||
#import <SudMGP/SudMGP.h>
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#import "ThemeColor.h"
|
||||
|
||||
@implementation SudCommon
|
||||
/// 获取用户名
|
||||
@@ -84,7 +83,7 @@
|
||||
|
||||
+ (NSMutableAttributedString *)getAttributedStringWithString:(NSString *)string color:(NSString*)color {
|
||||
NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc]initWithString:string];
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor RW_colorWithHexString:color] range:NSMakeRange(0, attributedString.length)];
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:[ThemeColor colorWithHexString:color] range:NSMakeRange(0, attributedString.length)];
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#import "AccountInfoStorage.h"
|
||||
#import "XPConstant.h"
|
||||
#import "XCHUDTool.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///Model
|
||||
#import "XPMessageRemoteExtModel.h"
|
||||
#import "UserInfoModel.h"
|
||||
@@ -71,13 +72,13 @@
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
XPRoomQuidkMessageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPRoomQuidkMessageCell class]) forIndexPath:indexPath];
|
||||
if (self.titleArray.count > 0) {
|
||||
cell.title = self.titleArray[indexPath.row];
|
||||
cell.title = [self.titleArray safeObjectAtIndex1:indexPath.row];
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *str = self.titleArray[indexPath.row];
|
||||
NSString *str = [self.titleArray safeObjectAtIndex1:indexPath.row];
|
||||
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:12]};
|
||||
CGSize size = [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 25) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil].size;
|
||||
return CGSizeMake(size.width + 10, 30);
|
||||
@@ -93,7 +94,7 @@
|
||||
return;
|
||||
}
|
||||
self.lastSendTime = time2;
|
||||
NSString *str = self.titleArray[indexPath.row];
|
||||
NSString *str = [self.titleArray safeObjectAtIndex1:indexPath.row];
|
||||
[self sendText:str];
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@
|
||||
///Tool
|
||||
#import "XPMacro.h"
|
||||
#import "ThemeColor.h"
|
||||
#import "NSArray+Safe.h"
|
||||
///View
|
||||
#import "XPRoomInsideRecommendCell.h"
|
||||
#import "XPRoomInsideRecommendEmptyCell.h"
|
||||
@@ -79,8 +80,8 @@
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
XPRoomInsideOperationCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPRoomInsideOperationCell class]) forIndexPath:indexPath];
|
||||
cell.title = self.titleArray[indexPath.row];
|
||||
cell.imageName = self.imageArray[indexPath.row];
|
||||
cell.title = [self.titleArray safeObjectAtIndex1:indexPath.row];
|
||||
cell.imageName = [self.imageArray safeObjectAtIndex1:indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (self.roomList.count > 0) {
|
||||
XPRoomInsideRecommendCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPRoomInsideRecommendCell class])];
|
||||
XPRoomRecommendModel *model = self.roomList[indexPath.row];
|
||||
XPRoomRecommendModel *model = [self.roomList safeObjectAtIndex1:indexPath.row];
|
||||
cell.model = model;
|
||||
return cell;
|
||||
}
|
||||
@@ -126,7 +127,7 @@
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if (self.roomList.count > 0) {
|
||||
XPRoomRecommendModel *model = self.roomList[indexPath.row];
|
||||
XPRoomRecommendModel *model = [self.roomList safeObjectAtIndex1:indexPath.row];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(xPRoomRecommendViewJumpToRoom:)]) {
|
||||
[self.delegate xPRoomRecommendViewJumpToRoom:[NSString stringWithFormat:@"%ld", model.uid]];
|
||||
}
|
||||
|
@@ -833,7 +833,9 @@ UIKIT_EXTERN NSString *kTabShowAnchorCardKey;
|
||||
@kStrongify(self);
|
||||
if (finished) {
|
||||
[view removeFromSuperview];
|
||||
[self.giftBroadcastQueue removeObjectAtIndex:0];
|
||||
if (self.giftBroadcastQueue.count > 0) {
|
||||
[self.giftBroadcastQueue removeObjectAtIndex:0];
|
||||
}
|
||||
if (self.giftBroadcastQueue.count > 0) {
|
||||
[self createGiftBroadcastViewAnimation:self.giftBroadcastQueue.firstObject];
|
||||
}
|
||||
|
Reference in New Issue
Block a user