Commit 1f98a72e authored by Jennie Shi's avatar Jennie Shi

插件更新

parent 82aa82a8
...@@ -109,6 +109,5 @@ ...@@ -109,6 +109,5 @@
<plugin name="cordova-plugin-device" spec="2.0.2" /> <plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" /> <plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="ionic-plugin-keyboard" spec="^2.2.1" /> <plugin name="ionic-plugin-keyboard" spec="^2.2.1" />
<plugin name="IdCardPlugin" spec="/Users/jeshi/Documents/徐工/card-plugin-test/IdCardPlugin" />
<engine name="android" spec="~6.2.0" /> <engine name="android" spec="~6.2.0" />
</widget> </widget>
...@@ -166,9 +166,6 @@ ...@@ -166,9 +166,6 @@
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
"dev": true "dev": true
}, },
"IdCardPlugin": {
"version": "file:../card-plugin-test/IdCardPlugin"
},
"abbrev": { "abbrev": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz", "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
...@@ -2523,7 +2520,7 @@ ...@@ -2523,7 +2520,7 @@
}, },
"cordova-android": { "cordova-android": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npm.taobao.org/cordova-android/download/cordova-android-6.2.0.tgz", "resolved": "https://registry.npm.taobao.org/cordova-android/download/cordova-android-6.2.0.tgz?cache=0&sync_timestamp=1612917180716&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcordova-android%2Fdownload%2Fcordova-android-6.2.0.tgz",
"integrity": "sha1-32iB29cuIzA8o9/e03KrAWFMAXM=", "integrity": "sha1-32iB29cuIzA8o9/e03KrAWFMAXM=",
"requires": { "requires": {
"cordova-common": "^2.0.1", "cordova-common": "^2.0.1",
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
"clean": "rimraf www/*" "clean": "rimraf www/*"
}, },
"dependencies": { "dependencies": {
"IdCardPlugin": "file:../card-plugin-test/IdCardPlugin",
"autosize": "^3.0.20", "autosize": "^3.0.20",
"better-scroll": "^1.10.3", "better-scroll": "^1.10.3",
"cordova-android": "^6.2.0", "cordova-android": "^6.2.0",
...@@ -117,9 +116,7 @@ ...@@ -117,9 +116,7 @@
"cordova-plugin-statusbar": {}, "cordova-plugin-statusbar": {},
"cordova-plugin-device": {}, "cordova-plugin-device": {},
"cordova-plugin-splashscreen": {}, "cordova-plugin-splashscreen": {},
"ionic-plugin-keyboard": {}, "ionic-plugin-keyboard": {}
"IdCardPlugin": {},
"cordova-plugin-hand-idcardplugin": {}
} }
} }
} }
\ No newline at end of file
{
"name": "IdCardPlugin",
"version": "1.0.0",
"description": "",
"cordova": {
"id": "IdCardPlugin",
"platforms": []
},
"keywords": [
"ecosystem:cordova"
],
"author": "",
"license": "ISC"
}
<?xml version='1.0' encoding='utf-8'?>
<plugin id="IdCardPlugin" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>IdCardPlugin</name>
<js-module name="IdCardPlugin" src="www/IdCardPlugin.js">
<clobbers target="cordova.plugins.IdCardPlugin" />
</js-module>
<!-- android -->
<platform name="android">
<!-- 业务类指定 -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="IdCardIdentifyPlugin">
<param name="android-package" value="com.xg.idcard.IdCardIdentifyPlugin"/>
</feature>
</config-file>
<!-- 需要的android权限 -->
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</config-file>
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity android:name="com.qsign.face.LivenessDetectActivity"/>
</config-file>
<!-- arr引用 -->
<resource-file src="src/android/lib/jsgzsdk.aar" target="libs/jsgzsdk.aar" />
<framework src="src/android/lib/idCard.gradle" custom="true" type="gradleReference" />
<source-file src="src/android/java/IdCardIdentifyPlugin.java" target-dir="src/com/xg/idcard/" />
<source-file src="src/android/lib/com.xcmg.app.dev-license.qsign-android" target-dir="assets/" />
<source-file src="src/android/lib/com.xcmg.app-license.qsign-android" target-dir="assets/" />
</platform>
</plugin>
身份检测cordova插件
调用方式:
```
1.实名认证
cordova.plugins.IdCardPlugin.idCardIdentify({"idNum":"身份证号码","idName":"姓名","phoneNum":"手机号"}, function (success) {}, function (reason) {});
2.人脸对比 成功回调返回人脸照片路径
cordova.plugins.IdCardPlugin.faceContrast({"idNum":"身份证号码","idName":"姓名"}, function (success) {}, function (reason) {});
```
package com.xg.idcard;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
import com.cn.qsign.jsgzlibrary.utils.QsignNotaryApi;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
public class IdCardIdentifyPlugin extends CordovaPlugin {
private static final String ID_CARD_IDENTIFY = "IdCardIdentify";//实名认证
private static final String FACE_CONTRAST = "faceContrast";//人脸对比
private String idNum;
private String idName;
private String phoneNum;
private CallbackContext mCallbackContext;
private String licenseName;
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
String packageName = cordova.getActivity().getPackageName();
if ("com.xcmg.app.dev".equals(packageName)) {
licenseName = "com.xcmg.app.dev-license.qsign-android";
} else {
licenseName = "com.xcmg.app-license.qsign-android";
}
boolean initok = QsignNotaryApi.getInstance().init(cordova.getActivity().getApplication(), "", licenseName, "xugong", false);
Log.d("IdCardIdentifyPlugin", "initok = " + initok);
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.mCallbackContext = callbackContext;
if (args == null) {
mCallbackContext.error(getResult(0, "参数错误"));
return false;
}
JSONObject idInfo = args.optJSONObject(0);
if (idInfo == null) {
mCallbackContext.error(getResult(0, "参数错误"));
return false;
}
idNum = idInfo.optString("idNum");
idName = idInfo.optString("idName");
if (idNum == null || idNum.isEmpty() || idName == null || idName.isEmpty()) {
mCallbackContext.error(getResult(0, "参数错误"));
return false;
}
if (ID_CARD_IDENTIFY.equals(action)) {
phoneNum = idInfo.optString("phoneNum");
if (phoneNum == null || phoneNum.isEmpty()) {
mCallbackContext.error(getResult(0, "参数错误"));
return false;
}
startIdCardCheck();
} else if (FACE_CONTRAST.equals(action)) {
checkCameraPermission();
} else {
mCallbackContext.error(getResult(0, "参数错误"));
return false;
}
return true;
}
private void startIdCardCheck() {
QsignNotaryApi.getInstance().identifyNotary(cordova.getActivity(),
idName, idNum, phoneNum,
new QsignNotaryApi.registerCallbackListener() {
@Override
public void onSuccess(QsignNotaryApi.QSIGNREGISTERCODE qsignregistercode, String s, String s1, String s2) {
if (qsignregistercode == QsignNotaryApi.QSIGNREGISTERCODE.NORMALREGISTER) {
mCallbackContext.success(getResult(1, "检测成功"));
} else {
mCallbackContext.error(getResult(0, "信息提交成功,等待人工审核"));
}
}
@Override
public void onError(QsignNotaryApi.QSIGNERRORCODE qsignerrorcode, String s) {
mCallbackContext.error(getResult(0, s));
}
});
}
private void startFaceContrast() {
QsignNotaryApi.getInstance().qsignLivenessNotary(cordova.getActivity(), idName, idNum, new QsignNotaryApi.faceCallbackListener() {
@Override
public void onSuccess(String s) {
String filePath = saveImage(s);
mCallbackContext.success(getResult(1, filePath));
}
@Override
public void onError(QsignNotaryApi.QSIGNERRORCODE qsignerrorcode, String s) {
mCallbackContext.error(getResult(0, s));
}
});
}
private String getResult(int code, String message) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("code", code);
jsonObject.put("message", message);
} catch (JSONException e) {
e.printStackTrace();
}
return jsonObject.toString();
}
private void checkCameraPermission() {
if (cordova.hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& cordova.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
startFaceContrast();
} else {
requestCameraPermission();
}
}
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static final int REQUEST_CAMERA_PERMISSION_CODE = 0x01;
private void requestCameraPermission() {
cordova.requestPermissions(this, REQUEST_CAMERA_PERMISSION_CODE, PERMISSIONS_STORAGE);
}
@Override
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException {
if (REQUEST_CAMERA_PERMISSION_CODE == requestCode) {
boolean checkPermission = true;
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
checkPermission = false;
}
}
} else {
checkPermission = false;
}
if (checkPermission) {
startFaceContrast();
} else {
mCallbackContext.success(getResult(0, "未授予文件读写"));
}
}
super.onRequestPermissionResult(requestCode, permissions, grantResults);
}
private String saveImage(String base64String) {
byte[] decode = Base64.decode(base64String, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
File appDir = new File(cordova.getActivity().getApplicationContext().getExternalFilesDir(null), "image");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return file.getPath();
}
}
IyDl5pQS3o3fFUQeXbstDxTvBS/uVKYWHDf549PcITq+WrHoe4ubjzoizlu5olJs2qHqvqAW4N+tnywSWMbzhMRiQKpx2SGHy7c+egnXWl5VCA3LRVMjRPsx+XE1bUHbL9RzjSUq/BN9WVz2HEryxSmRf+YD+QAKuc2e01Ei7c8=
\ No newline at end of file
OoC6eFPZ052U9SUIKADVkMowQX8QUK6xZdzz3R8W/15nMXisPRHSccLFlLalaf5n0pYf+/A087BXOcLDOfDqlWr0d68z0S+hNbmjvovgd4Og0sJodxnBHailPIGbjJPiqPByiAzke+Z6qxN3fB3bpA1ViXilJKXBwg5/bgJPxuE=
\ No newline at end of file
repositories{
jcenter()
flatDir {
dirs 'libs'
}
}
dependencies {
compile(name:"jsgzsdk",ext: 'aar')
implementation 'com.android.support:appcompat-v7:28.+'
//必须添加如下依赖!!!
implementation 'com.android.support:recyclerview-v7:28.+'
implementation 'com.google.code.gson:gson:2.8.0'
implementation 'com.alibaba:fastjson:1.2.31'
implementation 'com.lzy.net:okgo:3.0.4'
implementation ('com.github.bumptech.glide:glide:4.8.0'){
exclude group:"com.android.support"
}
implementation "com.android.support:exifinterface:28.+"
implementation 'com.otaliastudios:cameraview:1.5.0'
}
android {
packagingOptions {
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
aaptOptions {
noCompress "dat"
}
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '28.0.0'
}
}
}
}
\ No newline at end of file
var exec = require('cordova/exec');
exports.idCardIdentify = function (arg0, success, error) {
exec(success, error, 'IdCardIdentifyPlugin', 'IdCardIdentify', [arg0]);
};
exports.faceContrast = function (arg0, success, error) {
exec(success, error, 'IdCardIdentifyPlugin', 'faceContrast', [arg0]);
};
\ No newline at end of file
...@@ -70,9 +70,6 @@ ...@@ -70,9 +70,6 @@
"jpush-phonegap-plugin": { "jpush-phonegap-plugin": {
"APP_KEY": "bef4fd44dcf54b79b8ab27c3", "APP_KEY": "bef4fd44dcf54b79b8ab27c3",
"PACKAGE_NAME": "com.xcmg.app" "PACKAGE_NAME": "com.xcmg.app"
},
"IdCardPlugin": {
"PACKAGE_NAME": "com.xcmg.app"
} }
}, },
"dependent_plugins": { "dependent_plugins": {
......
# cordova-plugin-hotpatch
这个插件定义了一个全局对象 `hotpatch` object,整个方法当前版本只暴露出一个方法updateNewVersion,调用该方法传入一个 www.zip的下载地址,之后插件会自动下载,并解压
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
//hotpatch.updateNewVersion("http://10.211.131.232:8080/www.zip");
</script>
## Installation
cordova plugin add xxxxxxxxx
### Supported Platforms
- Android
- iOS
### 安装步骤
1 添加插件
2 在需要更新的时候调用更新地址
3 注意 android平台由于特殊性 ,需要打开主工程的mainActivity 文件,在{
super.onCreate(savedInstanceState);后面加上一行代码 init();
将DownLoadTask.java 文件中的import com.hand.download.R; 改为自己主工程MainActivity 文件 所在路径
如:agelocme-frontend\platforms\android\src\com\nuskin\agelocmeprod\MainActivity.java
则改为import com.nuskin.agelocmeprod.R;
4 安卓和ios需要打不同的www.zip包。安卓zip包需要取assets下面的www文件夹,ios的zip包需要取platforms/ios/www
#### 补充说明
在android平台上的热更新原理:加了init()后,当前app会优先执行从服务器下载到手机端的www文件内的代码,若是没有加init(),热更新不会失效,app重启后会执行原来打包的代码。
#### 热更新的优缺点
优点:避免了繁琐的打包过程
热更新的www代码不会放到公众服务器上。
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="com.handmobile.cordovaplugin.hotpatch"
version="1.0-dev">
<name>hotpatch</name>
<description>hand cordova hot patch plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,hotpatch</keywords>
<repo>git@github.com:jiangtiteng/cordova-plugin-baidupush.git</repo>
<engines>
<engine name="cordova" version=">=3.1.0" /><!-- Needs cordova/urlutil -->
</engines>
<js-module src="www/hotpatch.js" name="hotpatch">
<clobbers target="hotpatch" />
</js-module>
<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="hotpatch">
<param name="android-package" value="com.handmobile.cordova.hotpatch.HotPatchPlugin"/>
<param name="onload" value="true" />
</feature>
</config-file>
<source-file src="src/android/hotpatch/HotPatchPlugin.java" target-dir="src/com/handmobile/cordova/hotpatch"/>
<source-file src="src/android/hotpatch/DownLoadTask.java" target-dir="src/com/handmobile/cordova/hotpatch"/>
<source-file src="src/android/hotpatch/ZipUtil.java" target-dir="src/com/handmobile/cordova/hotpatch"/>
<source-file src="src/android/hotpatch/PluginUtil.java" target-dir="src/com/handmobile/cordova/hotpatch"/>
<source-file src="src/android/hotpatch/MyProgressBar.java" target-dir="src/com/handmobile/cordova/hotpatch"/>
<source-file src="src/android/hotpatch/alterlayout.xml" target-dir="res/layout"/>
<source-file src="src/android/hotpatch/dailog_bg.xml" target-dir="res/drawable"/>
<source-file src="src/android/hotpatch/shape_progressbar_mini.xml" target-dir="res/drawable"/>
<source-file src="src/android/hotpatch/styles.xml" target-dir="res/values"/>
</platform>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="hotpatch">
<param name="ios-package" value="HotPatchPlugin"/>
<param name="onload" value="true"/>
</feature>
</config-file>
<header-file src="src/ios/hotpatch/HotPatchPlugin.h"/>
<source-file src="src/ios/hotpatch/HotPatchPlugin.m"/>
<header-file src="src/ios/hotpatch/SDBaseProgressView.h"/>
<source-file src="src/ios/hotpatch/SDBaseProgressView.m"/>
<header-file src="src/ios/hotpatch/SDPieLoopProgressView.h"/>
<source-file src="src/ios/hotpatch/SDPieLoopProgressView.m"/>
<header-file src="src/ios/hotpatch/CustomIOSAlertView.h"/>
<source-file src="src/ios/hotpatch/CustomIOSAlertView.m"/>
<framework src="SystemConfiguration.framework" weak="true" />
<framework src="Security.framework" weak="true" />
<framework src="libz.tbd" weak="true" />
<framework src="src/ios/lib/AFNetworkingFramwork.framework" custom="true" />
<framework src="src/ios/lib/ZipArchive.framework" custom="true" />
</platform>
</plugin>
package com.handmobile.cordova.hotpatch;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.ZipEntry;
import org.apache.cordova.CordovaWebView;
import android.R.bool;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.widget.TextView;
import android.content.SharedPreferences; // add by ciwei
import android.preference.PreferenceManager; // add by ciwei
import android.content.pm.PackageManager;// add by ciwei
import android.content.res.Resources;
import android.content.pm.PackageInfo;// add by ciwei
import android.util.Log;
public class DownLoadTask extends AsyncTask<String, String, Boolean>{
private final static int TIME_OUT = 30 * 1000;
private String patchAppVersionKey ="patchAppVersion";
private Context mContext;
private CordovaWebView mWebView;
private ProgressDialog mProgressDialog;
private MyProgressBar mProgressBar;
private TextView mPercent;
private String mPercentString;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mPercent.setText(mPercentString);
}
};
public DownLoadTask(Context context,CordovaWebView webView)
{
mContext = context;
mWebView = webView;
mProgressDialog = new ProgressDialog(mContext);
// mProgressDialog.setTitle("升级文件下载");
// mProgressDialog.setMessage("文件下载中,请稍候...");
// mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setProgress(0);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
mProgressDialog.setOnKeyListener(onKeyListener);
mProgressDialog.setContentView(getResId("alterlayout"));
mProgressBar = (MyProgressBar) mProgressDialog.findViewById(getId("progressBar1"));
mProgressBar.setProgress(0);
mPercent =(TextView)mProgressDialog.findViewById(getId("tv_percent"));
}
@Override
protected Boolean doInBackground(String... params) {
if(params[0] !=null){
String url = params[0];
try {
HttpURLConnection connection = null;
URL u = new URL(url);
connection = (HttpURLConnection) u.openConnection();
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod("GET");
connection.setConnectTimeout(TIME_OUT);
connection.connect();
int lenghtOfFile = connection.getContentLength();
InputStream input = new BufferedInputStream(
connection.getInputStream());
mContext.deleteFile("www.zip");
OutputStream output = mContext.openFileOutput("www.zip", Context.MODE_PRIVATE);
byte data[] = new byte[1024 * 20];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
publishProgress(String.valueOf((total * 100) / lenghtOfFile));
}
output.flush();
output.close();
input.close();
mContext.deleteFile("www");
ZipUtil.UnZipFolder(mContext.getFileStreamPath("www.zip").toString(), mContext.getFilesDir().toString().concat("/"));
//保存版本号
SharedPreferences mSharedPreferences = PreferenceManager
.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = mSharedPreferences.edit();
PackageManager packageManager = mContext.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
mContext.getPackageName(), 0);// mod by ciwei +m
String currentVersion = packageInfo.versionName;
editor.putString(patchAppVersionKey,currentVersion);
editor.commit();
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}else {
return false;
}
return true;
}
@Override
protected void onProgressUpdate(String... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
mProgressDialog.setProgress(Integer.parseInt(values[0]));
mProgressBar.setProgress(Integer.parseInt(values[0]));
mPercentString =values[0]+"%";
mHandler.sendEmptyMessage(100);
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
if(true){
new Handler().postDelayed(new Runnable() {
public void run() {
mWebView.clearHistory();
mWebView.clearCache();
}
}, 0);
mWebView.loadUrlIntoView("file://".concat(mContext.getFilesDir().getPath()).concat("/www/index.html"), false);
}
else {
}
}
///////////////////
private OnKeyListener onKeyListener = new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
mProgressDialog.dismiss();
}
return false;
}
};
///////////////////////add by fuwei/////////////////////////////////
private int getResId(String resourceName){
Resources resources = mContext.getResources();
int resId = resources.getIdentifier(resourceName,"layout",mContext.getPackageName());
// int resId = resources.getIdentifier(getPackageName() + ":layout/" + resourceName, null, null);
return resId;
}
private int getId(String idName){
Resources resources = mContext.getResources();
int resId = resources.getIdentifier(idName, "id", mContext.getPackageName());
return resId;
}
//////////////////////////////////////////////////////////
}
package com.handmobile.cordova.hotpatch;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaActivity;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.webkit.WebView;
import android.content.SharedPreferences; // add by ciwei
import android.preference.PreferenceManager; // add by ciwei
import android.content.pm.PackageManager;// add by ciwei
import android.content.pm.PackageInfo;// add by ciwei
import android.text.TextUtils;//add by ciwei
import android.util.Log;
import com.handmobile.cordova.hotpatch.DownLoadTask;
import java.io.File;
import java.lang.reflect.Field;
public class HotPatchPlugin extends CordovaPlugin {
private CordovaActivity mCordovaActivity;
private String patchAppVersionKey ="patchAppVersion";
private String version ="";
private String currentVersion = "";
public HotPatchPlugin() {
}
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
// TODO Auto-generated method stub
super.initialize(cordova, webView);
mCordovaActivity = (CordovaActivity)cordova.getActivity();
//获取上次保存的版本号
SharedPreferences mSharedPreferences = PreferenceManager
.getDefaultSharedPreferences(webView.getContext());
version = mSharedPreferences.getString(patchAppVersionKey,"0.0.0");
//获取版本号 //add try by ciwei
try{
PackageManager packageManager = webView.getContext().getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(webView.getContext().getPackageName(), 0);// mod by ciwei add webView
currentVersion = packageInfo.versionName;
}catch (Exception e) {
e.printStackTrace();
}
//判断版本号大小
if(version.compareTo(currentVersion) < 0){
String mFilePath = webView.getContext().getFilesDir().toString().concat("/www");
File file = new File(mFilePath);
if(file.exists()){
boolean result = deleteDir(file);
if(!result){
PluginUtil.showErrorMessage("安装失败,权限不够",cordova.getActivity());
}
}
}
String targetFilePath = webView.getContext().getFilesDir().toString().concat("/www/index.html");
File targetFile = new File(targetFilePath);
if(targetFile.exists()){
Class userCla = (Class) CordovaActivity.class;
Field[] fs = userCla.getDeclaredFields();
for(int i = 0 ; i < fs.length; i++){
Field f = fs[i];
if(f.getName().equals("launchUrl")){
try {
f.setAccessible(true); //设置些属性是可以访问的
f.set(mCordovaActivity,"file://".concat(targetFilePath));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
private boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
//递归删除目录中的子目录下
for (int i=0; i<children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// 目录此时为空,可以删除
return dir.delete();
}
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if ("updateNewVersion".equals(action)) {
String updateUrl = args.getString(0);
if(updateUrl ==null || updateUrl.equals("")){
PluginUtil.showErrorMessage("热更新url 为空",cordova.getActivity());
}else {
updateNewVersion(updateUrl);
}
}
else {
return false;
}
return true;
}
public void updateNewVersion(String updateUrl)
{
DownLoadTask downLoadTask = new DownLoadTask(webView.getContext(),webView);
downLoadTask.execute(updateUrl);
}
}
package com.handmobile.cordova.hotpatch;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.ProgressBar;
/**
* Created by jimda on 2016/3/16.
*/
public class MyProgressBar extends ProgressBar {
private String text_progress;
private Paint mPaint;//画笔
public MyProgressBar(Context context) {
super(context);
initPaint();
}
public MyProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public MyProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initPaint();
}
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
setTextProgress(progress);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// Rect rect=new Rect();
// this.mPaint.getTextBounds(this.text_progress, 0, this.text_progress.length(), rect);
// int x = (getWidth() / 2) - rect.centerX();
// int y = (getHeight() / 2) - rect.centerY();
// canvas.drawText(this.text_progress, x, y, this.mPaint);
}
/**
*
*description: 初始化画笔
*Create by lll on 2013-8-13 下午1:41:49
*/
private void initPaint(){
this.mPaint=new Paint();
this.mPaint.setAntiAlias(true);
this.mPaint.setColor(Color.BLACK);
}
private void setTextProgress(int progress){
int i = (int) ((progress * 1.0f / this.getMax()) * 100);
// this.text_progress = String.valueOf(i) + "%";
}
}
\ No newline at end of file
package com.handmobile.cordova.hotpatch;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
/**
* Created by titengjiang on 16/2/29.
*/
public class PluginUtil {
public static void showErrorMessage(String errorMessage,Context context)
{
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("错误");
builder.setMessage(errorMessage);
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
}
}
package com.handmobile.cordova.hotpatch;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import android.util.Log;
public class ZipUtil {
/**
* 解压一个压缩文档 到指定位置
*
* @param zipFileString 压缩包的名字
* @param outPathString 指定的路径
* [url=home.php?mod=space&uid=2643633]@throws[/url] Exception
*/
public static void UnZipFolder(String zipFileString, String outPathString) throws Exception {
java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(zipFileString));
java.util.zip.ZipEntry zipEntry;
String szName = "";
File outPathFile = new File(outPathString);
if(outPathFile.exists()){
outPathFile.delete();
}
try {
while ((zipEntry = inZip.getNextEntry()) != null) {
szName = zipEntry.getName();
if (zipEntry.isDirectory()) {
// get the folder name of the widget
szName = szName.substring(0, szName.length() - 1);
java.io.File folder = new java.io.File(outPathString + java.io.File.separator + szName);
folder.mkdirs();
} else {
java.io.File file = null;
file = new java.io.File(outPathString + java.io.File.separator + szName);
file.createNewFile();
// get the output stream of the file
java.io.FileOutputStream out = new java.io.FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
// read (len) bytes into buffer
while ((len = inZip.read(buffer)) != -1) {
// write (len) byte from buffer at the position 0
out.write(buffer, 0, len);
out.flush();
}
out.close();
}
}//end of while
inZip.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EFEFEF"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true">
<com.handmobile.cordova.hotpatch.MyProgressBar
android:id="@+id/progressBar1"
style="@style/StyleProgressBarMini"
android:layout_width="200dp"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:progress="100" />
<TextView
android:id="@+id/tv_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="6dp"
android:layout_toRightOf="@+id/progressBar1"
android:gravity="center"
android:text="0%"
android:textColor="#C39075" />
</LinearLayout>
</RelativeLayout>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<stroke android:width="2dp" android:color="#FFFFFF" android:dashWidth="2dp"
android:dashGap="0dp" />
<padding android:left="10dp" android:top="10dp"
android:right="10dp" android:bottom="10dp" />
<corners android:radius="6dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!--背景 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:angle="270"
android:centerY="0.75"
android:endColor="#FFFFFF"
android:startColor="#FFFFFF" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="0dip" />
<gradient
android:angle="270"
android:centerY="0.75"
android:endColor="#df0024"
android:startColor="#df0024" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:angle="270"
android:centerY="0.75"
android:endColor="#64DCB5"
android:startColor="#64DCB5" />
</shape>
</clip>
</item>
</layer-list>
\ No newline at end of file
<resources>
<style name="StyleProgressBarMini" parent="@android:style/Widget.ProgressBar.Horizontal">
<item name="android:maxHeight">50dip</item>
<item name="android:minHeight">10dip</item>
<item name="android:indeterminateOnly">false</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
<item name="android:progressDrawable">@drawable/shape_progressbar_mini</item>
</style>
</resources>
//
// CustomIOSAlertView.h
// CustomIOSAlertView
//
// Created by Richard on 20/09/2013.
// Copyright (c) 2013-2015 Wimagguc.
//
// Lincesed under The MIT License (MIT)
// http://opensource.org/licenses/MIT
//
#import <UIKit/UIKit.h>
@protocol CustomIOSAlertViewDelegate
- (void)customIOS7dialogButtonTouchUpInside:(id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
@end
@interface CustomIOSAlertView : UIView<CustomIOSAlertViewDelegate>
@property (nonatomic, retain) UIView *parentView; // The parent view this 'dialog' is attached to
@property (nonatomic, retain) UIView *dialogView; // Dialog's container view
@property (nonatomic, retain) UIView *containerView; // Container within the dialog (place your ui elements here)
@property (nonatomic, assign) id<CustomIOSAlertViewDelegate> delegate;
@property (nonatomic, retain) NSArray *buttonTitles;
@property (nonatomic, assign) BOOL useMotionEffects;
@property (copy) void (^onButtonTouchUpInside)(CustomIOSAlertView *alertView, int buttonIndex) ;
- (id)init;
/*!
DEPRECATED: Use the [CustomIOSAlertView init] method without passing a parent view.
*/
- (id)initWithParentView: (UIView *)_parentView __attribute__ ((deprecated));
- (void)show;
- (void)close;
- (IBAction)customIOS7dialogButtonTouchUpInside:(id)sender;
- (void)setOnButtonTouchUpInside:(void (^)(CustomIOSAlertView *alertView, int buttonIndex))onButtonTouchUpInside;
- (void)deviceOrientationDidChange: (NSNotification *)notification;
- (void)dealloc;
@end
//
// BaiduPushPlugin.h
// HelloCordova
//
// Created by titengjiang on 15/9/23.
//
//
#import <UIKit/UIKit.h>
#import <Cordova/CDVPlugin.h>
#import <Cordova/CDVInvokedUrlCommand.h>
#import <ZipArchive/SSZipArchive.h>
//#import "SSZipArchive.h"
#import <Cordova/CDVViewController.h>
@interface HotPatchPlugin : CDVPlugin <SSZipArchiveDelegate>
-(void)updateNewVersion:(CDVInvokedUrlCommand*)command;
@end
//
// BaiduPushPlugin.m
// HelloCordova
//
// Created by titengjiang on 16/06/24.
//
//
#import "HotPatchPlugin.h"
#import <AFNetworkingFramwork/AFURLSessionManager.h>
#import <ZipArchive/SSZipArchive.h>
#import "SDPieLoopProgressView.h"
#import "CustomIOSAlertView.h"
//#import "AFURLSessionManager.h"
//#import "SSZipArchive.h"
static NSString *patchAppVersionKey = @"patchAppVersion";
@implementation HotPatchPlugin {
NSString *_HTMLURL;
NSURL *_BASEURL;
NSURL * _newWWWFloderUrl;
UIWebView * _webView;
CDVViewController * _cdvViewController;
UIProgressView * _progressView;
UIAlertView * _alertView;
SDPieLoopProgressView* _pieView;
CustomIOSAlertView* _malertView;
}
- (void)pluginInitialize
{
_webView = self.webView;
_cdvViewController = (CDVViewController *)self.viewController;
NSString *version = [[NSUserDefaults standardUserDefaults] valueForKey:patchAppVersionKey];
NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
NSString *current = [[NSUserDefaults standardUserDefaults] objectForKey:@"currentVersionPath"];
if (!current) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * targetUrl = [documentsDirectory stringByAppendingString:@"/www/index.html"];
if (!version || (version && [self isBigWithVersion1:currentVersion version2:version])) {
[[NSFileManager defaultManager] removeItemAtPath:[documentsDirectory stringByAppendingString:@"/www"] error:NULL];
}
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:targetUrl];
if(isExist) {
_cdvViewController.startPage = [[NSURL fileURLWithPath:[documentsDirectory stringByAppendingString:@"/www/index.html"]] absoluteString];
}
} else {
NSString * targetUrl = [current stringByAppendingString:@"/www/index.html"];
if (version && [self isBigWithVersion1:currentVersion version2:version]) {
[[NSFileManager defaultManager] removeItemAtPath:[current stringByAppendingString:@"/www"] error:NULL];
}
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:targetUrl];
if(isExist) {
_cdvViewController.startPage = [[NSURL fileURLWithPath:[current stringByAppendingString:@"/www/index.html"]] absoluteString];
}
}
}
-(void)dealloc{
}
#pragma mark util
- (BOOL)isBigWithVersion1:(NSString *)version1
version2:(NSString *)version2
{
if ([version1 compare:version2 options:NSNumericSearch] ==NSOrderedDescending)
{
return YES;
}
else {
return NO;
}
}
#pragma mark public
-(void)updateNewVersion:(CDVInvokedUrlCommand*)command {
_pieView = [[SDPieLoopProgressView alloc] init];
_pieView.frame=CGRectMake(0, 0, self.webView.center.x/2, self.webView.center.y/2);
_malertView = [[CustomIOSAlertView alloc] init];
// Add some custom content to the alert view
[_malertView setContainerView:_pieView];
[_malertView setUseMotionEffects:true];
// And launch the dialog
[_malertView show];
NSString * updateUrl = [command argumentAtIndex:0];
if(updateUrl == nil || [updateUrl isEqualToString:@""]){
[self showProgressAlert:@"错误" withMessage:@"更新地址不能为空"];
return;
}
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSProgress *progress;
NSURL *URL = [NSURL URLWithString:updateUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
// [self showProgressAlert:@"正在下载" withMessage:@"下载中"];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSString *documentsDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:@"currentVersionPath"];
if (documentsDirectory) {
NSURL *lastVersion = [NSURL fileURLWithPath:documentsDirectory];
[[NSFileManager defaultManager] removeItemAtURL:lastVersion error:nil];
}
NSURL *currentVersionDirectory = [self createCurrentPath];
NSURL *targetUrl = [currentVersionDirectory URLByAppendingPathComponent:[response suggestedFilename]];
return targetUrl;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSString *documentsDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:@"currentVersionPath"];
_newWWWFloderUrl = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingString:@"/www/index.html"]];
[SSZipArchive unzipFileAtPath:[filePath path] toDestination:documentsDirectory delegate:self];
[_malertView removeFromSuperview];
}];
[downloadTask resume];
// 给这个progress添加监听任务
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
}
#pragma mark kvo
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSLog(@"Progress is %f", progress.fractionCompleted);
[self performSelectorOnMainThread:@selector(progress:) withObject:@(progress.fractionCompleted) waitUntilDone:NO];
// 打印这个唯一标示符
NSLog(@"%@", progress.userInfo);
}
}
#pragma mark delegate
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath {
NSURLRequest* appReq = [NSURLRequest requestWithURL:_newWWWFloderUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
[_webView loadRequest:appReq];
[[NSUserDefaults standardUserDefaults] setObject:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:patchAppVersionKey];
[_alertView dismissWithClickedButtonIndex:0 animated:YES];
}
- (void)showProgressAlert:(NSString*)title withMessage:(NSString*)message {
if(_alertView == nil){
_alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil]
;
}
[_alertView show];
}
-(void)progress:(NSNumber*)progress {
_pieView.progress=[progress floatValue];
}
-(NSURL *)createCurrentPath {
NSError *error;
NSDate *date = [[NSDate alloc]init];
NSString *current = [NSString stringWithFormat:@"%@", date];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
documentsDirectory = [documentsDirectory stringByAppendingString:@"/"];
NSString *currentVersionPath = [documentsDirectory stringByAppendingString: current];
[[NSUserDefaults standardUserDefaults] setObject:currentVersionPath forKey:@"currentVersionPath"];
if (![[NSFileManager defaultManager] fileExistsAtPath:currentVersionPath])
[[NSFileManager defaultManager] createDirectoryAtPath:currentVersionPath withIntermediateDirectories:NO attributes:nil error:&error];
NSURL *currentVersionURL = [NSURL fileURLWithPath:currentVersionPath];
return currentVersionURL;
}
@end
\ No newline at end of file
//
// SDBaseProgressView.h
// SDProgressView
//
// Created by aier on 15-2-19.
// Copyright (c) 2015年 GSD. All rights reserved.
//
#import <UIKit/UIKit.h>
#define SDColorMaker(r, g, b, a) [UIColor colorWithRed:((r) / 255.0) green:((g) / 255.0) blue:((b) / 255.0) alpha:(a)]
#define SDProgressViewItemMargin 10
#define SDProgressViewFontScale (MIN(self.frame.size.width, self.frame.size.height) / 100.0)
// 背景颜色
#define SDProgressViewBackgroundColor SDColorMaker(240, 240, 240, 0.9)
@interface SDBaseProgressView : UIView
@property (nonatomic, assign) CGFloat progress;
- (void)setCenterProgressText:(NSString *)text withAttributes:(NSDictionary *)attributes;
- (void)dismiss;
+ (id)progressView;
@end
//
// SDBaseProgressView.m
// SDProgressView
//
// Created by aier on 15-2-19.
// Copyright (c) 2015年 GSD. All rights reserved.
//
#import "SDBaseProgressView.h"
@implementation SDBaseProgressView
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.backgroundColor = SDProgressViewBackgroundColor;
self.layer.cornerRadius = 5;
self.clipsToBounds = YES;
}
return self;
}
- (void)setProgress:(CGFloat)progress
{
_progress = progress;
if (progress >= 1.0) {
[self removeFromSuperview];
} else {
[self setNeedsDisplay];
}
}
- (void)setCenterProgressText:(NSString *)text withAttributes:(NSDictionary *)attributes
{
CGFloat xCenter = self.frame.size.width * 0.5;
CGFloat yCenter = self.frame.size.height * 0.5;
// 判断系统版本
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
CGSize strSize = [text sizeWithAttributes:attributes];
CGFloat strX = xCenter - strSize.width * 0.5;
CGFloat strY = yCenter - strSize.height * 0.5;
[text drawAtPoint:CGPointMake(strX, strY) withAttributes:attributes];
} else {
CGSize strSize;
NSAttributedString *attrStr = nil;
if (attributes[NSFontAttributeName]) {
strSize = [text sizeWithFont:attributes[NSFontAttributeName]];
attrStr = [[NSAttributedString alloc] initWithString:text attributes:attributes];
} else {
strSize = [text sizeWithFont:[UIFont systemFontOfSize:[UIFont systemFontSize]]];
attrStr = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]]}];
}
CGFloat strX = xCenter - strSize.width * 0.5;
CGFloat strY = yCenter - strSize.height * 0.5;
[attrStr drawAtPoint:CGPointMake(strX, strY)];
}
}
// 清除指示器
- (void)dismiss
{
self.progress = 1.0;
}
+ (id)progressView
{
return [[self alloc] init];
}
@end
//
// SDPieLoopProgressView.h
// SDProgressView
//
// Created by aier on 15-2-20.
// Copyright (c) 2015年 GSD. All rights reserved.
//
#import "SDBaseProgressView.h"
@interface SDPieLoopProgressView : SDBaseProgressView
@end
//
// SDPieLoopProgressView.m
// SDProgressView
//
// Created by aier on 15-2-20.
// Copyright (c) 2015年 GSD. All rights reserved.
//
#import "SDPieLoopProgressView.h"
@implementation SDPieLoopProgressView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat xCenter = rect.size.width * 0.5;
CGFloat yCenter = rect.size.height * 0.5;
CGFloat radius = MIN(rect.size.width * 0.5, rect.size.height * 0.5) - SDProgressViewItemMargin * 0.2;
// 进度环边框
[[UIColor grayColor] set];
CGFloat w = radius * 2 + 1;
CGFloat h = w;
CGFloat x = (rect.size.width - w) * 0.5;
CGFloat y = (rect.size.height - h) * 0.5;
CGContextAddEllipseInRect(ctx, CGRectMake(x, y, w, h));
CGContextStrokePath(ctx);
// 进度环
[SDProgressViewBackgroundColor set];
CGContextMoveToPoint(ctx, xCenter, yCenter);
CGContextAddLineToPoint(ctx, xCenter, 0);
CGFloat to = - M_PI * 0.5 + self.progress * M_PI * 2 + 0.001; // 初始值
CGContextAddArc(ctx, xCenter, yCenter, radius, - M_PI * 0.5, to, 0);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
// 遮罩
[SDColorMaker(240, 240, 240, 1) set];
CGFloat maskW = (radius - 15) * 2;
CGFloat maskH = maskW;
CGFloat maskX = (rect.size.width - maskW) * 0.5;
CGFloat maskY = (rect.size.height - maskH) * 0.5;
CGContextAddEllipseInRect(ctx, CGRectMake(maskX, maskY, maskW, maskH));
CGContextFillPath(ctx);
// 遮罩边框
[[UIColor grayColor] set];
CGFloat borderW = maskW + 1;
CGFloat borderH = borderW;
CGFloat borderX = (rect.size.width - borderW) * 0.5;
CGFloat borderY = (rect.size.height - borderH) * 0.5;
CGContextAddEllipseInRect(ctx, CGRectMake(borderX, borderY, borderW, borderH));
CGContextStrokePath(ctx);
// 进度数字
NSString *progressStr = [NSString stringWithFormat:@"%.0f%s", self.progress * 100, "\%"];
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
attributes[NSFontAttributeName] = [UIFont boldSystemFontOfSize:20 * SDProgressViewFontScale];
attributes[NSForegroundColorAttributeName] = [UIColor lightGrayColor];
[self setCenterProgressText:progressStr withAttributes:attributes];
}
@end
// AFHTTPRequestOperation.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import "AFURLConnectionOperation.h"
/**
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
*/
@interface AFHTTPRequestOperation : AFURLConnectionOperation
///------------------------------------------------
/// @name Getting HTTP URL Connection Information
///------------------------------------------------
/**
The last HTTP response received by the operation's connection.
*/
@property (readonly, nonatomic, strong) NSHTTPURLResponse *response;
/**
Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed.
@warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value
*/
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
/**
An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error.
*/
@property (readonly, nonatomic, strong) id responseObject;
///-----------------------------------------------------------
/// @name Setting Completion Block Success / Failure Callbacks
///-----------------------------------------------------------
/**
Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed.
This method should be overridden in subclasses in order to specify the response object passed into the success block.
@param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request.
@param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request.
*/
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
@end
// AFNetworkActivityIndicatorManager.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import <Availability.h>
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h>
/**
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself.
See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information:
http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44
*/
@interface AFNetworkActivityIndicatorManager : NSObject
/**
A Boolean value indicating whether the manager is enabled.
If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO.
*/
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
/**
A Boolean value indicating whether the network activity indicator is currently displayed in the status bar.
*/
@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible;
/**
Returns the shared network activity indicator manager object for the system.
@return The systemwide network activity indicator manager.
*/
+ (instancetype)sharedManager;
/**
Increments the number of active network requests. If this number was zero before incrementing, this will start animating the status bar network activity indicator.
*/
- (void)incrementActivityCount;
/**
Decrements the number of active network requests. If this number becomes zero after decrementing, this will stop animating the status bar network activity indicator.
*/
- (void)decrementActivityCount;
@end
#endif
// AFNetworkReachabilityManager.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#else
#define NS_DESIGNATED_INITIALIZER
#endif
#endif
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,
AFNetworkReachabilityStatusReachableViaWWAN = 1,
AFNetworkReachabilityStatusReachableViaWiFi = 2,
};
/**
`AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/)
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
*/
@interface AFNetworkReachabilityManager : NSObject
/**
The current network reachability status.
*/
@property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
/**
Whether or not the network is currently reachable.
*/
@property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable;
/**
Whether or not the network is currently reachable via WWAN.
*/
@property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN;
/**
Whether or not the network is currently reachable via WiFi.
*/
@property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi;
///---------------------
/// @name Initialization
///---------------------
/**
Returns the shared network reachability manager.
*/
+ (instancetype)sharedManager;
/**
Creates and returns a network reachability manager for the specified domain.
@param domain The domain used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified domain.
*/
+ (instancetype)managerForDomain:(NSString *)domain;
/**
Creates and returns a network reachability manager for the socket address.
@param address The socket address (`sockaddr_in`) used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified socket address.
*/
+ (instancetype)managerForAddress:(const void *)address;
/**
Initializes an instance of a network reachability manager from the specified reachability object.
@param reachability The reachability object to monitor.
@return An initialized network reachability manager, actively monitoring the specified reachability.
*/
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
///--------------------------------------------------
/// @name Starting & Stopping Reachability Monitoring
///--------------------------------------------------
/**
Starts monitoring for changes in network reachability status.
*/
- (void)startMonitoring;
/**
Stops monitoring for changes in network reachability status.
*/
- (void)stopMonitoring;
///-------------------------------------------------
/// @name Getting Localized Reachability Description
///-------------------------------------------------
/**
Returns a localized string representation of the current network reachability status.
*/
- (NSString *)localizedNetworkReachabilityStatusString;
///---------------------------------------------------
/// @name Setting Network Reachability Change Callback
///---------------------------------------------------
/**
Sets a callback to be executed when the network availability of the `baseURL` host changes.
@param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`.
*/
- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block;
@end
///----------------
/// @name Constants
///----------------
/**
## Network Reachability
The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses.
enum {
AFNetworkReachabilityStatusUnknown,
AFNetworkReachabilityStatusNotReachable,
AFNetworkReachabilityStatusReachableViaWWAN,
AFNetworkReachabilityStatusReachableViaWiFi,
}
`AFNetworkReachabilityStatusUnknown`
The `baseURL` host reachability is not known.
`AFNetworkReachabilityStatusNotReachable`
The `baseURL` host cannot be reached.
`AFNetworkReachabilityStatusReachableViaWWAN`
The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS.
`AFNetworkReachabilityStatusReachableViaWiFi`
The `baseURL` host can be reached via a Wi-Fi connection.
### Keys for Notification UserInfo Dictionary
Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification.
`AFNetworkingReachabilityNotificationStatusItem`
A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification.
The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status.
*/
///--------------------
/// @name Notifications
///--------------------
/**
Posted when network reachability changes.
This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability.
@warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import <SystemConfiguration/SystemConfiguration.h>` to the header prefix of the project (`Prefix.pch`).
*/
extern NSString * const AFNetworkingReachabilityDidChangeNotification;
extern NSString * const AFNetworkingReachabilityNotificationStatusItem;
///--------------------
/// @name Functions
///--------------------
/**
Returns a localized string representation of an `AFNetworkReachabilityStatus` value.
*/
extern NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status);
// AFNetworking.h
//
// Copyright (c) 2013 AFNetworking (http://afnetworking.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.
#import <Foundation/Foundation.h>
#import <Availability.h>
#ifndef _AFNETWORKING_
#define _AFNETWORKING_
#import "AFURLRequestSerialization.h"
#import "AFURLResponseSerialization.h"
#import "AFSecurityPolicy.h"
#import "AFNetworkReachabilityManager.h"
#import "AFURLConnectionOperation.h"
#import "AFHTTPRequestOperation.h"
#import "AFHTTPRequestOperationManager.h"
#if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \
( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) )
#import "AFURLSessionManager.h"
#import "AFHTTPSessionManager.h"
#endif
#endif /* _AFNETWORKING_ */
//
// AFNetworkingFramwork.h
// AFNetworkingFramwork
//
// Created by 吴笑诚 on 16/2/17.
// Copyright © 2016年 sky1and2sea. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for AFNetworkingFramwork.
FOUNDATION_EXPORT double AFNetworkingFramworkVersionNumber;
//! Project version string for AFNetworkingFramwork.
FOUNDATION_EXPORT const unsigned char AFNetworkingFramworkVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <AFNetworkingFramwork/PublicHeader.h>
// AFSecurityPolicy.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import <Security/Security.h>
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone,
AFSSLPinningModePublicKey,
AFSSLPinningModeCertificate,
};
/**
`AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections.
Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled.
*/
@interface AFSecurityPolicy : NSObject
/**
The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`.
*/
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
/**
Whether to evaluate an entire SSL certificate chain, or just the leaf certificate. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesCertificateChain;
/**
The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle.
*/
@property (nonatomic, strong) NSArray *pinnedCertificates;
/**
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
*/
@property (nonatomic, assign) BOOL allowInvalidCertificates;
/**
Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesDomainName;
///-----------------------------------------
/// @name Getting Specific Security Policies
///-----------------------------------------
/**
Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys.
@return The default security policy.
*/
+ (instancetype)defaultPolicy;
///---------------------
/// @name Initialization
///---------------------
/**
Creates and returns a security policy with the specified pinning mode.
@param pinningMode The SSL pinning mode.
@return A new security policy.
*/
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;
///------------------------------
/// @name Evaluating Server Trust
///------------------------------
/**
Whether or not the specified server trust should be accepted, based on the security policy.
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@return Whether or not to trust the server.
@warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE;
/**
Whether or not the specified server trust should be accepted, based on the security policy.
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@param domain The domain of serverTrust. If `nil`, the domain will not be validated.
@return Whether or not to trust the server.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain;
@end
///----------------
/// @name Constants
///----------------
/**
## SSL Pinning Modes
The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.
enum {
AFSSLPinningModeNone,
AFSSLPinningModePublicKey,
AFSSLPinningModeCertificate,
}
`AFSSLPinningModeNone`
Do not used pinned certificates to validate servers.
`AFSSLPinningModePublicKey`
Validate host certificates against public keys of pinned certificates.
`AFSSLPinningModeCertificate`
Validate host certificates against pinned certificates.
*/
// UIActivityIndicatorView+AFNetworking.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import <Availability.h>
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h>
@class AFURLConnectionOperation;
/**
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a request operation or session task.
*/
@interface UIActivityIndicatorView (AFNetworking)
///----------------------------------
/// @name Animating for Session Tasks
///----------------------------------
/**
Binds the animating state to the state of the specified task.
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
#endif
///---------------------------------------
/// @name Animating for Request Operations
///---------------------------------------
/**
Binds the animating state to the execution state of the specified operation.
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation;
@end
#endif
// UIAlertView+AFNetworking.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// 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.
#import <Foundation/Foundation.h>
#import <Availability.h>
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
#import <UIKit/UIKit.h>
@class AFURLConnectionOperation;
/**
This category adds methods to the UIKit framework's `UIAlertView` class. The methods in this category provide support for automatically showing an alert if a session task or request operation finishes with an error. Alert title and message are filled from the corresponding `localizedDescription` & `localizedRecoverySuggestion` or `localizedFailureReason` of the error.
*/
@interface UIAlertView (AFNetworking)
///-------------------------------------
/// @name Showing Alert for Session Task
///-------------------------------------
/**
Shows an alert view with the error of the specified session task, if any.
@param task The session task.
@param delegate The alert view delegate.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(id)delegate;
#endif
/**
Shows an alert view with the error of the specified session task, if any, with a custom cancel button title and other button titles.
@param task The session task.
@param delegate The alert view delegate.
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;
#endif
///------------------------------------------
/// @name Showing Alert for Request Operation
///------------------------------------------
/**
Shows an alert view with the error of the specified request operation, if any.
@param operation The request operation.
@param delegate The alert view delegate.
*/
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(id)delegate;
/**
Shows an alert view with the error of the specified request operation, if any, with a custom cancel button title and other button titles.
@param operation The request operation.
@param delegate The alert view delegate.
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
*/
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;
@end
#endif
// UIKit+AFNetworking.h
//
// Copyright (c) 2013 AFNetworking (http://afnetworking.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.
#import <UIKit/UIKit.h>
#ifndef _UIKIT_AFNETWORKING_
#define _UIKIT_AFNETWORKING_
#import "AFNetworkActivityIndicatorManager.h"
#import "UIActivityIndicatorView+AFNetworking.h"
#import "UIAlertView+AFNetworking.h"
#import "UIButton+AFNetworking.h"
#import "UIImageView+AFNetworking.h"
#import "UIKit+AFNetworking.h"
#import "UIProgressView+AFNetworking.h"
#import "UIRefreshControl+AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#endif /* _UIKIT_AFNETWORKING_ */
framework module ZipArchive {
umbrella header "ZipArchive.h"
export *
module * { export * }
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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