目錄
1、代碼中更改Icon圖標
1. 代碼中更改Icon圖標(更換圖標,會彈出確認框,僅支持13及以上系統)
第1步. 修改Info.plist
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>原AppIcon圖標名</string>
</array>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>icon01</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon圖標名2</string>
</array>
</dict>
<key>icon02</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon圖標名3</string>
</array>
</dict>
</dict>
</dict>
第2步. 將所有AppIcon放入工程中(不要放在Assets.xcassets)
第3步. 代碼
// 更換
if ([UIApplication sharedApplication].supportsAlternateIcons) {
[[UIApplication sharedApplication] setAlternateIconName:圖標名key字符串 completionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"success:%@",圖標名);
}else{
NSLog(@"error:%@",error);
}
}];
} else {
NSLog(@"不能更換icon");
return;
}
}
// 還原
if ([UIApplication sharedApplication].alternateIconName != nil) { // 圖標被替換過
// 重置icon
[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"success");
} else {
NSLog(@"error:%@",error);
}
}];
}
示例
dispatch_async(dispatch_get_main_queue(), ^{
// 更換圖標,會彈出確認框
if (@available(iOS 10.3, *)) {
if ([UIApplication sharedApplication].supportsAlternateIcons) {
[[UIApplication sharedApplication] setAlternateIconName:@"icon01" completionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"success:%@",@"icon02");
}else{
NSLog(@"error:%@",error);
}
}];
} else {
NSLog(@"不能更換icon");
return;
}
} else {
// Fallback on earlier versions
}
});
2. 制作靜態庫
庫是代碼集合,是共享代碼的一種方式。2種方式:
開源:公開源代碼
閉源:靜態庫(.a .framework) / 動態庫(.dylib .framework)
靜態庫:在鏈接階段,會將文件完全復制過來。冗余占內存
動態庫:程序運行時有系統加載到內存供程序調用,僅加載一次。
注意
自定義的動態庫不允許上傳AppStore
.a文件(純二進制)不能單獨使用,需要.h配合。
.framework文件(包含二進制,.h,plist等)可單獨使用。
制作.a
1.新建項目(選擇CocoaTouch StaticLibrary),并寫入相關代碼
2.項目|buildPhases|+|New Header Phase|拖入對外頭文件
3.選擇真機編譯(拿到.a),選擇模擬器編譯(拿到.a) (2者是不一樣的,Debug-iphoneos文件夾中是真機,Debug-iphonesimulator文件夾中是模擬器)
4.終端合并2.a (lipo -create Debug-iphoneos/xxx.a Debug-iphonesimulator/xxx.a -output xxx.a) 可改變路徑 /Users/cx/Desktop/...
5.使用.a, 將.a和include中的文件拖入項目中
制作.framework
1.新建項目(選擇CocoaTouch Framework),并寫入相關代碼
2.項目|buildPhases|+|New Header Phase|拖入對外頭文件
項目|編輯區左上角Add Target|Cross-platform|Aggregate| Build Phases | + | NewRunScript Phase
# Sets the target folders and the final framework product.
# 如果工程名稱和Framework的Target名稱不一樣的話,要自定義FMKNAME
# 例如: FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME}
# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target"${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target"${FMK_NAME}" -sdk iphonesimulator clean build
# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/""${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}""${SIMULATOR_DIR}/${FMK_NAME}" -output"${INSTALL_DIR}/${FMK_NAME}"
rm -r "${WRK_DIR}"
open "${SRCROOT}/Products/"
項目|項目target|Build Settings|Mach-O Type 選擇StaticLibrary
選擇AggregateTarget進行編譯(自動彈出Product文件夾)
使用
導入.framework
#import<>
查看支持的arm架構
lipo -info framework
制作.bundle
bundle文件:靜態文件,不參加編譯,作為資源解析成特殊的二進制數據
新建bundle
新建項目(選擇macOS|bundle)| 放入圖片 | 編譯 | 拿到.bundle
使用
[UIImageimageNamed:@"TestBundle.bundle/Contents/Resources/1.png"]
記錄崩潰日志
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 設置處理崩潰方法(閃退時調用)
NSSetUncaughtExceptionHandler(&ExceptionHandler);
}
void ExceptionHandler(NSException *exception){
//
NSArray *arr=[exception callStackSymbols];
// 閃退原因
NSString *reason=[exception reason];
// 閃退名
NSString *name=[exception name];
// 當前版本號
NSString *currentVersion=[[[NSBundle mainBundle]infoDictionary]objectForKey:@"CFBundleversion"];
// 調接口
}
唯一標識
在iOS5前可以獲取唯一標識UDID(Unique Device Identifier)。
思路(在非越獄的手機上):
1.獲取某個硬件信息生成唯一標識。第一找蘋果的漏洞,第二調用私有接口。不可持續發展
2.獲取操作系統信息生成唯一標識。在系統升級、卸載重裝、備份恢復都可以保留,但重置手機系統會清除。
國內
友盟用的是 Openudid + IDFA
TalkingData用的是 Keychain + IDFA
Openudid
github上開源項目
原理:利用iOS系統中的UIPasteboard剪貼板類通過鍵值對來存儲一個160位的隨機字符串。
iOS7之后,蘋果封堵了剪貼板通信的漏洞,之前所有的應用都可以共享同一個剪貼板存儲內容。現在只有在同一CFBundleIdentifier標識下的App才能共享內容,如com.koudai.a和com.koudai.b。
keychain
keychain鑰匙串,是一個蘋果用來存儲密碼和證書的加密存儲區域,目的是為了幫助用戶安全存儲應用或者瀏覽器的密碼,減少了很多輸入密碼和記密碼的麻煩。
keychain存儲在手機的某個公共區域(不是沙盒),因此卸載應用并不影響但重置系統會清除,可以拿keychain來存儲唯一標識。
UUID, 全球獨立標識(Globally Unique Identifier)
重復概率為170億分之一
NSString *uuid = [[NSUUID UUID] UUIDString];
IDFA
ASIdentifierManager單例(AdSupport.framework框架)提供了一個方法advertisingIdentifier,返回一個的NSUUID實例
重置系統或還原廣告標示符(設置程序|通用|關于本機|廣告|還原廣告標示符)是會清除
使用IDFA(必須勾選IDFA選項)但未集成任何廣告服務的應用審核都會被拒