一.一個項目的開始搭建
1.工具類的文件可以直接用之前項目的。
二.Cocopod導入需要的庫。
cd 項目位置
然后添加podfile文件:vim podfile (注:在寫該文件的時候要注意格式??? ' '?? );
進入后按i進入插入模式,進行編輯,安裝官方最新的文檔格式:
platform :ios, '8.0'
target '你的項目名稱' do
pod 'AFNetworking', '~> 3.0'
end
編輯完成后,按ESC退出編輯模式,最后輸入:wq保存并退出文件,此時可以發現在項目目錄下多了一個Podfile的文件,請注意這個文件必須與.xcodeproj在同一目錄下,
最后:pod install進行安裝即可
三.基礎頁面的搭建。
1.基類的viewcontroller,基類的WKWebViewController.
四.與后臺對接接口。
/**
*發送get請求
*
*@param url url
*@param params發送的參數
*@param success成功回調
*@param failure失敗回調
*/
+ (void)get:(NSString*)url params:(nullableNSDictionary*)params showHud:(BOOL)showHudsuccess:(void(^)(id__nullablejson))success failure:(void(^)(NSError*error))failure{
// 1.創建請求管理者}
AFHTTPSessionManager*mgr = [AFHTTPSessionManagermanager];
//mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
mgr.requestSerializer= [AFHTTPRequestSerializerserializer];
//添加證書
[mgrsetSecurityPolicy:[QWAFSecurityPolicycustomSecurityPolicy]];
mgr.requestSerializer.timeoutInterval=30;
mgr.responseSerializer.acceptableContentTypes= [NSSetsetWithObjects:@"application/json",@"text/json",@"text/xml",@"text/plain",@"text/html",@"image/png",nil];
[mgrGET:urlparameters:paramsprogress:^(NSProgress*_NonnulldownloadProgress) {
}success:^(NSURLSessionDataTask*_Nonnulltask,id_NullableresponseObject) {
if(showHud) {
[hudhideAnimated:YES];
}
if(success) {
//NSString *online = [NSString stringWithFormat:@"%@",responseObject[@"online"]];
//[QWAccountModel sharedModel].isOnline = [online boolValue];
success(responseObject);
}
}failure:^(NSURLSessionDataTask*_Nullabletask,NSError*_Nonnullerror) {
if(showHud) {
[hudhideAnimated:YES];
}
//[MBProgressHUD hideHUD];
//[TJShowMessage showMessage:@"網絡異常,請重新加載"];
//[[NSNotificationCenter defaultCenter] postNotificationName:TJReloadDataFailedNotification object:nil];
if(failure) {
failure(error);
}
}];
+ (void)postmanager:(NSString*)url params:(NSDictionary*)params success:(void(^)(idmanager,idjson))success failure:(void(^)(
NSError*error))failure{
AFHTTPSessionManager*mgr = [AFHTTPSessionManagermanager];
mgr.requestSerializer= [AFHTTPRequestSerializerserializer];
//添加證書
[mgrsetSecurityPolicy:[QWAFSecurityPolicycustomSecurityPolicy]];
mgr.requestSerializer.timeoutInterval=30;
mgr.responseSerializer.acceptableContentTypes= [NSSetsetWithObjects:@"application/json",@"text/json",@"text/xml",@"text/plain",@"text/html",nil];
[mgrPOST:urlparameters:paramsprogress:nilsuccess:^(NSURLSessionDataTask*_Nonnulltask,id_NullableresponseObject) {
if(success) {success(task, responseObject);
}
}failure:^(NSURLSessionDataTask*_Nullabletask,NSError*_Nonnullerror) {
if(failure) {failure(error);
}
加密驗簽。
//生成sign
+ (NSString*)getSignAndSignDict:(NSMutableDictionary*)dict
{
NSMutableDictionary*dic = [NSMutableDictionarydictionaryWithDictionary:dict];
[dicsetValue:VersionforKey:@"version"];
[dicsetValue:[CommonFunctime]forKey:@"timeStamp"];
[dicsetValue:PtforKey:@"pt"];
[dicsetValue:ImeiforKey:@"imei"];
NSString*singstr = [selfsortDicToString:dic];
returnsingstr;
}
//排序驗簽
+ (NSString*) sortDicToString:(NSMutableDictionary*)dic{
//排序
NSMutableArray*stringArray = [NSMutableArrayarrayWithArray:dic.allKeys];
[stringArraysortUsingComparator: ^NSComparisonResult(NSString*str1,NSString*str2) {
return[str1compare:str2];
}];
//驗簽
NSString*md5StrPre =@"";
for(inti =0; i < [stringArraycount]; i++) {
NSString*key = [stringArrayobjectAtIndex:i];
md5StrPre = [md5StrPrestringByAppendingString:[dicobjectForKey:key]];
}
NSString*getKey =QWKey;
md5StrPre = [md5StrPrestringByAppendingString:getKey];
NSString*md5Str = [QWCommonFuncmd5:md5StrPre];
returnmd5Str;
}
五.MVC模式搭界面。
六.登錄分享。
1.很多公司都是用H5頁面直接調取登錄注冊。這里主要說一下第三方登錄。
Cocopod導入shareSDK或者直接在官網拖入導入(但是要手動添加一些依賴庫)。
- (instancetype)init
{
if(self= [superinit])
{
self.users= [NSMutableArrayarray];
//將已授權用戶加入列表
[[SSEThirdPartyLoginHelperusers]enumerateKeysAndObjectsUsingBlock:^(idkey,SSEBaseUser*obj,BOOL*stop) {
[self.usersaddObject:obj];
}];
}
returnself;
}
[ShareSDKregisterApp:QWShareKey
activePlatforms:@[
@(SSDKPlatformTypeSinaWeibo),
@(SSDKPlatformTypeWechat),
@(SSDKPlatformTypeQQ),]
onImport:^(SSDKPlatformTypeplatformType)
{
switch(platformType)
{
caseSSDKPlatformTypeWechat:
[ShareSDKConnectorconnectWeChat:[WXApiclass]delegate:self];
break;
//case SSDKPlatformSubTypeQZone:
caseSSDKPlatformTypeQQ:
[ShareSDKConnectorconnectQQ:[QQApiInterfaceclass]tencentOAuthClass:[TencentOAuthclass]];
break;
caseSSDKPlatformTypeSinaWeibo:
[ShareSDKConnectorconnectWeibo:[WeiboSDKclass]];
break;
default:
break;
}
}
onConfiguration:^(SSDKPlatformTypeplatformType,NSMutableDictionary*appInfo)
{
switch(platformType)
{
caseSSDKPlatformTypeSinaWeibo:
//設置新浪微博應用信息,其中authType設置為使用SSO+Web形式授權
[appInfoSSDKSetupSinaWeiboByAppKey:SinaAppid
appSecret:SinaAppsecret
redirectUri:@""
authType:SSDKAuthTypeBoth];
break;
caseSSDKPlatformTypeWechat:
[appInfoSSDKSetupWeChatByAppId:WXAppid
appSecret:WXAppsecret];
break;
caseSSDKPlatformTypeQQ:
[appInfoSSDKSetupQQByAppId:QQAppid
appKey:QQAppsecret
authType:SSDKAuthTypeBoth];
break;
default:
break;
}
以上是分享和登錄的KEY注冊。
[SSEThirdPartyLoginHelper loginByPlatform:SSDKPlatformTypeSinaWeibo
onUserSync:^(SSDKUser*user,SSEUserAssociateHandlerassociateHandler) {
onLoginResult:^(SSDKResponseStatestate,SSEBaseUser*user,NSError*error) {
}];
分享需要注意的是:
微博和微信朋友圈的分享需要特別分清。
NSMutableDictionary*shareParams = [NSMutableDictionarydictionary];
[shareParamsSSDKEnableUseClientShare];
//定制微博的分享內容
[shareParamsSSDKSetupSinaWeiboShareParamsByText:[NSStringstringWithFormat:@"%@%@",[QWStringUtilsconvertNullString:content],[NSURLURLWithString:url]]title:[QWStringUtilsconvertNullString:title]image:imageArrayurl:[NSURLURLWithString:url]latitude:0longitude:0objectID:niltype:SSDKContentTypeAuto];
//定制微信朋友圈的分享內容
[shareParamsSSDKSetupWeChatParamsByText:[NSStringstringWithFormat:@"%@",[QWStringUtilsconvertNullString:content]]title:[QWStringUtilsconvertNullString:title]url:[NSURLURLWithString:url]thumbImage:nilimage:imageArraymusicFileURL:nilextInfo:nilfileData:nilemoticonData:niltype:SSDKContentTypeAutoforPlatformSubType:SSDKPlatformSubTypeWechatTimeline];
[shareParamsSSDKSetupShareParamsByText:[NSStringstringWithFormat:@"%@%@",[QWStringUtilsconvertNullString:content],[NSURLURLWithString:url]]
images:imageArray
url:[NSURLURLWithString:url]
title:[QWStringUtilsconvertNullString:title]
type:SSDKContentTypeAuto];
系統的分享UI界面
[ShareSDKshowShareActionSheet:nil
items:typeArr
shareParams:shareParams
onShareStateChanged:^(SSDKResponseStatestate,SSDKPlatformTypeplatformType,NSDictionary*userData,SSDKContentEntity*contentEntity,NSError*error,BOOLend) {
switch(state) {
caseSSDKResponseStateSuccess:
{
[QWShowMessageshowToastmsg:@"分享成功"toView:controller.view];
break;
}
caseSSDKResponseStateFail:
{
[QWShowMessageshowToastmsg:@"分享失敗"toView:controller.view];break;
}caseSSDKResponseStateCancel: {
[QWShowMessageshowToastmsg:@"分享取消"toView:controller.view];
break;
}
default:
break;
}
}
];
自定義分享界面
這個可以自己寫一個View。(用tableview或者collection)(也可以寫成button的點擊)
__blocktypeof(self)weakSelf =self;
[ShareSDKshare:[dict[@"shareType"]intValue]parameters:shareParamsonStateChanged:^(SSDKResponseStatestate,NSDictionary*userData,SSDKContentEntity*contentEntity,NSError*error) {
switch(state) {
caseSSDKResponseStateSuccess:
{
[weakSelfshareSuccessMsg];
Log(@"分享成功!");
break;
}
caseSSDKResponseStateFail:
{
[TJShowMessageshowToast:self.superViewmsg:@"分享失敗"];
TJLog(@"---%@",error.description);
break;
}
caseSSDKResponseStateCancel: {
break;
}
default:
break;
}];
如何判斷是否登錄成功了呢?
還有如何下次啟動不在輸入密碼,自動登錄呢?
那么我們需要AccountModel單例和LoginTool。
當然我們也需要歸檔和解檔。來判斷是否登錄。記錄是否有賬號和密碼。但是這種有一個缺點,如果我們卸載了該應用然后在安裝,就不會有登錄的記錄。很多程序是記錄的手機UDID,傳給后臺,一一對應。
實現歸檔中的 encodeWithCoder 和 initWithCoder方法
http://www.lxweimin.com/p/98ce827931c7
+ (void)saveAccount:(AccountModel*)model
{
[NSKeyedArchiverarchiveRootObject:modeltoFile:AccountPath];//歸檔
}
+ (AccountModel*)loadAccount
{
AccountModel*model = [NSKeyedUnarchiverunarchiveObjectWithFile:AccountPath];
returnmodel;
}
if(![QWLoginToolisLogin]) {
[selfpresentViewController:[QWLoginToollogin]animated:YEScompletion:nil];
return;
}
判斷是否登錄。
七.支付
1.支付寶支付。
2.微信支付。
3.銀聯支付。
4.京東支付。
5.蘋果內購支付。
關于蘋果內購支付的思路。
1.證書。
五個證書。兩個p12證書(一個development開發者,一個distribution發布者),三個描述文件(一個development開發描述真機測試,一個distribution發布APP描述文件,一個distribution_adhoc打包測試證書)。
2.流程
1、Get Set of Product IDs內購商品信息最好存放到服務器,因為界面的展示都是根據模型顯示(將數據放到一個集合里面:NSSet/Web Service)前提是需要將項目在蘋果內購后臺信息配置好
2、向蘋果請求有效的內購商品信息Request Valid Product IDs (蘋果可能限制某些商品)怎么請求:SKProductsRequest(創建這個請求)。
3、蘋果返回有效的內購商品信息Valid DIs Returned
4、展示購買的選項(展示界面)Display Purchase Options
5、用戶開始購買(User Initiates Purchase):選中某個商品,創建票據(SKPayment),將票據加入到交易隊列里面(User Works Through Dialogs)
6、監聽交易隊列交易成功還是失敗(添加觀察者,遵守協議,實現方法進行回調)。
(代理一對一,觀察者一對多)
八.常用的框架
1.Masonry(布局)
2.github.com/forkingdog(流暢的側滑)
3.WMPageController(好框架)(自己寫的話就有些小麻煩,浪費時間。)
4.SDCycleScrollView(廣告輪播圖)
5.iCarousel-(第一次啟動新手引導)
九.封裝。優化。
十.上架。
十一.與H5頁面交互。
#pragma mark WKUIDelegate
//頁面開始加載時調用
-(void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation{
NSLog(@"開始加載");
}
//內容開始返回時調用
-(void)webView:(WKWebView*)webView didCommitNavigation:(WKNavigation*)navigation{
NSLog(@"開始返回");
}
//頁面加載完成時調用
-(void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation{
NSLog(@"加載完成");
}
//頁面加載失敗時調用
-(void)webView:(WKWebView*)webView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error{
NSLog(@"加載失敗");
}
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler
{
NSString*requestStr = navigationAction.request.URL.absoluteString;
QWLog(@"requestStr==%@",requestStr);
if([requestStrisEqualToString:@""]) {
QWLog(@"獲取URL失敗");
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
if([requestStrrangeOfString:@"#"].location!=NSNotFound) {
NSArray*arr = [requestStrcomponentsSeparatedByString:@"#"];
requestStr = [arrobjectAtIndex:1];
Log(@"找到帶#號的url");
decisionHandler(WKNavigationActionPolicyCancel);
requestStr = [requestStrstringByRemovingPercentEncoding];
NSData*data = [requestStrdataUsingEncoding:NSUTF8StringEncoding];
NSDictionary*dic = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingMutableLeaveserror:nil];
QWLog(@"dic = %@",dic);
if([requestStrrangeOfString:@""].location!=NSNotFound) {
}
decisionHandler(WKNavigationActionPolicyAllow);
if(![requestStrhasPrefix:@"http"])
{
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}