Fork me on GitHub

iOS-解压zip

最近的项目中涉及到了将zip文件从服务上下载下来,然后解压使用。搜索了一下发现有一个压缩与解压zip文件的第三方“SSZipArchive”:https://github.com/ZipArchive/ZipArchive 是用C语言实现的,包装用于OC与swift.

一、在使用过程中遇到过几个坑:
  1. 导入头文件冲突,我在pch文件里面导入了一些OC的头文件,而SSZipArchive是由C语言实现的,所以报了很多的系统错误。解决办法:将pch里面的导入头文件代码放在
    “#ifdef OBJC
    //导入头文件
    “#endif 里面”
    或者删除里面导入头文件的代码,去具体需要的文件里面导入,有一点暴力哈。

  2. 我每一次下载的文件样式都是一样的,所以希望覆盖式的解压,一开始没有注意以为它只有解压方法:+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;
    就自己去判定是否存在然后删除,后来去仔细的看源码才发现它是有带是否覆盖式解压的方法:+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError * *)error;
    当然它还有很多方法,包括带有代理方法,带有密码,带有完成后的block回调方法,
    http://blog.csdn.net/zhengang007/article/details/51019479
    这里有每一个方法的详细说明。

二、我的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- (void)downFileFromServer{
//远程地址
NSURL *URL = [NSURL URLWithString:DOWN_URL];
//默认配置
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//AFN3.0+基于封住URLSession的句柄
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

//请求
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

//下载Task操作
_downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
// 下载进度

} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

//- block的返回值, 要求返回一个URL, 返回的这个URL就是文件的位置的路径
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

//设置下载完成操作
// filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
NSString *imgFilePath = [filePath path];// 将NSURL转成NSString
MyLog(@"imgFilePath = %@",imgFilePath);
NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *path = [[documentArray lastObject] stringByAppendingPathComponent:@"Preferences"];
[self releaseZipFilesWithUnzipFileAtPath:imgFilePath Destination:path];
}];
[_downloadTask resume];
}

// 解压
- (void)releaseZipFilesWithUnzipFileAtPath:(NSString *)zipPath Destination:(NSString *)unzipPath{
NSError *error;
if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:YES password:nil error:&error delegate:self]) {
MyLog(@"success");
MyLog(@"unzipPath = %@",unzipPath);
}else {
MyLog(@"%@",error);
}
}

#pragma mark - SSZipArchiveDelegate
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo {
MyLog(@"将要解压。");
}

- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPat uniqueId:(NSString *)uniqueId {
MyLog(@"解压完成!");
}

当然还得遵守协议:SSZipArchiveDelegate
以上就是我使用SSZipArchive的体会,欢迎各位指正。

iOS-js与iOS的交互(基于WKWebViewJavascriptBridge第三方)

后天就要去北京出差了,据说那边的项目主要是与网页交互,所以就简单的研究了一下js与iOS的交互。
其交互方式有很多种

一、native(app)通过UIWebView的代理方法拦截url scheme判断是否是我们需要拦截处理的url及其所对应的要处理的逻辑(可以实现对网页的返回、前景、刷新),比较通用和简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];

self.webView.delegate = self;

[self.webView setUserInteractionEnabled:YES]; //是否支持交互

[self.webView setOpaque:NO]; //opaque是不透明的意思

[self.webView setScalesPageToFit:YES]; //自动缩放以适应屏幕

[self.view addSubview:self.webView];

if (sender.tag == 101) {

// 返回(点击页面才会有返回)
[self.mWebView goBack];

}else if (sender.tag == 102) {

// 前进(点击过的页面)
[self.mWebView goForward];

}else {

// 刷新页面
[self.mWebView reload];

}

二、iOS7之后出了JavaScriptCore.framework用于与JS交互,通过JSContext调用JS代码的方法:

1、直接调用JS代码

2、在ObjC中通过JSContext注入模型,然后调用模型的方法

通过evaluateScript:方法就可以执行JS代码

三、React Native (不是很了解,只知道是Facebook的,能编译很多的语音,兼容性很强,可移植也很强,有很多很好的原生控件,有兴趣的朋友可以了解一下)

四、WebViewJavascriptBridge(第三方)是基于方式一封装的(主要是两个回调函数)。

1
在iOS端:1.self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];

链接iOS与js,self.webView就是展示你用来显示需要交换页面的UIWebView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2.[self.bridge registerHandler:@"testJavascriptHandler" handler:^(id data, WVJBResponseCallback responseCallback) {

NSLog(@"ObjC Echo called with: %@", data);

// 反馈给JS
responseCallback(data);

}];

// 在JS中如果调用了bridge.send(),那么将触发OC端_bridge初始化方法中的回调。

// 在JS中调用了bridge.callHandler('testJavascriptHandler'),它将触发OC端注册的同名方法

// oc 同理

// JS主动调用OjbC的方法

// 这是JS会调用ObjC Echo方法,这是OC注册给JS调用的

// JS需要回调,当然JS也可以传参数过来。data就是JS所传的参数,不一定需要传

// OC端通过responseCallback回调JS端,JS就可以得到所需要的数据

3.[self.bridge callHandler:@"sayHello" data:@{@"hello": @"你好"} responseCallback:^(id responseData) {

NSLog(@"回调结果: %@", responseData);

}];

直接调用JS端注册的HandleName,一定注意此次的名字一定要与js端的相同。
js调用时也一样

在JS端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1.Copy and paste setupWebViewJavascriptBridge into your JS:

(此段代码为固定格式,直接放在js端就行)

function setupWebViewJavascriptBridge(callback) {

if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }

if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }

window.WVJBCallbacks = [callback];

var WVJBIframe = document.createElement('iframe');

WVJBIframe.style.display = 'none';

WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';

document.documentElement.appendChild(WVJBIframe);

setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)

}

后面几步与iOS端一样

如有错误,望请指出。

iOS-高德地图

一直以来在简书上学习了不少的知识,自己也想分享一些知识供大家指点,最近正好在研究高德地图API,所以分享一下自己最近捣鼓的。
要使用高德API,首先要去高德API官网注册开发者账号,创建应用,获得key值。然后在本地创建自己的项目pod高德SDK,在pod时要提前思考清楚是否需要导航,我在这里就被坑过,因为导航的SDK包含搜索的SDK,如果将搜索SDK与导航SDK都pod了会报链接错误,所以如果需要导航就可以不用pod搜索SDK了。最后就是本地导入相应头文件,然后配置key。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const static NSString *APIKey = @"你申请的key";

// 配置用户Key

[MAMapServices sharedServices].apiKey = (NSString *)APIKey;

// 搜索

[AMapSearchServices sharedServices].apiKey = (NSString *)APIKey;

// 导航

[AMapNaviServices sharedServices].apiKey = (NSString *)APIKey;

后面的就可以按照它的开发指南写,要注意的是路径规划是建立在路径搜索之上的,要路径规划先得完成路径搜索。导航的语音合成,我是用的讯飞的在线语音合成,离线的好像要收费,在下穷猿一名。高德导航的demo好像也是用的讯飞的。去讯飞API官网注册账号,创建应用,获取key,然后配置语音。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//设置sdk的log等级,log保存在下面设置的工作路径中
[IFlySetting setLogFile:LVL_ALL];

//打开输出在console的log开关
[IFlySetting showLogcat:YES];

//设置sdk的工作路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
[IFlySetting setLogFilePath:cachePath];

// 配置相关参数
- (void)configIFlySpeech
{
[IFlySpeechUtility createUtility:[NSString stringWithFormat:@"appid=%@,timeout=%@",@"5733feca",@"20000"]];

[IFlySetting setLogFile:LVL_NONE];

[IFlySetting showLogcat:NO];

// 设置语音合成的参数
[[IFlySpeechSynthesizer sharedInstance] setParameter:@"50" forKey:[IFlySpeechConstant SPEED]];//合成的语速,取值范围 0~100

[[IFlySpeechSynthesizer sharedInstance] setParameter:@"50" forKey:[IFlySpeechConstant VOLUME]];//合成的音量;取值范围 0~100

// 发音人,默认为”xiaoyan”;可以设置的参数列表可参考个 性化发音人列表;
[[IFlySpeechSynthesizer sharedInstance] setParameter:@"xiaowang" forKey:[IFlySpeechConstant VOICE_NAME]];

// 音频采样率,目前支持的采样率有 16000 和 8000;
[[IFlySpeechSynthesizer sharedInstance] setParameter:@"8000" forKey:[IFlySpeechConstant SAMPLE_RATE]];

// 当你再不需要保存音频时,请在必要的地方加上这行。
[[IFlySpeechSynthesizer sharedInstance] setParameter:nil forKey:[IFlySpeechConstant TTS_AUDIO_PATH]];

}

然后初始化和设置代理。
- (void)initIFlySpeech {

if (self.iFlySpeechSynthesizer == nil)

{

_iFlySpeechSynthesizer = [IFlySpeechSynthesizer sharedInstance];

}

_iFlySpeechSynthesizer.delegate = self;

}

// 语音失败回调代理函数
- (void)onCompleted:(IFlySpeechError *)error {

NSLog(@"Speak Error:{%d:%@}", error.errorCode, error.errorDesc);

}

高德导航有一个回调函数,会传回导航语音的字符串,在回调函数里面创建异步线程,将字符串合成语音,并且播放,在高德导航点击关闭按钮的回调函数里面关闭播放并且关闭导航。

####pragma mark – 语音调用(导航回调)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

- (void)naviManager:(AMapNaviManager *)naviManager playNaviSoundString:(NSString *)soundString soundStringType:(AMapNaviSoundType)soundStringType {

if (soundStringType == AMapNaviSoundTypePassedReminder) {

// 系统语音
AudioServicesPlaySystemSound(1009);
}else {
// 开启异步线程(全局)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[_iFlySpeechSynthesizer startSpeaking:soundString];
});
}
}

// 这是点击关闭按钮的回调函数(就是导航界面的叉叉)
- (void)naviViewControllerCloseButtonClicked:(AMapNaviViewController *)naviViewController {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

[self.iFlySpeechSynthesizer stopSpeaking];

});

[self.naviManager stopNavi];

[self.naviManager dismissNaviViewControllerAnimated:YES];

}

以上就是我最近研究的高德API,一是对最近学习的总结,二是希望帮助刚刚接触高德的人,希望对你们有帮助,文章写得有点乱,第一次啊,以后肯定会越来越好。如有错误欢迎各位指出。谢谢。

  • Copyrights © 2015-2025 kindyourself@163.com
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信